diff --git a/README.md b/README.md index 08323afd..c29517fd 100644 --- a/README.md +++ b/README.md @@ -61,7 +61,7 @@ Example `.env` variables (or export in shell): ```bash MAILTRAP_API_KEY=your_api_token # https://mailtrap.io/api-tokens MAILTRAP_USE_SANDBOX=true # true/false toggle -MAILTRAP_INBOX_ID=123456 # Only needed for sandbox +MAILTRAP_SANDBOX_ID=123456 # Only needed for sandbox ``` Bootstrap logic: @@ -71,12 +71,12 @@ import { MailtrapClient } from "mailtrap"; const apiKey = process.env.MAILTRAP_API_KEY; const isSandbox = process.env.MAILTRAP_USE_SANDBOX === "true"; -const inboxId = isSandbox ? Number(process.env.MAILTRAP_INBOX_ID) : undefined; // required only for sandbox +const sandboxId = isSandbox ? Number(process.env.MAILTRAP_SANDBOX_ID) : undefined; // required only for sandbox const client = new MailtrapClient({ token: apiKey, sandbox: isSandbox, - testInboxId: inboxId, // undefined is ignored for production + sandboxId, // undefined is ignored for production }); client @@ -119,7 +119,7 @@ const mailtrap = new MailtrapClient({ token: process.env.MAILTRAP_API_KEY, // your API token bulk: false, // set to true for bulk email sending (false by default) sandbox: false, // set to true for sandbox mode (false by default) - testInboxId: undefined, // optional, only for sandbox mode + sandboxId: undefined, // optional, only for sandbox mode }); const welcomeImage = fs.readFileSync(path.join(__dirname, "welcome.png")); @@ -236,23 +236,23 @@ Email API: - Batch send (Bulk) – [`batch/bulk.ts`](examples/bulk/bulk.ts) - Batch send with Template (Transactional) – [`batch/template.ts`](examples/batch/template.ts) - Batch send with Template (Bulk) – [`batch/template.ts`](examples/batch/template.ts) -- Sending domain management CRUD and settings – [`sending-domains/everything.ts`](examples/sending-domains/everything.ts) -- Sending domain company info – [`company-info/everything.ts`](examples/company-info/everything.ts) +- Domain management CRUD and settings – [`domains/everything.ts`](examples/domains/everything.ts) +- Domain company info – [`company-info/everything.ts`](examples/company-info/everything.ts) - Sending stats (aggregated and by domain, category, ESP, date) – [`stats/everything.ts`](examples/stats/everything.ts) - Email logs (list with filters, get by message ID) – [`email-logs/everything.ts`](examples/email-logs/everything.ts) - Webhooks CRUD – [`webhooks/everything.ts`](examples/webhooks/everything.ts) - Verifying webhook signatures – [`webhooks/verify-signature.ts`](examples/webhooks/verify-signature.ts) -Email Sandbox (Testing): +Email Sandbox: -- Send an email (Sandbox) – [`testing/send-mail.ts`](examples/testing/send-mail.ts) -- Send an email with a Template (Sandbox) – [`testing/template.ts`](examples/testing/template.ts) +- Send an email (Sandbox) – [`sandbox/send-mail.ts`](examples/sandbox/send-mail.ts) +- Send an email with a Template (Sandbox) – [`sandbox/template.ts`](examples/sandbox/template.ts) - Batch send (Sandbox) – [`batch/sandbox.ts`](examples/batch/sandbox.ts) - Batch send with Template (Sandbox) – [`batch/sandbox.ts`](examples/batch/sandbox.ts) -- Message management CRUD – [`testing/messages.ts`](examples/testing/messages.ts) -- Inbox management CRUD – [`testing/inboxes.ts`](examples/testing/inboxes.ts) -- Project management CRUD – [`testing/projects.ts`](examples/testing/projects.ts) -- Attachments operations – [`testing/attachments.ts`](examples/testing/attachments.ts) +- Message management CRUD – [`sandbox/messages.ts`](examples/sandbox/messages.ts) +- Sandbox management CRUD – [`sandbox/sandboxes.ts`](examples/sandbox/sandboxes.ts) +- Project management CRUD – [`sandbox/projects.ts`](examples/sandbox/projects.ts) +- Attachments operations – [`sandbox/attachments.ts`](examples/sandbox/attachments.ts) Inbound Email: @@ -304,6 +304,24 @@ Everyone interacting in the Mailtrap project's codebases, issue trackers, chat r Versions of this package up to 2.0.2 were an [unofficial client](https://github.com/vchin/mailtrap-client) developed by [@vchin](https://github.com/vchin). Package version 3 is a completely new package. +### Renamed APIs + +The SDK now uses the product's names: Email Sandbox inboxes are **sandboxes** and sending domains are **domains**. The old names still work, call the same endpoints, and will be removed in a future major release. Each old option, getter and method emits a `DeprecationWarning` the first time it is used. + +| Old name | New name | +|---|---| +| `testInboxId` config option | `sandboxId` | +| `client.testing` | `client.sandbox` | +| `client.testing.inboxes` | `client.sandbox.sandboxes` | +| `inboxes.getInboxAttributes()` | `sandboxes.getSandboxAttributes()` | +| `inboxes.updateInbox()` | `sandboxes.updateSandbox()` | +| `inboxes.cleanInbox()` | `sandboxes.cleanSandbox()` | +| `client.sendingDomains` | `client.domains` | + +The other methods of `client.testing` and `client.sendingDomains` keep their names. Fields that mirror the API, such as `inbox_id` on messages or `sending_domain_id` on email logs, keep their names too. Passing both `sandboxId` and `testInboxId` with different values throws a `MailtrapError`. + +The warnings carry the code `MAILTRAP_DEPRECATED_NAME`. `node --no-deprecation` silences them, along with every other deprecation warning. + ### Upgrading to 5.0 `client.templates` now calls the paginated `/api/templates` endpoints instead of `/api/email_templates`: diff --git a/examples/batch/sandbox.ts b/examples/batch/sandbox.ts index ac06ff7d..920ce412 100644 --- a/examples/batch/sandbox.ts +++ b/examples/batch/sandbox.ts @@ -7,14 +7,14 @@ import { MailtrapClient } from "mailtrap"; */ const TOKEN = ""; -const TEST_INBOX_ID = ""; +const SANDBOX_ID = ""; const SENDER_EMAIL = ""; const RECIPIENT_EMAIL = ""; const client = new MailtrapClient({ token: TOKEN, sandbox: true, - testInboxId: TEST_INBOX_ID + sandboxId: Number(SANDBOX_ID) }); client.batchSend({ diff --git a/examples/company-info/everything.ts b/examples/company-info/everything.ts index b34de568..02da30ae 100644 --- a/examples/company-info/everything.ts +++ b/examples/company-info/everything.ts @@ -22,7 +22,7 @@ async function companyInfoFlow() { }); console.log("Created company info:", JSON.stringify(created, null, 2)); - // Get the company info of a sending domain + // Get the company info of a domain const companyInfo = await client.companyInfo.get(DOMAIN_ID); console.log("Company info:", JSON.stringify(companyInfo, null, 2)); diff --git a/examples/domains/everything.ts b/examples/domains/everything.ts new file mode 100644 index 00000000..f6a821e1 --- /dev/null +++ b/examples/domains/everything.ts @@ -0,0 +1,57 @@ +import { MailtrapClient } from "mailtrap"; + +const TOKEN = ""; +const ACCOUNT_ID = ""; + +const client = new MailtrapClient({ + token: TOKEN, + accountId: Number(ACCOUNT_ID), +}); + +async function domainsFlow() { + try { + // Get all domains + const all = await client.domains.getList(); + console.log("All domains:", JSON.stringify(all, null, 2)); + + if (all.data && all.data.length > 0) { + // Get a specific domain + const one = await client.domains.get(all.data[0].id); + console.log("One domain:", JSON.stringify(one, null, 2)); + + // Send setup instructions + await client.domains.sendSetupInstructions( + all.data[0].id, + "admin@example.com" + ); + console.log("Setup instructions sent"); + } else { + console.log("No domains found for this account."); + } + + // Create a new domain + const created = await client.domains.create({ + domain_name: "test-domain-" + Date.now() + ".com", + }); + console.log("Created domain:", JSON.stringify(created, null, 2)); + + // Update the settings of the created domain + const updated = await client.domains.update(created.id, { + open_tracking_enabled: true, + click_tracking_enabled: true, + tracking_opt_out_enabled: true, + auto_unsubscribe_link_enabled: false, + inbound_enabled: false, + }); + console.log("Updated domain:", JSON.stringify(updated, null, 2)); + + // Delete the created domain + await client.domains.delete(created.id); + console.log("Domain deleted"); + + } catch (error) { + console.error("Error in domainsFlow:", error instanceof Error ? error.message : String(error)); + } +} + +domainsFlow(); diff --git a/examples/email-campaigns/everything.ts b/examples/email-campaigns/everything.ts index 471da271..11763319 100644 --- a/examples/email-campaigns/everything.ts +++ b/examples/email-campaigns/everything.ts @@ -1,8 +1,8 @@ import { MailtrapClient } from "mailtrap"; const TOKEN = ""; -// ID of a verified sending domain on the account (required to create a campaign), -// as returned by the Sending Domains endpoints. +// ID of a verified domain on the account (required to create a campaign), +// as returned by `client.domains`. const SENDING_DOMAIN_ID = ""; // The Email Campaigns API is token-scoped — no `accountId` is needed. diff --git a/examples/general/account-accesses.ts b/examples/general/account-accesses.ts index 96312a20..fe87bec8 100644 --- a/examples/general/account-accesses.ts +++ b/examples/general/account-accesses.ts @@ -1,10 +1,9 @@ import { MailtrapClient } from "mailtrap" const TOKEN = ""; -const TEST_INBOX_ID = "" const ACCOUNT_ID = "" -const client = new MailtrapClient({ token: TOKEN, testInboxId: TEST_INBOX_ID, accountId: ACCOUNT_ID }); +const client = new MailtrapClient({ token: TOKEN, accountId: Number(ACCOUNT_ID) }); const accountAccessesClient = client.general.accountAccesses diff --git a/examples/general/billing.ts b/examples/general/billing.ts index 3ebb8c80..c09c7393 100644 --- a/examples/general/billing.ts +++ b/examples/general/billing.ts @@ -1,10 +1,9 @@ import { MailtrapClient } from "mailtrap" const TOKEN = ""; -const TEST_INBOX_ID = "" const ACCOUNT_ID = "" -const client = new MailtrapClient({ token: TOKEN, testInboxId: TEST_INBOX_ID, accountId: ACCOUNT_ID }); +const client = new MailtrapClient({ token: TOKEN, accountId: Number(ACCOUNT_ID) }); const billingClient = client.general.billing diff --git a/examples/general/permissions.ts b/examples/general/permissions.ts index 24d01bbf..fc552737 100644 --- a/examples/general/permissions.ts +++ b/examples/general/permissions.ts @@ -1,10 +1,9 @@ import { MailtrapClient } from "mailtrap" const TOKEN = ""; -const TEST_INBOX_ID = "" const ACCOUNT_ID = "" -const client = new MailtrapClient({ token: TOKEN, testInboxId: TEST_INBOX_ID, accountId: ACCOUNT_ID }); +const client = new MailtrapClient({ token: TOKEN, accountId: Number(ACCOUNT_ID) }); const permissionsClient = client.general.permissions diff --git a/examples/marketing-stats/everything.ts b/examples/marketing-stats/everything.ts index 21f6fa30..733e334a 100644 --- a/examples/marketing-stats/everything.ts +++ b/examples/marketing-stats/everything.ts @@ -30,7 +30,7 @@ async function marketingStatsFlow() { console.log("Campaigns only:", JSON.stringify(campaigns.data, null, 2)); // Narrow further by recipient email service provider; add - // `sending_domain_ids` (from the Sending Domains endpoints) to pick domains. + // `sending_domain_ids` (from `client.domains`) to pick domains. const automationsAtGoogle = await client.marketingStats.get({ ...dateRange, sources: ["automations"], diff --git a/examples/sandbox/attachments.ts b/examples/sandbox/attachments.ts new file mode 100644 index 00000000..0c0e054d --- /dev/null +++ b/examples/sandbox/attachments.ts @@ -0,0 +1,32 @@ +import { MailtrapClient } from "mailtrap" + +const TOKEN = ""; +const ACCOUNT_ID = "" + +const client = new MailtrapClient({ token: TOKEN, accountId: Number(ACCOUNT_ID) }); + +const sandboxesClient = client.sandbox.sandboxes +const messagesClient = client.sandbox.messages +const attachmentsClient = client.sandbox.attachments + +sandboxesClient.getList() + .then(async (sandboxes) => { + if (sandboxes && sandboxes.length > 0) { + const firstSandboxId = sandboxes[0].id + + const messages = await messagesClient.get(firstSandboxId) + + if (messages && messages.length > 0) { + const firstMessageId = messages[0].id + + const attachments = await attachmentsClient.getList(firstSandboxId, firstMessageId) + + if (attachments && attachments.length > 0) { + const firstAttachment = attachments[0].id + const attachmentData = await attachmentsClient.get(firstSandboxId, firstMessageId, firstAttachment) + + console.log(attachmentData) + } + } + } + }) diff --git a/examples/sandbox/messages.ts b/examples/sandbox/messages.ts new file mode 100644 index 00000000..780f6e9d --- /dev/null +++ b/examples/sandbox/messages.ts @@ -0,0 +1,39 @@ +import { MailtrapClient } from "mailtrap" + +const TOKEN = ""; +const ACCOUNT_ID = "" + +const client = new MailtrapClient({ token: TOKEN, accountId: Number(ACCOUNT_ID) }); + +const sandboxesClient = client.sandbox.sandboxes +const messagesClient = client.sandbox.messages + +sandboxesClient.getList() + .then(async (sandboxes) => { + if (sandboxes && sandboxes.length > 0) { + const firstSandboxId = sandboxes[0].id + + const messages = await messagesClient.get(firstSandboxId) + + if (messages && messages.length > 0) { + const firstMessageId = messages[0].id + + await messagesClient.getHtmlAnalysis(firstSandboxId, firstMessageId) + await messagesClient.getHtmlMessage(firstSandboxId, firstMessageId) + await messagesClient.getTextMessage(firstSandboxId, firstMessageId) + await messagesClient.getMailHeaders(firstSandboxId, firstMessageId) + await messagesClient.getMessageAsEml(firstSandboxId, firstMessageId) + await messagesClient.getMessageHtmlSource(firstSandboxId, firstMessageId) + await messagesClient.getRawMessage(firstSandboxId, firstMessageId) + await messagesClient.getSpamScore(firstSandboxId, firstMessageId) + await messagesClient.showEmailMessage(firstSandboxId, firstMessageId) + await messagesClient.updateMessage(firstSandboxId, firstMessageId, { + isRead: false + }) + await messagesClient.forward(firstSandboxId, firstMessageId, 'mock@mail.com') + const response = await messagesClient.deleteMessage(firstSandboxId, firstMessageId) + + console.log(response) + } + } + }) diff --git a/examples/testing/projects.ts b/examples/sandbox/projects.ts similarity index 70% rename from examples/testing/projects.ts rename to examples/sandbox/projects.ts index b7f8520f..3ea61805 100644 --- a/examples/testing/projects.ts +++ b/examples/sandbox/projects.ts @@ -1,12 +1,11 @@ import { MailtrapClient } from "mailtrap" const TOKEN = ""; -const TEST_INBOX_ID = "" const ACCOUNT_ID = "" -const client = new MailtrapClient({ token: TOKEN, testInboxId: TEST_INBOX_ID, accountId: ACCOUNT_ID }); +const client = new MailtrapClient({ token: TOKEN, accountId: Number(ACCOUNT_ID) }); -const projectsClient = client.testing.projects +const projectsClient = client.sandbox.projects projectsClient.getList() .then(async (projects) => { diff --git a/examples/sandbox/sandboxes.ts b/examples/sandbox/sandboxes.ts new file mode 100644 index 00000000..db164e40 --- /dev/null +++ b/examples/sandbox/sandboxes.ts @@ -0,0 +1,32 @@ +import { MailtrapClient } from "mailtrap" + +const TOKEN = ""; +const ACCOUNT_ID = "" + +const client = new MailtrapClient({ token: TOKEN, accountId: Number(ACCOUNT_ID) }); + +const projectsClient = client.sandbox.projects +const sandboxesClient = client.sandbox.sandboxes + +projectsClient.getList() + .then(async (projects) => { + if (projects && projects.length > 0) { + const firstProjectId = projects[0].id + + // Work on the sandbox created here, so the account's existing sandboxes stay untouched. + const { id: sandboxId } = await sandboxesClient.create(firstProjectId, 'test-sandbox') + + const sandboxes = await sandboxesClient.getList() + console.log(sandboxes) + + const sandboxAttributes = await sandboxesClient.getSandboxAttributes(sandboxId) + await sandboxesClient.updateSandbox(sandboxId, {name: 'mock-name', emailUsername: 'mocker'}) + await sandboxesClient.cleanSandbox(sandboxId) + await sandboxesClient.markAsRead(sandboxId) + await sandboxesClient.resetCredentials(sandboxId) + await sandboxesClient.enableEmailAddress(sandboxId) + const response = await sandboxesClient.resetEmailAddress(sandboxId) + + console.log(response) + } + }) diff --git a/examples/testing/send-mail.ts b/examples/sandbox/send-mail.ts similarity index 90% rename from examples/testing/send-mail.ts rename to examples/sandbox/send-mail.ts index 15bbde17..a49af13e 100644 --- a/examples/testing/send-mail.ts +++ b/examples/sandbox/send-mail.ts @@ -9,11 +9,11 @@ import { MailtrapClient } from "mailtrap" const TOKEN = ""; -const TEST_INBOX_ID = "" +const SANDBOX_ID = "" const SENDER_EMAIL = ""; const RECIPIENT_EMAIL = ""; -const client = new MailtrapClient({ token: TOKEN, sandbox: true, testInboxId: TEST_INBOX_ID }); +const client = new MailtrapClient({ token: TOKEN, sandbox: true, sandboxId: Number(SANDBOX_ID) }); client.send({ from: { name: "Mailtrap Test", email: SENDER_EMAIL }, diff --git a/examples/testing/template.ts b/examples/sandbox/template.ts similarity index 80% rename from examples/testing/template.ts rename to examples/sandbox/template.ts index e39ff57a..3df84095 100644 --- a/examples/testing/template.ts +++ b/examples/sandbox/template.ts @@ -7,12 +7,13 @@ import { MailtrapClient } from "mailtrap" */ const TOKEN = ""; +const SANDBOX_ID = ""; const SENDER_EMAIL = ""; const RECIPIENT_EMAIL = ""; -const client = new MailtrapClient({ token: TOKEN }); +const client = new MailtrapClient({ token: TOKEN, sandbox: true, sandboxId: Number(SANDBOX_ID) }); -client.testing.send({ +client.send({ from: { name: "Mailtrap Test", email: SENDER_EMAIL }, to: [{ email: RECIPIENT_EMAIL }], template_uuid: "813e39db-c74a-4830-b037-0e6ba8b1fe88", diff --git a/examples/testing/transport.ts b/examples/sandbox/transport.ts similarity index 95% rename from examples/testing/transport.ts rename to examples/sandbox/transport.ts index 1a8abf17..a2da0d49 100644 --- a/examples/testing/transport.ts +++ b/examples/sandbox/transport.ts @@ -9,13 +9,13 @@ import { MailtrapTransport } from "mailtrap" */ const TOKEN = "" -const TEST_INBOX_ID = "" +const SANDBOX_ID = "" const SENDER_EMAIL = ""; const RECIPIENT_EMAIL = ""; const transport = Nodemailer.createTransport(MailtrapTransport({ token: TOKEN, - testInboxId: TEST_INBOX_ID, + sandboxId: Number(SANDBOX_ID), sandbox: true })) diff --git a/examples/sending-domains/everything.ts b/examples/sending-domains/everything.ts deleted file mode 100644 index 4fb7e147..00000000 --- a/examples/sending-domains/everything.ts +++ /dev/null @@ -1,58 +0,0 @@ -import { MailtrapClient } from "mailtrap"; - -const TOKEN = ""; -const ACCOUNT_ID = ""; - -const client = new MailtrapClient({ - token: TOKEN, - accountId: Number(ACCOUNT_ID), -}); - -async function sendingDomainsFlow() { - try { - // Get all sending domains - const all = await client.sendingDomains.getList(); - console.log("All sending domains:", JSON.stringify(all, null, 2)); - - if (!all.data || all.data.length === 0) { - console.log("No sending domains found for this account."); - return; - } - - // Get a specific sending domain - const one = await client.sendingDomains.get(all.data[0].id); - console.log("One sending domain:", JSON.stringify(one, null, 2)); - - // Send setup instructions - const setupResponse = await client.sendingDomains.sendSetupInstructions( - all.data[0].id, - "admin@example.com" - ); - console.log("Setup instructions sent"); - - // Create a new sending domain - const created = await client.sendingDomains.create({ - domain_name: "test-domain-" + Date.now() + ".com", - }); - console.log("Created sending domain:", JSON.stringify(created, null, 2)); - - // Update the settings of the created domain - const updated = await client.sendingDomains.update(created.id, { - open_tracking_enabled: true, - click_tracking_enabled: true, - tracking_opt_out_enabled: true, - auto_unsubscribe_link_enabled: false, - inbound_enabled: false, - }); - console.log("Updated sending domain:", JSON.stringify(updated, null, 2)); - - // Delete the created domain - await client.sendingDomains.delete(created.id); - console.log("Sending domain deleted"); - - } catch (error) { - console.error("Error in sendingDomainsFlow:", error instanceof Error ? error.message : String(error)); - } -} - -sendingDomainsFlow(); diff --git a/examples/testing/attachments.ts b/examples/testing/attachments.ts deleted file mode 100644 index 51eaed20..00000000 --- a/examples/testing/attachments.ts +++ /dev/null @@ -1,33 +0,0 @@ -import { MailtrapClient } from "mailtrap" - -const TOKEN = ""; -const TEST_INBOX_ID = "" -const ACCOUNT_ID = "" - -const client = new MailtrapClient({ token: TOKEN, testInboxId: TEST_INBOX_ID, accountId: ACCOUNT_ID }); - -const inboxesClient = client.testing.inboxes -const messagesClient = client.testing.messages -const attachmentsClient = client.testing.attachments - -inboxesClient.getList() - .then(async (inboxes) => { - if (inboxes && inboxes.length > 0) { - const firstInboxId = inboxes[0].id - - const messages = await messagesClient.get(firstInboxId) - - if (messages && messages.length > 0) { - const firstMessageId = messages[0].id - - const attachments = await attachmentsClient.getList(firstMessageId, firstInboxId) - - if (attachments && attachments.length > 0) { - const firstAttachment = attachments[0].id - const attachmentData = await attachmentsClient.get(firstInboxId, firstMessageId, firstAttachment) - - console.log(attachmentData) - } - } - } - }) diff --git a/examples/testing/inboxes.ts b/examples/testing/inboxes.ts deleted file mode 100644 index fd30a1e1..00000000 --- a/examples/testing/inboxes.ts +++ /dev/null @@ -1,35 +0,0 @@ -import { MailtrapClient } from "mailtrap" - -const TOKEN = ""; -const TEST_INBOX_ID = "" -const ACCOUNT_ID = "" - -const client = new MailtrapClient({ token: TOKEN, testInboxId: TEST_INBOX_ID, accountId: ACCOUNT_ID }); - -const projectsClient = client.testing.projects -const inboxesClient = client.testing.inboxes - -projectsClient.getList() - .then(async (projects) => { - if (projects && projects.length > 0) { - const firstProjectId = projects[0].id - - await inboxesClient.create(firstProjectId, 'test-inbox') - - const inboxes = await inboxesClient.getList() - - if (inboxes && inboxes.length > 0) { - const firstInboxId = inboxes[0].id - - const inboxAttributes = await inboxesClient.getInboxAttributes(firstInboxId) - await inboxesClient.updateInbox(firstInboxId, {name: 'mock-name', emailUsername: 'mocker'}) - await inboxesClient.cleanInbox(firstInboxId) - await inboxesClient.markAsRead(firstInboxId) - await inboxesClient.resetCredentials(firstInboxId) - await inboxesClient.enableEmailAddress(firstInboxId) - const response = await inboxesClient.resetEmailAddress(firstInboxId) - - console.log(response) - } - } - }) diff --git a/examples/testing/messages.ts b/examples/testing/messages.ts deleted file mode 100644 index 1295a68a..00000000 --- a/examples/testing/messages.ts +++ /dev/null @@ -1,41 +0,0 @@ -import { MailtrapClient } from "mailtrap" - -const TOKEN = ""; -const TEST_INBOX_ID = "" -const ACCOUNT_ID = "" - -const client = new MailtrapClient({ token: TOKEN, testInboxId: TEST_INBOX_ID, accountId: ACCOUNT_ID }); - -const inboxesClient = client.testing.inboxes -const messagesClient = client.testing.messages - -inboxesClient.getList() - .then(async (inboxes) => { - if (inboxes && inboxes.length > 0) { - const firstInboxId = inboxes[0].id - - const messages = await messagesClient.get(firstInboxId) - - if (messages && messages.length > 0) { - const firstMessageId = messages[0].id - - await messagesClient.get(firstInboxId) - await messagesClient.getHtmlAnalysis(firstInboxId, firstMessageId) - await messagesClient.getHtmlMessage(firstInboxId, firstMessageId) - await messagesClient.getTextMessage(firstInboxId, firstMessageId) - await messagesClient.getMailHeaders(firstInboxId, firstMessageId) - await messagesClient.getMessageAsEml(firstInboxId, firstMessageId) - await messagesClient.getMessageHtmlSource(firstInboxId, firstMessageId) - await messagesClient.getRawMessage(firstInboxId, firstMessageId) - await messagesClient.getSpamScore(firstInboxId, firstMessageId) - await messagesClient.showEmailMessage(firstInboxId, firstMessageId) - await messagesClient.updateMessage(firstInboxId, firstMessageId, { - isRead: false - }) - await messagesClient.forward(firstInboxId, firstMessageId, 'mock@mail.com') - const response = await messagesClient.deleteMessage(firstInboxId, firstMessageId) - - console.log(response) - } - } - }) diff --git a/src/__tests__/lib/api/Sandbox.test.ts b/src/__tests__/lib/api/Sandbox.test.ts new file mode 100644 index 00000000..c328a0bf --- /dev/null +++ b/src/__tests__/lib/api/Sandbox.test.ts @@ -0,0 +1,43 @@ +import axios from "axios"; + +import Sandbox from "../../../lib/api/Sandbox"; +import Testing from "../../../lib/api/Testing"; +import InboxesApi from "../../../lib/api/resources/Inboxes"; +import warnDeprecated from "../../../lib/deprecation"; + +jest.mock("../../../lib/deprecation"); + +describe("lib/api/Sandbox: ", () => { + const accountId = 100; + const sandboxAPI = new Sandbox(axios, accountId); + + describe("class Sandbox(): ", () => { + describe("init: ", () => { + it("initializes with all necessary params.", () => { + expect(sandboxAPI).toHaveProperty("projects"); + expect(sandboxAPI).toHaveProperty("sandboxes"); + expect(sandboxAPI).toHaveProperty("messages"); + expect(sandboxAPI).toHaveProperty("attachments"); + }); + }); + }); + + describe("class Testing() (deprecated): ", () => { + const testingAPI = new Testing(axios, accountId); + + it("keeps the Sandbox resources.", () => { + expect(testingAPI).toBeInstanceOf(Sandbox); + }); + + it("inboxes returns the same InboxesApi and warns.", () => { + const { inboxes } = testingAPI; + + expect(inboxes).toBeInstanceOf(InboxesApi); + expect(testingAPI.inboxes).toBe(inboxes); + expect(warnDeprecated).toHaveBeenCalledWith( + "client.testing.inboxes", + "client.sandbox.sandboxes" + ); + }); + }); +}); diff --git a/src/__tests__/lib/api/Testing.test.ts b/src/__tests__/lib/api/Testing.test.ts deleted file mode 100644 index b77b35d3..00000000 --- a/src/__tests__/lib/api/Testing.test.ts +++ /dev/null @@ -1,19 +0,0 @@ -import axios from "axios"; - -import Testing from "../../../lib/api/Testing"; - -describe("lib/api/Testing: ", () => { - const testInboxId = 100; - const testingAPI = new Testing(axios, testInboxId); - - describe("class Testing(): ", () => { - describe("init: ", () => { - it("initializes with all necessary params.", () => { - expect(testingAPI).toHaveProperty("projects"); - expect(testingAPI).toHaveProperty("inboxes"); - expect(testingAPI).toHaveProperty("messages"); - expect(testingAPI).toHaveProperty("attachments"); - }); - }); - }); -}); diff --git a/src/__tests__/lib/api/resources/Attachments.test.ts b/src/__tests__/lib/api/resources/Attachments.test.ts index 21a696e8..2c5f5501 100644 --- a/src/__tests__/lib/api/resources/Attachments.test.ts +++ b/src/__tests__/lib/api/resources/Attachments.test.ts @@ -28,7 +28,7 @@ describe("lib/api/resources/Attachments: ", () => { attachment_human_size: "mock-attachment_human_size", download_path: "mock-download_path", }; - const inboxId = 1; + const sandboxId = 1; const messageId = 1; const attachmentId = 100; @@ -58,11 +58,11 @@ describe("lib/api/resources/Attachments: ", () => { describe("getList(): ", () => { it("successfully gets list of attachments.", async () => { - const endpoint = `${GENERAL_ENDPOINT}/api/accounts/${accountId}/inboxes/${inboxId}/messages/${messageId}/attachments`; + const endpoint = `${GENERAL_ENDPOINT}/api/accounts/${accountId}/inboxes/${sandboxId}/messages/${messageId}/attachments`; const expectedResponseData = [responseData]; mock.onGet(endpoint).reply(200, expectedResponseData); - const result = await attachmentsAPI.getList(inboxId, messageId); + const result = await attachmentsAPI.getList(sandboxId, messageId); expect(mock.history.get[0].url).toEqual(endpoint); expect(result).toEqual(expectedResponseData); @@ -74,7 +74,7 @@ describe("lib/api/resources/Attachments: ", () => { expect.assertions(2); try { - await attachmentsAPI.getList(inboxId, messageId); + await attachmentsAPI.getList(sandboxId, messageId); } catch (error) { expect(error).toBeInstanceOf(MailtrapError); @@ -87,10 +87,14 @@ describe("lib/api/resources/Attachments: ", () => { describe("get(): ", () => { it("successfully gets single attachment.", async () => { - const endpoint = `${GENERAL_ENDPOINT}/api/accounts/${accountId}/inboxes/${inboxId}/messages/${messageId}/attachments/${attachmentId}`; + const endpoint = `${GENERAL_ENDPOINT}/api/accounts/${accountId}/inboxes/${sandboxId}/messages/${messageId}/attachments/${attachmentId}`; mock.onGet(endpoint).reply(200, responseData); - const result = await attachmentsAPI.get(inboxId, messageId, attachmentId); + const result = await attachmentsAPI.get( + sandboxId, + messageId, + attachmentId + ); expect(mock.history.get[0].url).toEqual(endpoint); expect(result).toEqual(responseData); @@ -102,7 +106,7 @@ describe("lib/api/resources/Attachments: ", () => { expect.assertions(2); try { - await attachmentsAPI.get(inboxId, messageId, attachmentId); + await attachmentsAPI.get(sandboxId, messageId, attachmentId); } catch (error) { expect(error).toBeInstanceOf(MailtrapError); diff --git a/src/__tests__/lib/api/resources/SendingDomains.test.ts b/src/__tests__/lib/api/resources/Domains.test.ts similarity index 64% rename from src/__tests__/lib/api/resources/SendingDomains.test.ts rename to src/__tests__/lib/api/resources/Domains.test.ts index ee162484..5cad1923 100644 --- a/src/__tests__/lib/api/resources/SendingDomains.test.ts +++ b/src/__tests__/lib/api/resources/Domains.test.ts @@ -1,14 +1,18 @@ import axios, { AxiosInstance } from "axios"; import MockAdapter from "axios-mock-adapter"; +import DomainsBaseAPI from "../../../../lib/api/Domains"; import SendingDomainsBaseAPI from "../../../../lib/api/SendingDomains"; +import DomainsApi from "../../../../lib/api/resources/Domains"; +import SendingDomainsApi from "../../../../lib/api/resources/SendingDomains"; import { - SendingDomain, + Domain, DnsRecord, - SendingDomainPermissions, -} from "../../../../types/api/sending-domains"; + DomainPermissions, +} from "../../../../types/api/domains"; +import { SendingDomainsResponse } from "../../../../types/api/sending-domains"; -describe("lib/api/SendingDomains: ", () => { +describe("lib/api/Domains: ", () => { const axiosInstance: AxiosInstance = axios.create(); const mock = new MockAdapter(axiosInstance); @@ -16,25 +20,22 @@ describe("lib/api/SendingDomains: ", () => { axiosInstance.interceptors.response.use((response) => response.data); const testAccountId = 100; - const sendingDomainsAPI = new SendingDomainsBaseAPI( - axiosInstance, - testAccountId - ); + const domainsAPI = new DomainsBaseAPI(axiosInstance, testAccountId); - describe("class SendingDomainsBaseAPI(): ", () => { + describe("class DomainsBaseAPI(): ", () => { describe("init: ", () => { it("initializes with all necessary params.", () => { - expect(sendingDomainsAPI).toHaveProperty("get"); - expect(sendingDomainsAPI).toHaveProperty("getList"); - expect(sendingDomainsAPI).toHaveProperty("create"); - expect(sendingDomainsAPI).toHaveProperty("update"); - expect(sendingDomainsAPI).toHaveProperty("delete"); - expect(sendingDomainsAPI).toHaveProperty("sendSetupInstructions"); + expect(domainsAPI).toHaveProperty("get"); + expect(domainsAPI).toHaveProperty("getList"); + expect(domainsAPI).toHaveProperty("create"); + expect(domainsAPI).toHaveProperty("update"); + expect(domainsAPI).toHaveProperty("delete"); + expect(domainsAPI).toHaveProperty("sendSetupInstructions"); }); }); - describe("sendingDomains.getList(): ", () => { - it("should get sending domains list.", async () => { + describe("domains.getList(): ", () => { + it("should get domains list.", async () => { const mockDnsRecords: DnsRecord[] = [ { key: "verification", @@ -54,13 +55,13 @@ describe("lib/api/SendingDomains: ", () => { }, ]; - const mockPermissions: SendingDomainPermissions = { + const mockPermissions: DomainPermissions = { can_read: true, can_update: true, can_destroy: true, }; - const mockSendingDomains: SendingDomain[] = [ + const mockDomains: Domain[] = [ { id: 435, domain_name: "example.com", @@ -87,16 +88,16 @@ describe("lib/api/SendingDomains: ", () => { .onGet( `https://mailtrap.io/api/accounts/${testAccountId}/sending_domains` ) - .reply(200, { data: mockSendingDomains }); + .reply(200, { data: mockDomains }); - const result = await sendingDomainsAPI.getList(); + const result = await domainsAPI.getList(); - expect(result).toEqual({ data: mockSendingDomains }); + expect(result).toEqual({ data: mockDomains }); }); }); - describe("sendingDomains.get(): ", () => { - it("should get a single sending domain by id.", async () => { + describe("domains.get(): ", () => { + it("should get a single domain by id.", async () => { const mockDnsRecords: DnsRecord[] = [ { key: "verification", @@ -108,13 +109,13 @@ describe("lib/api/SendingDomains: ", () => { }, ]; - const mockPermissions: SendingDomainPermissions = { + const mockPermissions: DomainPermissions = { can_read: true, can_update: true, can_destroy: true, }; - const mockSendingDomain: SendingDomain = { + const mockDomain: Domain = { id: 999, domain_name: "example.com", demo: false, @@ -137,18 +138,18 @@ describe("lib/api/SendingDomains: ", () => { mock .onGet( - `https://mailtrap.io/api/accounts/${testAccountId}/sending_domains/${mockSendingDomain.id}` + `https://mailtrap.io/api/accounts/${testAccountId}/sending_domains/${mockDomain.id}` ) - .reply(200, mockSendingDomain); + .reply(200, mockDomain); - const result = await sendingDomainsAPI.get(mockSendingDomain.id); + const result = await domainsAPI.get(mockDomain.id); - expect(result).toEqual(mockSendingDomain); + expect(result).toEqual(mockDomain); }); }); - describe("sendingDomains.create(): ", () => { - it("should create a new sending domain.", async () => { + describe("domains.create(): ", () => { + it("should create a new domain.", async () => { const mockDnsRecords: DnsRecord[] = [ { key: "verification", @@ -160,13 +161,13 @@ describe("lib/api/SendingDomains: ", () => { }, ]; - const mockPermissions: SendingDomainPermissions = { + const mockPermissions: DomainPermissions = { can_read: true, can_update: true, can_destroy: true, }; - const mockSendingDomain: SendingDomain = { + const mockDomain: Domain = { id: 436, domain_name: "newdomain.com", demo: false, @@ -196,23 +197,23 @@ describe("lib/api/SendingDomains: ", () => { `https://mailtrap.io/api/accounts/${testAccountId}/sending_domains`, { sending_domain: createParams } ) - .reply(201, mockSendingDomain); + .reply(201, mockDomain); - const result = await sendingDomainsAPI.create(createParams); + const result = await domainsAPI.create(createParams); - expect(result).toEqual(mockSendingDomain); + expect(result).toEqual(mockDomain); }); }); - describe("sendingDomains.update(): ", () => { - it("should update a sending domain.", async () => { - const mockPermissions: SendingDomainPermissions = { + describe("domains.update(): ", () => { + it("should update a domain.", async () => { + const mockPermissions: DomainPermissions = { can_read: true, can_update: true, can_destroy: true, }; - const mockSendingDomain: SendingDomain = { + const mockDomain: Domain = { id: 435, domain_name: "example.com", demo: false, @@ -243,54 +244,73 @@ describe("lib/api/SendingDomains: ", () => { mock .onPatch( - `https://mailtrap.io/api/accounts/${testAccountId}/sending_domains/${mockSendingDomain.id}`, + `https://mailtrap.io/api/accounts/${testAccountId}/sending_domains/${mockDomain.id}`, { sending_domain: updateParams } ) - .reply(200, mockSendingDomain); + .reply(200, mockDomain); - const result = await sendingDomainsAPI.update( - mockSendingDomain.id, - updateParams - ); + const result = await domainsAPI.update(mockDomain.id, updateParams); - expect(result).toEqual(mockSendingDomain); + expect(result).toEqual(mockDomain); }); }); - describe("sendingDomains.delete(): ", () => { - it("should delete a sending domain by id.", async () => { - const sendingDomainId = 999; + describe("domains.delete(): ", () => { + it("should delete a domain by id.", async () => { + const domainId = 999; mock .onDelete( - `https://mailtrap.io/api/accounts/${testAccountId}/sending_domains/${sendingDomainId}` + `https://mailtrap.io/api/accounts/${testAccountId}/sending_domains/${domainId}` ) .reply(204); - const result = await sendingDomainsAPI.delete(sendingDomainId); + const result = await domainsAPI.delete(domainId); expect(result).toBeUndefined(); }); }); - describe("sendingDomains.sendSetupInstructions(): ", () => { - it("should send setup instructions for a sending domain.", async () => { - const sendingDomainId = 999; + describe("domains.sendSetupInstructions(): ", () => { + it("should send setup instructions for a domain.", async () => { + const domainId = 999; const email = "admin@example.com"; mock .onPost( - `https://mailtrap.io/api/accounts/${testAccountId}/sending_domains/${sendingDomainId}/send_setup_instructions` + `https://mailtrap.io/api/accounts/${testAccountId}/sending_domains/${domainId}/send_setup_instructions` ) .reply(204); - const result = await sendingDomainsAPI.sendSetupInstructions( - sendingDomainId, - email - ); + const result = await domainsAPI.sendSetupInstructions(domainId, email); expect(result).toBeUndefined(); }); }); }); + + describe("deprecated SendingDomains names: ", () => { + it("SendingDomainsBaseAPI is a DomainsBaseAPI calling the same endpoints.", async () => { + const sendingDomainsAPI = new SendingDomainsBaseAPI( + axiosInstance, + testAccountId + ); + mock + .onGet( + `https://mailtrap.io/api/accounts/${testAccountId}/sending_domains` + ) + .reply(200, { data: [] }); + + const result: SendingDomainsResponse = await sendingDomainsAPI.getList(); + + expect(sendingDomainsAPI).toBeInstanceOf(DomainsBaseAPI); + expect(result).toEqual({ data: [] }); + }); + + it("SendingDomainsApi is a DomainsApi.", () => { + expect( + new SendingDomainsApi(axiosInstance, testAccountId) + ).toBeInstanceOf(DomainsApi); + }); + }); }); diff --git a/src/__tests__/lib/api/resources/Messages.test.ts b/src/__tests__/lib/api/resources/Messages.test.ts index 9e49e881..85327311 100644 --- a/src/__tests__/lib/api/resources/Messages.test.ts +++ b/src/__tests__/lib/api/resources/Messages.test.ts @@ -14,7 +14,7 @@ describe("lib/api/resources/Messages: ", () => { let mock: AxiosMockAdapter; const accountId = 100; const messagesAPI = new Messages(axios, accountId); - const inboxId = 1; + const sandboxId = 1; const messageId = 1; const responseData = { id: 1, @@ -80,11 +80,11 @@ describe("lib/api/resources/Messages: ", () => { describe("showEmailMessage(): ", () => { it("successfully deletes message.", async () => { - const endpoint = `${GENERAL_ENDPOINT}/api/accounts/${accountId}/inboxes/${inboxId}/messages/${messageId}`; + const endpoint = `${GENERAL_ENDPOINT}/api/accounts/${accountId}/inboxes/${sandboxId}/messages/${messageId}`; mock.onGet(endpoint).reply(200, responseData); - const result = await messagesAPI.showEmailMessage(inboxId, messageId); + const result = await messagesAPI.showEmailMessage(sandboxId, messageId); expect(mock.history.get[0].url).toEqual(endpoint); expect(result).toEqual(responseData); @@ -96,7 +96,7 @@ describe("lib/api/resources/Messages: ", () => { expect.assertions(2); try { - await messagesAPI.showEmailMessage(inboxId, messageId); + await messagesAPI.showEmailMessage(sandboxId, messageId); } catch (error) { expect(error).toBeInstanceOf(MailtrapError); @@ -109,11 +109,11 @@ describe("lib/api/resources/Messages: ", () => { describe("updateMessage(): ", () => { it("successfully updates message.", async () => { - const endpoint = `${GENERAL_ENDPOINT}/api/accounts/${accountId}/inboxes/${inboxId}/messages/${messageId}`; + const endpoint = `${GENERAL_ENDPOINT}/api/accounts/${accountId}/inboxes/${sandboxId}/messages/${messageId}`; mock.onPatch(endpoint).reply(200, responseData); - const result = await messagesAPI.updateMessage(inboxId, messageId, { + const result = await messagesAPI.updateMessage(sandboxId, messageId, { isRead: true, }); @@ -129,7 +129,7 @@ describe("lib/api/resources/Messages: ", () => { expect.assertions(2); try { - await messagesAPI.updateMessage(inboxId, messageId, { + await messagesAPI.updateMessage(sandboxId, messageId, { isRead: true, }); } catch (error) { @@ -144,11 +144,11 @@ describe("lib/api/resources/Messages: ", () => { describe("deleteMessage(): ", () => { it("successfully deletes message.", async () => { - const endpoint = `${GENERAL_ENDPOINT}/api/accounts/${accountId}/inboxes/${inboxId}/messages/${messageId}`; + const endpoint = `${GENERAL_ENDPOINT}/api/accounts/${accountId}/inboxes/${sandboxId}/messages/${messageId}`; mock.onDelete(endpoint).reply(200, responseData); - const result = await messagesAPI.deleteMessage(inboxId, messageId); + const result = await messagesAPI.deleteMessage(sandboxId, messageId); expect(mock.history.delete[0].url).toEqual(endpoint); expect(mock.history.delete[0].data).toBeUndefined(); @@ -161,7 +161,7 @@ describe("lib/api/resources/Messages: ", () => { expect.assertions(2); try { - await messagesAPI.deleteMessage(inboxId, messageId); + await messagesAPI.deleteMessage(sandboxId, messageId); } catch (error) { expect(error).toBeInstanceOf(MailtrapError); @@ -174,19 +174,19 @@ describe("lib/api/resources/Messages: ", () => { describe("get(): ", () => { it("successfully gets all messages.", async () => { - const endpoint = `${GENERAL_ENDPOINT}/api/accounts/${accountId}/inboxes/${inboxId}/messages`; + const endpoint = `${GENERAL_ENDPOINT}/api/accounts/${accountId}/inboxes/${sandboxId}/messages`; const expectedResponseData = [responseData]; mock.onGet(endpoint).reply(200, expectedResponseData); - const result = await messagesAPI.get(inboxId); + const result = await messagesAPI.get(sandboxId); expect(mock.history.get[0].url).toEqual(endpoint); expect(result).toEqual(expectedResponseData); }); it("successfully gets messages with last_id parameter.", async () => { - const endpoint = `${GENERAL_ENDPOINT}/api/accounts/${accountId}/inboxes/${inboxId}/messages`; + const endpoint = `${GENERAL_ENDPOINT}/api/accounts/${accountId}/inboxes/${sandboxId}/messages`; const lastId = 100; const expectedResponseData = [responseData]; @@ -194,7 +194,7 @@ describe("lib/api/resources/Messages: ", () => { .onGet(endpoint, { params: { last_id: lastId } }) .reply(200, expectedResponseData); - const result = await messagesAPI.get(inboxId, { last_id: lastId }); + const result = await messagesAPI.get(sandboxId, { last_id: lastId }); expect(mock.history.get[0].url).toEqual(endpoint); expect(mock.history.get[0].params).toEqual({ last_id: lastId }); @@ -202,7 +202,7 @@ describe("lib/api/resources/Messages: ", () => { }); it("successfully gets messages with page parameter.", async () => { - const endpoint = `${GENERAL_ENDPOINT}/api/accounts/${accountId}/inboxes/${inboxId}/messages`; + const endpoint = `${GENERAL_ENDPOINT}/api/accounts/${accountId}/inboxes/${sandboxId}/messages`; const page = 2; const expectedResponseData = [responseData]; @@ -210,7 +210,7 @@ describe("lib/api/resources/Messages: ", () => { .onGet(endpoint, { params: { page } }) .reply(200, expectedResponseData); - const result = await messagesAPI.get(inboxId, { page }); + const result = await messagesAPI.get(sandboxId, { page }); expect(mock.history.get[0].url).toEqual(endpoint); expect(mock.history.get[0].params).toEqual({ page }); @@ -218,7 +218,7 @@ describe("lib/api/resources/Messages: ", () => { }); it("successfully gets messages with search parameter.", async () => { - const endpoint = `${GENERAL_ENDPOINT}/api/accounts/${accountId}/inboxes/${inboxId}/messages`; + const endpoint = `${GENERAL_ENDPOINT}/api/accounts/${accountId}/inboxes/${sandboxId}/messages`; const search = "test query"; const expectedResponseData = [responseData]; @@ -226,7 +226,7 @@ describe("lib/api/resources/Messages: ", () => { .onGet(endpoint, { params: { search } }) .reply(200, expectedResponseData); - const result = await messagesAPI.get(inboxId, { search }); + const result = await messagesAPI.get(sandboxId, { search }); expect(mock.history.get[0].url).toEqual(endpoint); expect(mock.history.get[0].params).toEqual({ search }); @@ -234,7 +234,7 @@ describe("lib/api/resources/Messages: ", () => { }); it("successfully gets messages with all query parameters.", async () => { - const endpoint = `${GENERAL_ENDPOINT}/api/accounts/${accountId}/inboxes/${inboxId}/messages`; + const endpoint = `${GENERAL_ENDPOINT}/api/accounts/${accountId}/inboxes/${sandboxId}/messages`; const options = { last_id: 100, page: 2, search: "test query" }; const expectedResponseData = [responseData]; @@ -242,7 +242,7 @@ describe("lib/api/resources/Messages: ", () => { .onGet(endpoint, { params: options }) .reply(200, expectedResponseData); - const result = await messagesAPI.get(inboxId, options); + const result = await messagesAPI.get(sandboxId, options); expect(mock.history.get[0].url).toEqual(endpoint); expect(mock.history.get[0].params).toEqual(options); @@ -255,7 +255,7 @@ describe("lib/api/resources/Messages: ", () => { expect.assertions(2); try { - await messagesAPI.get(inboxId); + await messagesAPI.get(sandboxId); } catch (error) { expect(error).toBeInstanceOf(MailtrapError); @@ -270,12 +270,12 @@ describe("lib/api/resources/Messages: ", () => { const emailToForward = "mock@emailtoforward.com"; it("successfully forwards message.", async () => { - const endpoint = `${GENERAL_ENDPOINT}/api/accounts/${accountId}/inboxes/${inboxId}/messages/${messageId}/forward`; + const endpoint = `${GENERAL_ENDPOINT}/api/accounts/${accountId}/inboxes/${sandboxId}/messages/${messageId}/forward`; mock.onPost(endpoint).reply(200, responseData); const result = await messagesAPI.forward( - inboxId, + sandboxId, messageId, emailToForward ); @@ -293,7 +293,7 @@ describe("lib/api/resources/Messages: ", () => { expect.assertions(2); try { - await messagesAPI.forward(inboxId, messageId, emailToForward); + await messagesAPI.forward(sandboxId, messageId, emailToForward); } catch (error) { expect(error).toBeInstanceOf(MailtrapError); @@ -316,11 +316,11 @@ describe("lib/api/resources/Messages: ", () => { }; it("successfully gets message spam score.", async () => { - const endpoint = `${GENERAL_ENDPOINT}/api/accounts/${accountId}/inboxes/${inboxId}/messages/${messageId}/spam_report`; + const endpoint = `${GENERAL_ENDPOINT}/api/accounts/${accountId}/inboxes/${sandboxId}/messages/${messageId}/spam_report`; mock.onGet(endpoint).reply(200, spamReportData); - const result = await messagesAPI.getSpamScore(inboxId, messageId); + const result = await messagesAPI.getSpamScore(sandboxId, messageId); expect(mock.history.get[0].url).toEqual(endpoint); expect(result).toEqual(spamReportData); @@ -332,7 +332,7 @@ describe("lib/api/resources/Messages: ", () => { expect.assertions(2); try { - await messagesAPI.getSpamScore(inboxId, messageId); + await messagesAPI.getSpamScore(sandboxId, messageId); } catch (error) { expect(error).toBeInstanceOf(MailtrapError); @@ -350,11 +350,11 @@ describe("lib/api/resources/Messages: ", () => { }; it("successfully gets html analysis.", async () => { - const endpoint = `${GENERAL_ENDPOINT}/api/accounts/${accountId}/inboxes/${inboxId}/messages/${messageId}/analyze`; + const endpoint = `${GENERAL_ENDPOINT}/api/accounts/${accountId}/inboxes/${sandboxId}/messages/${messageId}/analyze`; mock.onGet(endpoint).reply(200, htmlReportData); - const result = await messagesAPI.getHtmlAnalysis(inboxId, messageId); + const result = await messagesAPI.getHtmlAnalysis(sandboxId, messageId); expect(mock.history.get[0].url).toEqual(endpoint); expect(result).toEqual(htmlReportData); @@ -366,7 +366,7 @@ describe("lib/api/resources/Messages: ", () => { expect.assertions(2); try { - await messagesAPI.getHtmlAnalysis(inboxId, messageId); + await messagesAPI.getHtmlAnalysis(sandboxId, messageId); } catch (error) { expect(error).toBeInstanceOf(MailtrapError); @@ -379,11 +379,11 @@ describe("lib/api/resources/Messages: ", () => { describe("getTextMessage(): ", () => { it("successfully gets text message.", async () => { - const endpoint = `${GENERAL_ENDPOINT}/api/accounts/${accountId}/inboxes/${inboxId}/messages/${messageId}/body.txt`; + const endpoint = `${GENERAL_ENDPOINT}/api/accounts/${accountId}/inboxes/${sandboxId}/messages/${messageId}/body.txt`; const message = "mock-message"; mock.onGet(endpoint).reply(200, message); - const result = await messagesAPI.getTextMessage(inboxId, messageId); + const result = await messagesAPI.getTextMessage(sandboxId, messageId); expect(mock.history.get[0].url).toEqual(endpoint); expect(result).toEqual(message); @@ -395,7 +395,7 @@ describe("lib/api/resources/Messages: ", () => { expect.assertions(2); try { - await messagesAPI.getTextMessage(inboxId, messageId); + await messagesAPI.getTextMessage(sandboxId, messageId); } catch (error) { expect(error).toBeInstanceOf(MailtrapError); @@ -408,11 +408,11 @@ describe("lib/api/resources/Messages: ", () => { describe("getRawMessage(): ", () => { it("successfully gets raw message.", async () => { - const endpoint = `${GENERAL_ENDPOINT}/api/accounts/${accountId}/inboxes/${inboxId}/messages/${messageId}/body.raw`; + const endpoint = `${GENERAL_ENDPOINT}/api/accounts/${accountId}/inboxes/${sandboxId}/messages/${messageId}/body.raw`; const message = "mock-message"; mock.onGet(endpoint).reply(200, message); - const result = await messagesAPI.getRawMessage(inboxId, messageId); + const result = await messagesAPI.getRawMessage(sandboxId, messageId); expect(mock.history.get[0].url).toEqual(endpoint); expect(result).toEqual(message); @@ -424,7 +424,7 @@ describe("lib/api/resources/Messages: ", () => { expect.assertions(2); try { - await messagesAPI.getRawMessage(inboxId, messageId); + await messagesAPI.getRawMessage(sandboxId, messageId); } catch (error) { expect(error).toBeInstanceOf(MailtrapError); @@ -437,11 +437,14 @@ describe("lib/api/resources/Messages: ", () => { describe("getMessageHtmlSource(): ", () => { it("successfully gets html source.", async () => { - const endpoint = `${GENERAL_ENDPOINT}/api/accounts/${accountId}/inboxes/${inboxId}/messages/${messageId}/body.htmlsource`; + const endpoint = `${GENERAL_ENDPOINT}/api/accounts/${accountId}/inboxes/${sandboxId}/messages/${messageId}/body.htmlsource`; const htmlSource = "mock-htmlSource"; mock.onGet(endpoint).reply(200, htmlSource); - const result = await messagesAPI.getMessageHtmlSource(inboxId, messageId); + const result = await messagesAPI.getMessageHtmlSource( + sandboxId, + messageId + ); expect(mock.history.get[0].url).toEqual(endpoint); expect(result).toEqual(htmlSource); @@ -453,7 +456,7 @@ describe("lib/api/resources/Messages: ", () => { expect.assertions(2); try { - await messagesAPI.getMessageHtmlSource(inboxId, messageId); + await messagesAPI.getMessageHtmlSource(sandboxId, messageId); } catch (error) { expect(error).toBeInstanceOf(MailtrapError); @@ -466,11 +469,11 @@ describe("lib/api/resources/Messages: ", () => { describe("getHtmlMessage(): ", () => { it("successfully gets html message.", async () => { - const endpoint = `${GENERAL_ENDPOINT}/api/accounts/${accountId}/inboxes/${inboxId}/messages/${messageId}/body.html`; + const endpoint = `${GENERAL_ENDPOINT}/api/accounts/${accountId}/inboxes/${sandboxId}/messages/${messageId}/body.html`; const html = "
interesting mock
"; mock.onGet(endpoint).reply(200, html); - const result = await messagesAPI.getHtmlMessage(inboxId, messageId); + const result = await messagesAPI.getHtmlMessage(sandboxId, messageId); expect(mock.history.get[0].url).toEqual(endpoint); expect(result).toEqual(html); @@ -482,7 +485,7 @@ describe("lib/api/resources/Messages: ", () => { expect.assertions(2); try { - await messagesAPI.getHtmlMessage(inboxId, messageId); + await messagesAPI.getHtmlMessage(sandboxId, messageId); } catch (error) { expect(error).toBeInstanceOf(MailtrapError); @@ -495,11 +498,11 @@ describe("lib/api/resources/Messages: ", () => { describe("getMessageAsEml(): ", () => { it("successfully gets mail headers.", async () => { - const endpoint = `${GENERAL_ENDPOINT}/api/accounts/${accountId}/inboxes/${inboxId}/messages/${messageId}/body.eml`; + const endpoint = `${GENERAL_ENDPOINT}/api/accounts/${accountId}/inboxes/${sandboxId}/messages/${messageId}/body.eml`; const eml = "mock-eml"; mock.onGet(endpoint).reply(200, eml); - const result = await messagesAPI.getMessageAsEml(inboxId, messageId); + const result = await messagesAPI.getMessageAsEml(sandboxId, messageId); expect(mock.history.get[0].url).toEqual(endpoint); expect(result).toEqual(eml); @@ -511,7 +514,7 @@ describe("lib/api/resources/Messages: ", () => { expect.assertions(2); try { - await messagesAPI.getMessageAsEml(inboxId, messageId); + await messagesAPI.getMessageAsEml(sandboxId, messageId); } catch (error) { expect(error).toBeInstanceOf(MailtrapError); @@ -524,11 +527,11 @@ describe("lib/api/resources/Messages: ", () => { describe("getMailHeaders(): ", () => { it("successfully gets message html source.", async () => { - const endpoint = `${GENERAL_ENDPOINT}/api/accounts/${accountId}/inboxes/${inboxId}/messages/${messageId}/mail_headers`; + const endpoint = `${GENERAL_ENDPOINT}/api/accounts/${accountId}/inboxes/${sandboxId}/messages/${messageId}/mail_headers`; const eml = "mock-eml"; mock.onGet(endpoint).reply(200, eml); - const result = await messagesAPI.getMailHeaders(inboxId, messageId); + const result = await messagesAPI.getMailHeaders(sandboxId, messageId); expect(mock.history.get[0].url).toEqual(endpoint); expect(result).toEqual(eml); @@ -540,7 +543,7 @@ describe("lib/api/resources/Messages: ", () => { expect.assertions(2); try { - await messagesAPI.getMailHeaders(inboxId, messageId); + await messagesAPI.getMailHeaders(sandboxId, messageId); } catch (error) { expect(error).toBeInstanceOf(MailtrapError); diff --git a/src/__tests__/lib/api/resources/Inboxes.test.ts b/src/__tests__/lib/api/resources/Sandboxes.test.ts similarity index 61% rename from src/__tests__/lib/api/resources/Inboxes.test.ts rename to src/__tests__/lib/api/resources/Sandboxes.test.ts index cc86e6a9..a2e9df97 100644 --- a/src/__tests__/lib/api/resources/Inboxes.test.ts +++ b/src/__tests__/lib/api/resources/Sandboxes.test.ts @@ -1,19 +1,24 @@ import axios from "axios"; import AxiosMockAdapter from "axios-mock-adapter"; -import Inboxes from "../../../../lib/api/resources/Inboxes"; +import Sandboxes from "../../../../lib/api/resources/Sandboxes"; +import InboxesApi from "../../../../lib/api/resources/Inboxes"; +import warnDeprecated from "../../../../lib/deprecation"; import handleSendingError from "../../../../lib/axios-logger"; import MailtrapError from "../../../../lib/MailtrapError"; import CONFIG from "../../../../config"; +import { Inbox } from "../../../../types/api/inboxes"; + +jest.mock("../../../../lib/deprecation"); const { CLIENT_SETTINGS } = CONFIG; const { GENERAL_ENDPOINT } = CLIENT_SETTINGS; -describe("lib/api/resources/Inboxes: ", () => { +describe("lib/api/resources/Sandboxes: ", () => { let mock: AxiosMockAdapter; const accountId = 100; - const inboxesAPI = new Inboxes(axios, accountId); + const sandboxesAPI = new Sandboxes(axios, accountId); const responseData = { id: 10, name: "mock-name", @@ -40,19 +45,19 @@ describe("lib/api/resources/Inboxes: ", () => { permissions: [], }; - describe("class Inboxes(): ", () => { + describe("class Sandboxes(): ", () => { describe("init: ", () => { it("initializes with all necessary params.", () => { - expect(inboxesAPI).toHaveProperty("cleanInbox"); - expect(inboxesAPI).toHaveProperty("create"); - expect(inboxesAPI).toHaveProperty("delete"); - expect(inboxesAPI).toHaveProperty("enableEmailAddress"); - expect(inboxesAPI).toHaveProperty("getInboxAttributes"); - expect(inboxesAPI).toHaveProperty("getList"); - expect(inboxesAPI).toHaveProperty("markAsRead"); - expect(inboxesAPI).toHaveProperty("resetCredentials"); - expect(inboxesAPI).toHaveProperty("resetEmailAddress"); - expect(inboxesAPI).toHaveProperty("updateInbox"); + expect(sandboxesAPI).toHaveProperty("cleanSandbox"); + expect(sandboxesAPI).toHaveProperty("create"); + expect(sandboxesAPI).toHaveProperty("delete"); + expect(sandboxesAPI).toHaveProperty("enableEmailAddress"); + expect(sandboxesAPI).toHaveProperty("getSandboxAttributes"); + expect(sandboxesAPI).toHaveProperty("getList"); + expect(sandboxesAPI).toHaveProperty("markAsRead"); + expect(sandboxesAPI).toHaveProperty("resetCredentials"); + expect(sandboxesAPI).toHaveProperty("resetEmailAddress"); + expect(sandboxesAPI).toHaveProperty("updateSandbox"); }); }); }); @@ -78,10 +83,10 @@ describe("lib/api/resources/Inboxes: ", () => { const endpoint = `${GENERAL_ENDPOINT}/api/accounts/${accountId}/projects/${projectId}/inboxes`; mock.onPost(endpoint).reply(200, responseData); - const inboxName = "mock-inboxName"; - const result = await inboxesAPI.create(projectId, inboxName); + const sandboxName = "mock-sandboxName"; + const result = await sandboxesAPI.create(projectId, sandboxName); - const sentData = { inbox: { name: inboxName } }; + const sentData = { inbox: { name: sandboxName } }; expect(mock.history.post[0].url).toEqual(endpoint); expect(mock.history.post[0].data).toEqual(JSON.stringify(sentData)); @@ -90,13 +95,13 @@ describe("lib/api/resources/Inboxes: ", () => { it("fails with error.", async () => { const projectId = 1; - const inboxName = "mock-inboxName"; + const sandboxName = "mock-sandboxName"; const expectedErrorMessage = "Request failed with status code 404"; expect.assertions(2); try { - await inboxesAPI.create(projectId, inboxName); + await sandboxesAPI.create(projectId, sandboxName); } catch (error) { expect(error).toBeInstanceOf(MailtrapError); @@ -106,15 +111,15 @@ describe("lib/api/resources/Inboxes: ", () => { } }); - describe("updateInbox(): ", () => { - it("succesfully updates inbox.", async () => { - const inboxId = 1; - const endpoint = `${GENERAL_ENDPOINT}/api/accounts/${accountId}/inboxes/${inboxId}`; + describe("updateSandbox(): ", () => { + it("succesfully updates sandbox.", async () => { + const sandboxId = 1; + const endpoint = `${GENERAL_ENDPOINT}/api/accounts/${accountId}/inboxes/${sandboxId}`; mock.onPatch(endpoint).reply(200, responseData); - const name = "mock-inboxName"; + const name = "mock-sandboxName"; const emailUsername = "mock@email.com"; - const result = await inboxesAPI.updateInbox(inboxId, { + const result = await sandboxesAPI.updateSandbox(sandboxId, { name, emailUsername, }); @@ -132,16 +137,16 @@ describe("lib/api/resources/Inboxes: ", () => { }); it("fails with error", async () => { - const inboxId = 1; + const sandboxId = 1; const expectedErrorMessage = "Request failed with status code 404"; - const name = "mock-inboxName"; + const name = "mock-sandboxName"; const emailUsername = "mock@email.com"; expect.assertions(2); try { - await inboxesAPI.updateInbox(inboxId, { + await sandboxesAPI.updateSandbox(sandboxId, { name, emailUsername, }); @@ -155,27 +160,27 @@ describe("lib/api/resources/Inboxes: ", () => { }); }); - describe("getInboxAttributes(): ", () => { - it("succesfully gets inbox attributes.", async () => { - const inboxId = 1; - const endpoint = `${GENERAL_ENDPOINT}/api/accounts/${accountId}/inboxes/${inboxId}`; + describe("getSandboxAttributes(): ", () => { + it("succesfully gets sandbox attributes.", async () => { + const sandboxId = 1; + const endpoint = `${GENERAL_ENDPOINT}/api/accounts/${accountId}/inboxes/${sandboxId}`; mock.onGet(endpoint).reply(200, responseData); - const result = await inboxesAPI.getInboxAttributes(inboxId); + const result = await sandboxesAPI.getSandboxAttributes(sandboxId); expect(mock.history.get[0].url).toEqual(endpoint); expect(result).toEqual(responseData); }); it("fails with error", async () => { - const inboxId = 1; + const sandboxId = 1; const expectedErrorMessage = "Request failed with status code 404"; expect.assertions(2); try { - await inboxesAPI.getInboxAttributes(inboxId); + await sandboxesAPI.getSandboxAttributes(sandboxId); } catch (error) { expect(error).toBeInstanceOf(MailtrapError); @@ -188,26 +193,26 @@ describe("lib/api/resources/Inboxes: ", () => { }); describe("delete(): ", () => { - it("succesfully deletes inbox.", async () => { - const inboxId = 1; - const endpoint = `${GENERAL_ENDPOINT}/api/accounts/${accountId}/inboxes/${inboxId}`; + it("succesfully deletes sandbox.", async () => { + const sandboxId = 1; + const endpoint = `${GENERAL_ENDPOINT}/api/accounts/${accountId}/inboxes/${sandboxId}`; mock.onDelete(endpoint).reply(200, responseData); - const result = await inboxesAPI.delete(inboxId); + const result = await sandboxesAPI.delete(sandboxId); expect(mock.history.delete[0].url).toEqual(endpoint); expect(result).toEqual(responseData); }); it("fails with error", async () => { - const inboxId = 1; + const sandboxId = 1; const expectedErrorMessage = "Request failed with status code 404"; expect.assertions(2); try { - await inboxesAPI.delete(inboxId); + await sandboxesAPI.delete(sandboxId); } catch (error) { expect(error).toBeInstanceOf(MailtrapError); @@ -218,14 +223,14 @@ describe("lib/api/resources/Inboxes: ", () => { }); }); - describe("cleanInbox(): ", () => { - it("succesfully cleans inbox.", async () => { - const inboxId = 1; - const endpoint = `${GENERAL_ENDPOINT}/api/accounts/${accountId}/inboxes/${inboxId}/clean`; + describe("cleanSandbox(): ", () => { + it("succesfully cleans sandbox.", async () => { + const sandboxId = 1; + const endpoint = `${GENERAL_ENDPOINT}/api/accounts/${accountId}/inboxes/${sandboxId}/clean`; mock.onPatch(endpoint).reply(200, responseData); - const result = await inboxesAPI.cleanInbox(inboxId); + const result = await sandboxesAPI.cleanSandbox(sandboxId); expect(mock.history.patch[0].url).toEqual(endpoint); expect(mock.history.patch[0].data).toBeUndefined(); @@ -233,13 +238,13 @@ describe("lib/api/resources/Inboxes: ", () => { }); it("fails with error", async () => { - const inboxId = 1; + const sandboxId = 1; const expectedErrorMessage = "Request failed with status code 404"; expect.assertions(2); try { - await inboxesAPI.cleanInbox(inboxId); + await sandboxesAPI.cleanSandbox(sandboxId); } catch (error) { expect(error).toBeInstanceOf(MailtrapError); @@ -251,13 +256,13 @@ describe("lib/api/resources/Inboxes: ", () => { }); describe("markAsRead(): ", () => { - it("succesfully marks inbox as read.", async () => { - const inboxId = 1; - const endpoint = `${GENERAL_ENDPOINT}/api/accounts/${accountId}/inboxes/${inboxId}/all_read`; + it("succesfully marks sandbox as read.", async () => { + const sandboxId = 1; + const endpoint = `${GENERAL_ENDPOINT}/api/accounts/${accountId}/inboxes/${sandboxId}/all_read`; mock.onPatch(endpoint).reply(200, responseData); - const result = await inboxesAPI.markAsRead(inboxId); + const result = await sandboxesAPI.markAsRead(sandboxId); expect(mock.history.patch[0].url).toEqual(endpoint); expect(mock.history.patch[0].data).toBeUndefined(); @@ -265,13 +270,13 @@ describe("lib/api/resources/Inboxes: ", () => { }); it("fails with error", async () => { - const inboxId = 1; + const sandboxId = 1; const expectedErrorMessage = "Request failed with status code 404"; expect.assertions(2); try { - await inboxesAPI.markAsRead(inboxId); + await sandboxesAPI.markAsRead(sandboxId); } catch (error) { expect(error).toBeInstanceOf(MailtrapError); @@ -284,12 +289,12 @@ describe("lib/api/resources/Inboxes: ", () => { describe("resetCredentials(): ", () => { it("succesfully resets credentials.", async () => { - const inboxId = 1; - const endpoint = `${GENERAL_ENDPOINT}/api/accounts/${accountId}/inboxes/${inboxId}/reset_credentials`; + const sandboxId = 1; + const endpoint = `${GENERAL_ENDPOINT}/api/accounts/${accountId}/inboxes/${sandboxId}/reset_credentials`; mock.onPatch(endpoint).reply(200, responseData); - const result = await inboxesAPI.resetCredentials(inboxId); + const result = await sandboxesAPI.resetCredentials(sandboxId); expect(mock.history.patch[0].url).toEqual(endpoint); expect(mock.history.patch[0].data).toBeUndefined(); @@ -297,13 +302,13 @@ describe("lib/api/resources/Inboxes: ", () => { }); it("fails with error", async () => { - const inboxId = 1; + const sandboxId = 1; const expectedErrorMessage = "Request failed with status code 404"; expect.assertions(2); try { - await inboxesAPI.resetCredentials(inboxId); + await sandboxesAPI.resetCredentials(sandboxId); } catch (error) { expect(error).toBeInstanceOf(MailtrapError); @@ -316,12 +321,12 @@ describe("lib/api/resources/Inboxes: ", () => { describe("enableEmailAddress(): ", () => { it("succesfully toggles email availability.", async () => { - const inboxId = 1; - const endpoint = `${GENERAL_ENDPOINT}/api/accounts/${accountId}/inboxes/${inboxId}/toggle_email_username`; + const sandboxId = 1; + const endpoint = `${GENERAL_ENDPOINT}/api/accounts/${accountId}/inboxes/${sandboxId}/toggle_email_username`; mock.onPatch(endpoint).reply(200, responseData); - const result = await inboxesAPI.enableEmailAddress(inboxId); + const result = await sandboxesAPI.enableEmailAddress(sandboxId); expect(mock.history.patch[0].url).toEqual(endpoint); expect(mock.history.patch[0].data).toBeUndefined(); @@ -329,13 +334,13 @@ describe("lib/api/resources/Inboxes: ", () => { }); it("fails with error", async () => { - const inboxId = 1; + const sandboxId = 1; const expectedErrorMessage = "Request failed with status code 404"; expect.assertions(2); try { - await inboxesAPI.enableEmailAddress(inboxId); + await sandboxesAPI.enableEmailAddress(sandboxId); } catch (error) { expect(error).toBeInstanceOf(MailtrapError); @@ -348,12 +353,12 @@ describe("lib/api/resources/Inboxes: ", () => { describe("resetEmailAddress(): ", () => { it("succesfully resets email address.", async () => { - const inboxId = 1; - const endpoint = `${GENERAL_ENDPOINT}/api/accounts/${accountId}/inboxes/${inboxId}/reset_email_username`; + const sandboxId = 1; + const endpoint = `${GENERAL_ENDPOINT}/api/accounts/${accountId}/inboxes/${sandboxId}/reset_email_username`; mock.onPatch(endpoint).reply(200, responseData); - const result = await inboxesAPI.resetEmailAddress(inboxId); + const result = await sandboxesAPI.resetEmailAddress(sandboxId); expect(mock.history.patch[0].url).toEqual(endpoint); expect(mock.history.patch[0].data).toBeUndefined(); @@ -361,13 +366,13 @@ describe("lib/api/resources/Inboxes: ", () => { }); it("fails with error", async () => { - const inboxId = 1; + const sandboxId = 1; const expectedErrorMessage = "Request failed with status code 404"; expect.assertions(2); try { - await inboxesAPI.resetEmailAddress(inboxId); + await sandboxesAPI.resetEmailAddress(sandboxId); } catch (error) { expect(error).toBeInstanceOf(MailtrapError); @@ -379,14 +384,14 @@ describe("lib/api/resources/Inboxes: ", () => { }); describe("getList(): ", () => { - it("succesfully gets inbox list.", async () => { + it("succesfully gets sandbox list.", async () => { const endpoint = `${GENERAL_ENDPOINT}/api/accounts/${accountId}/inboxes`; const expectedResponseData = [responseData]; mock.onGet(endpoint).reply(200, expectedResponseData); - const result = await inboxesAPI.getList(); + const result = await sandboxesAPI.getList(); expect(mock.history.get[0].url).toEqual(endpoint); expect(result).toEqual(expectedResponseData); @@ -398,7 +403,7 @@ describe("lib/api/resources/Inboxes: ", () => { expect.assertions(2); try { - await inboxesAPI.getList(); + await sandboxesAPI.getList(); } catch (error) { expect(error).toBeInstanceOf(MailtrapError); @@ -408,4 +413,59 @@ describe("lib/api/resources/Inboxes: ", () => { } }); }); + + describe("class InboxesApi() (deprecated): ", () => { + const inboxesAPI = new InboxesApi(axios, accountId); + const sandboxId = 1; + const sandboxURL = `${GENERAL_ENDPOINT}/api/accounts/${accountId}/inboxes/${sandboxId}`; + + it("keeps the SandboxesApi methods.", () => { + expect(inboxesAPI).toBeInstanceOf(Sandboxes); + }); + + it("getInboxAttributes() delegates to getSandboxAttributes() and warns.", async () => { + mock.onGet(sandboxURL).reply(200, responseData); + + const result: Inbox = await inboxesAPI.getInboxAttributes(sandboxId); + + expect(mock.history.get[0].url).toEqual(sandboxURL); + expect(result).toEqual(responseData); + expect(warnDeprecated).toHaveBeenCalledWith( + "client.testing.inboxes.getInboxAttributes", + "client.sandbox.sandboxes.getSandboxAttributes" + ); + }); + + it("updateInbox() delegates to updateSandbox() and warns.", async () => { + mock.onPatch(sandboxURL).reply(200, responseData); + + const result = await inboxesAPI.updateInbox(sandboxId, { + name: "mock-sandboxName", + emailUsername: "mock", + }); + + expect(mock.history.patch[0].data).toEqual( + JSON.stringify({ + inbox: { name: "mock-sandboxName", email_username: "mock" }, + }) + ); + expect(result).toEqual(responseData); + expect(warnDeprecated).toHaveBeenCalledWith( + "client.testing.inboxes.updateInbox", + "client.sandbox.sandboxes.updateSandbox" + ); + }); + + it("cleanInbox() delegates to cleanSandbox() and warns.", async () => { + mock.onPatch(`${sandboxURL}/clean`).reply(200, responseData); + + const result = await inboxesAPI.cleanInbox(sandboxId); + + expect(result).toEqual(responseData); + expect(warnDeprecated).toHaveBeenCalledWith( + "client.testing.inboxes.cleanInbox", + "client.sandbox.sandboxes.cleanSandbox" + ); + }); + }); }); diff --git a/src/__tests__/lib/deprecation.test.ts b/src/__tests__/lib/deprecation.test.ts new file mode 100644 index 00000000..c181864f --- /dev/null +++ b/src/__tests__/lib/deprecation.test.ts @@ -0,0 +1,35 @@ +import warnDeprecated from "../../lib/deprecation"; + +describe("lib/deprecation: ", () => { + let emitWarning: jest.SpyInstance; + + beforeEach(() => { + emitWarning = jest + .spyOn(process, "emitWarning") + .mockImplementation(() => {}); + }); + + afterEach(() => { + emitWarning.mockRestore(); + }); + + it("emits a DeprecationWarning naming the replacement.", () => { + warnDeprecated("client.oldName", "client.newName"); + + expect(emitWarning).toHaveBeenCalledWith( + "client.oldName is deprecated and will be removed in a future major release; use client.newName instead.", + { type: "DeprecationWarning", code: "MAILTRAP_DEPRECATED_NAME" } + ); + }); + + it("warns once per old name.", () => { + warnDeprecated("client.firstName", "client.newName"); + warnDeprecated("client.firstName", "client.newName"); + warnDeprecated("client.secondName", "client.newName"); + + expect(emitWarning.mock.calls.map(([message]) => message)).toEqual([ + "client.firstName is deprecated and will be removed in a future major release; use client.newName instead.", + "client.secondName is deprecated and will be removed in a future major release; use client.newName instead.", + ]); + }); +}); diff --git a/src/__tests__/lib/mailtrap-client.test.ts b/src/__tests__/lib/mailtrap-client.test.ts index c3de9f76..c071f128 100644 --- a/src/__tests__/lib/mailtrap-client.test.ts +++ b/src/__tests__/lib/mailtrap-client.test.ts @@ -8,6 +8,7 @@ import MailtrapError from "../../lib/MailtrapError"; import CONFIG from "../../config"; import GeneralAPI from "../../lib/api/General"; +import SandboxAPI from "../../lib/api/Sandbox"; import TestingAPI from "../../lib/api/Testing"; import ContactLists from "../../lib/api/ContactLists"; import Contacts from "../../lib/api/Contacts"; @@ -15,16 +16,24 @@ import ContactExportsBaseAPI from "../../lib/api/ContactExports"; import TemplatesBaseAPI from "../../lib/api/Templates"; import EmailTemplatesBaseAPI from "../../lib/api/EmailTemplates"; import SuppressionsBaseAPI from "../../lib/api/Suppressions"; +import DomainsBaseAPI from "../../lib/api/Domains"; import SendingDomainsBaseAPI from "../../lib/api/SendingDomains"; import EmailLogsBaseAPI from "../../lib/api/EmailLogs"; import ContactEventsBaseAPI from "../../lib/api/ContactEvents"; import MarketingStatsBaseAPI from "../../lib/api/MarketingStats"; +import warnDeprecated from "../../lib/deprecation"; + +jest.mock("../../lib/deprecation"); const { ERRORS, CLIENT_SETTINGS } = CONFIG; const { TESTING_ENDPOINT, BULK_ENDPOINT, SENDING_ENDPOINT, GENERAL_ENDPOINT } = CLIENT_SETTINGS; -const { ACCOUNT_ID_MISSING, BULK_SANDBOX_INCOMPATIBLE, TEST_INBOX_ID_MISSING } = - ERRORS; +const { + ACCOUNT_ID_MISSING, + BULK_SANDBOX_INCOMPATIBLE, + SANDBOX_ID_CONFLICT, + SANDBOX_ID_MISSING, +} = ERRORS; describe("lib/mailtrap-client: ", () => { let mock: AxiosMockAdapter; @@ -65,15 +74,15 @@ describe("lib/mailtrap-client: ", () => { expect(error).toEqual(new MailtrapError(BULK_SANDBOX_INCOMPATIBLE)); } }); - const testInboxId = 100; + const sandboxId = 100; - it("successfully sends testing email.", async () => { - const testingClient = new MailtrapClient({ + it("successfully sends sandbox email.", async () => { + const sandboxClient = new MailtrapClient({ token: "MY_API_TOKEN", sandbox: true, - testInboxId, + sandboxId, }); - const endpoint = `${TESTING_ENDPOINT}/api/send/${testInboxId}`; + const endpoint = `${TESTING_ENDPOINT}/api/send/${sandboxId}`; const expectedResponseData = { success: true, message_ids: ["0c7fd939-02cf-11ed-88c2-0a58a9feac02"], @@ -96,7 +105,7 @@ describe("lib/mailtrap-client: ", () => { html: "
Mock text
", }; - const result = await testingClient.send(emailData); + const result = await sandboxClient.send(emailData); expect(mock.history.post[0].url).toEqual(endpoint); expect(mock.history.post[0].data).toEqual(JSON.stringify(emailData)); @@ -139,17 +148,17 @@ describe("lib/mailtrap-client: ", () => { }); it("handles an API error.", async () => { - const testingClient = new MailtrapClient({ + const sandboxClient = new MailtrapClient({ token: "MY_API_TOKEN", sandbox: true, - testInboxId, + sandboxId, }); const responseData = { success: false, errors: ["mock-error-1", "mock-error-2"], }; - const endpoint = `${TESTING_ENDPOINT}/api/send/${testInboxId}`; + const endpoint = `${TESTING_ENDPOINT}/api/send/${sandboxId}`; mock.onPost(endpoint).reply(400, responseData); @@ -174,7 +183,7 @@ describe("lib/mailtrap-client: ", () => { expect.assertions(3); try { - await testingClient.send(emailData); + await sandboxClient.send(emailData); } catch (error) { expect(mock.history.post[0].url).toEqual(endpoint); expect(mock.history.post[0].data).toEqual(JSON.stringify(emailData)); @@ -186,10 +195,10 @@ describe("lib/mailtrap-client: ", () => { }); it("handles an HTTP transport error.", async () => { - const testingClient = new MailtrapClient({ + const sandboxClient = new MailtrapClient({ token: "MY_API_TOKEN", sandbox: true, - testInboxId, + sandboxId, }); const emailData = { from: { @@ -212,7 +221,7 @@ describe("lib/mailtrap-client: ", () => { expect.assertions(2); try { - await testingClient.send(emailData); + await sandboxClient.send(emailData); } catch (error) { expect(error).toBeInstanceOf(MailtrapError); @@ -339,7 +348,7 @@ describe("lib/mailtrap-client: ", () => { } }); - it("throws MailtrapError(TEST_INBOX_ID_MISSING) when sending in sandbox mode without testInboxId", async () => { + it("throws MailtrapError(SANDBOX_ID_MISSING) when sending in sandbox mode without sandboxId", async () => { const client = new MailtrapClient({ token: "MY_API_TOKEN", sandbox: true, @@ -353,11 +362,11 @@ describe("lib/mailtrap-client: ", () => { subject: "Test", text: "Body", }) - ).rejects.toEqual(new MailtrapError(TEST_INBOX_ID_MISSING)); + ).rejects.toEqual(new MailtrapError(SANDBOX_ID_MISSING)); }); describe("batch sending:", () => { - it("throws MailtrapError(TEST_INBOX_ID_MISSING) when batch sending in sandbox mode without testInboxId", async () => { + it("throws MailtrapError(SANDBOX_ID_MISSING) when batch sending in sandbox mode without sandboxId", async () => { const client = new MailtrapClient({ token: "MY_API_TOKEN", sandbox: true, @@ -378,7 +387,7 @@ describe("lib/mailtrap-client: ", () => { }; await expect(client.batchSend(batchData)).rejects.toEqual( - new MailtrapError(TEST_INBOX_ID_MISSING) + new MailtrapError(SANDBOX_ID_MISSING) ); }); @@ -488,7 +497,7 @@ describe("lib/mailtrap-client: ", () => { const batchClient = new MailtrapClient({ token: "MY_API_TOKEN", sandbox: true, - testInboxId: 100, + sandboxId: 100, }); const endpoint = `${TESTING_ENDPOINT}/api/batch/100`; const expectedBatchResponseData = { @@ -713,7 +722,7 @@ describe("lib/mailtrap-client: ", () => { }); }); - describe("get testing(): ", () => { + describe("get sandbox(): ", () => { it("rejects with Mailtrap error, when `accountId` is missing.", () => { const client = new MailtrapClient({ token: "MY_API_TOKEN", @@ -722,33 +731,22 @@ describe("lib/mailtrap-client: ", () => { expect.assertions(1); try { - client.testing; + client.sandbox; } catch (error) { expect(error).toEqual(new MailtrapError(ACCOUNT_ID_MISSING)); } }); - it("returns testing API object when accountId is provided, even without testInboxId", () => { + it("returns sandbox API object when accountId is provided, even without sandboxId", () => { const client = new MailtrapClient({ token: "MY_API_TOKEN", accountId: 123, - // testInboxId is intentionally omitted - }); - expect.assertions(1); - - const testingClient = client.testing; - expect(testingClient).toBeInstanceOf(TestingAPI); - }); - - it("returns testing API object, console warn is called twice.", () => { - const client = new MailtrapClient({ - token: "MY_API_TOKEN", - accountId: 10, + // sandboxId is intentionally omitted }); expect.assertions(1); - const testingClient = client.testing; - expect(testingClient).toBeInstanceOf(TestingAPI); + const sandboxClient = client.sandbox; + expect(sandboxClient).toBeInstanceOf(SandboxAPI); }); describe("get general(): ", () => { @@ -962,7 +960,7 @@ describe("lib/mailtrap-client: ", () => { }); }); - describe("get sendingDomains(): ", () => { + describe("get domains(): ", () => { it("rejects with Mailtrap error, when `accountId` is missing.", () => { expect.assertions(1); @@ -970,12 +968,12 @@ describe("lib/mailtrap-client: ", () => { token: "test-token", }); - expect(() => client.sendingDomains).toThrow( + expect(() => client.domains).toThrow( "accountId is missing, please provide a valid accountId." ); }); - it("returns sending domains API object when accountId is provided.", () => { + it("returns domains API object when accountId is provided.", () => { expect.assertions(1); const client = new MailtrapClient({ @@ -983,8 +981,8 @@ describe("lib/mailtrap-client: ", () => { accountId: 123, }); - const sendingDomainsClient = client.sendingDomains; - expect(sendingDomainsClient).toBeInstanceOf(SendingDomainsBaseAPI); + const domainsClient = client.domains; + expect(domainsClient).toBeInstanceOf(DomainsBaseAPI); }); }); @@ -1052,4 +1050,136 @@ describe("lib/mailtrap-client: ", () => { }); }); }); + + describe("deprecated names: ", () => { + const accountId = 123; + + beforeAll(() => { + mock = new AxiosMockAdapter(axios); + }); + + afterEach(() => { + mock.reset(); + }); + + describe("testInboxId config option: ", () => { + it("still sets the sandbox to send to and warns.", async () => { + const endpoint = `${TESTING_ENDPOINT}/api/send/100`; + mock.onPost(endpoint).reply(200, { success: true, message_ids: [] }); + + await new MailtrapClient({ + token: "MY_API_TOKEN", + sandbox: true, + testInboxId: 100, + }).send(goodMail); + + expect(mock.history.post[0].url).toEqual(endpoint); + expect(warnDeprecated).toHaveBeenCalledWith("testInboxId", "sandboxId"); + }); + + it("accepts the same value as sandboxId.", () => { + expect( + () => + new MailtrapClient({ + token: "MY_API_TOKEN", + sandboxId: 100, + testInboxId: 100, + }) + ).not.toThrow(); + }); + + it("throws MailtrapError(SANDBOX_ID_CONFLICT) when it differs from sandboxId.", () => { + expect( + () => + new MailtrapClient({ + token: "MY_API_TOKEN", + sandboxId: 100, + testInboxId: 200, + }) + ).toThrow(new MailtrapError(SANDBOX_ID_CONFLICT)); + }); + + it("treats null as not set, like undefined.", async () => { + const endpoint = `${TESTING_ENDPOINT}/api/send/100`; + mock.onPost(endpoint).reply(200, { success: true, message_ids: [] }); + + await new MailtrapClient({ + token: "MY_API_TOKEN", + sandbox: true, + sandboxId: 100, + testInboxId: null as unknown as number, + }).send(goodMail); + + expect(mock.history.post[0].url).toEqual(endpoint); + expect(warnDeprecated).not.toHaveBeenCalled(); + expect( + () => + new MailtrapClient({ + token: "MY_API_TOKEN", + sandboxId: null as unknown as number, + testInboxId: 100, + }) + ).not.toThrow(); + }); + + it("does not warn when only sandboxId is set.", () => { + // eslint-disable-next-line no-new + new MailtrapClient({ token: "MY_API_TOKEN", sandboxId: 100 }); + + expect(warnDeprecated).not.toHaveBeenCalled(); + }); + }); + + describe("get testing(): ", () => { + it("rejects with Mailtrap error, when `accountId` is missing.", () => { + const client = new MailtrapClient({ token: "MY_API_TOKEN" }); + + expect(() => client.testing).toThrow( + new MailtrapError(ACCOUNT_ID_MISSING) + ); + }); + + it("client.testing.inboxes.getList() still resolves and warns.", async () => { + const client = new MailtrapClient({ token: "MY_API_TOKEN", accountId }); + const endpoint = `${GENERAL_ENDPOINT}/api/accounts/${accountId}/inboxes`; + mock.onGet(endpoint).reply(200, [{ id: 1 }]); + + const result = await client.testing.inboxes.getList(); + + expect(client.testing).toBeInstanceOf(TestingAPI); + expect(result).toEqual([{ id: 1 }]); + expect(mock.history.get[0].url).toEqual(endpoint); + expect(warnDeprecated).toHaveBeenCalledWith( + "client.testing", + "client.sandbox" + ); + }); + }); + + describe("get sendingDomains(): ", () => { + it("rejects with Mailtrap error, when `accountId` is missing.", () => { + const client = new MailtrapClient({ token: "MY_API_TOKEN" }); + + expect(() => client.sendingDomains).toThrow( + new MailtrapError(ACCOUNT_ID_MISSING) + ); + }); + + it("client.sendingDomains.getList() still resolves and warns.", async () => { + const client = new MailtrapClient({ token: "MY_API_TOKEN", accountId }); + const endpoint = `${GENERAL_ENDPOINT}/api/accounts/${accountId}/sending_domains`; + mock.onGet(endpoint).reply(200, { data: [] }); + + const result = await client.sendingDomains.getList(); + + expect(client.sendingDomains).toBeInstanceOf(SendingDomainsBaseAPI); + expect(result).toEqual({ data: [] }); + expect(mock.history.get[0].url).toEqual(endpoint); + expect(warnDeprecated).toHaveBeenCalledWith( + "client.sendingDomains", + "client.domains" + ); + }); + }); + }); }); diff --git a/src/config/index.ts b/src/config/index.ts index 6c94d3d5..f593c5ed 100644 --- a/src/config/index.ts +++ b/src/config/index.ts @@ -6,7 +6,9 @@ export default { FROM_REQUIRED: "From is required.", SENDING_FAILED: "Sending failed.", NO_DATA_ERROR: "No Data.", - TEST_INBOX_ID_MISSING: "testInboxId is missing, testing API will not work.", + SANDBOX_ID_MISSING: "sandboxId is missing, sandbox sending will not work.", + SANDBOX_ID_CONFLICT: + "sandboxId and testInboxId are set to different values; set only sandboxId.", ACCOUNT_ID_MISSING: "accountId is missing, please provide a valid accountId.", ORGANIZATION_ID_MISSING: diff --git a/src/lib/MailtrapClient.ts b/src/lib/MailtrapClient.ts index 5a96750a..611a5ec6 100644 --- a/src/lib/MailtrapClient.ts +++ b/src/lib/MailtrapClient.ts @@ -19,6 +19,7 @@ import EmailLogsBaseAPI from "./api/EmailLogs"; import GeneralAPI from "./api/General"; import InboundAPI from "./api/Inbound"; import MarketingStatsBaseAPI from "./api/MarketingStats"; +import DomainsBaseAPI from "./api/Domains"; import SendingDomainsBaseAPI from "./api/SendingDomains"; import StatsBaseAPI from "./api/Stats"; import SuppressionsBaseAPI from "./api/Suppressions"; @@ -26,9 +27,12 @@ import TrackingOptOutsBaseAPI from "./api/TrackingOptOuts"; import OrganizationsBaseAPI from "./api/Organizations"; import TemplatesBaseAPI from "./api/Templates"; import EmailTemplatesBaseAPI from "./api/EmailTemplates"; +import SandboxAPI from "./api/Sandbox"; import TestingAPI from "./api/Testing"; import WebhooksBaseAPI from "./api/Webhooks"; +import warnDeprecated from "./deprecation"; + import CONFIG from "../config"; import { @@ -52,7 +56,8 @@ const { ACCOUNT_ID_MISSING, BULK_SANDBOX_INCOMPATIBLE, ORGANIZATION_ID_MISSING, - TEST_INBOX_ID_MISSING, + SANDBOX_ID_CONFLICT, + SANDBOX_ID_MISSING, } = ERRORS; /** @@ -61,7 +66,7 @@ const { export default class MailtrapClient { private axios: AxiosInstance; - private testInboxId?: number; + private sandboxId?: number; private accountId?: number; @@ -69,13 +74,14 @@ export default class MailtrapClient { private bulk: boolean; - private sandbox: boolean; + private sandboxMode: boolean; /** * Initalizes axios instance with Mailtrap params. */ constructor({ token, + sandboxId, testInboxId, accountId, organizationId, @@ -83,6 +89,15 @@ export default class MailtrapClient { sandbox = false, userAgent, }: MailtrapClientConfig) { + // `!= null` matches the `??` fallback below: `null` means "not set" too. + if (testInboxId != null) { + if (sandboxId != null && sandboxId !== testInboxId) { + throw new MailtrapError(SANDBOX_ID_CONFLICT); + } + + warnDeprecated("testInboxId", "sandboxId"); + } + this.axios = axios.create({ httpAgent: new http.Agent({ keepAlive: true }), httpsAgent: new https.Agent({ keepAlive: true }), @@ -101,11 +116,11 @@ export default class MailtrapClient { handleSendingError ); - this.testInboxId = testInboxId; + this.sandboxId = sandboxId ?? testInboxId; this.accountId = accountId; this.organizationId = organizationId; this.bulk = bulk; - this.sandbox = sandbox; + this.sandboxMode = sandbox; } /** @@ -129,18 +144,27 @@ export default class MailtrapClient { } /** - * Validates that test inbox ID is present, throws MailtrapError if missing. + * Validates that sandbox ID is present, throws MailtrapError if missing. */ - private validateTestInboxIdPresence(): void { - if (this.sandbox && !this.testInboxId) { - throw new MailtrapError(TEST_INBOX_ID_MISSING); + private validateSandboxIdPresence(): void { + if (this.sandboxMode && !this.sandboxId) { + throw new MailtrapError(SANDBOX_ID_MISSING); } } /** - * Getter for Testing API. Warns if some of the required keys are missing. + * Getter for Email Sandbox API: projects, sandboxes, messages and attachments. + */ + get sandbox() { + const accountId = this.validateAccountIdPresence(); + return new SandboxAPI(this.axios, accountId); + } + + /** + * @deprecated Use `client.sandbox` instead. */ get testing() { + warnDeprecated("client.testing", "client.sandbox"); const accountId = this.validateAccountIdPresence(); return new TestingAPI(this.axios, accountId); } @@ -243,9 +267,18 @@ export default class MailtrapClient { } /** - * Getter for Sending Domains API. + * Getter for Domains API. + */ + get domains() { + const accountId = this.validateAccountIdPresence(); + return new DomainsBaseAPI(this.axios, accountId); + } + + /** + * @deprecated Use `client.domains` instead. */ get sendingDomains() { + warnDeprecated("client.sendingDomains", "client.domains"); const accountId = this.validateAccountIdPresence(); return new SendingDomainsBaseAPI(this.axios, accountId); } @@ -310,9 +343,9 @@ export default class MailtrapClient { private determineHost() { let host; - if (this.bulk && this.sandbox) { + if (this.bulk && this.sandboxMode) { throw new MailtrapError(BULK_SANDBOX_INCOMPATIBLE); - } else if (this.sandbox) { + } else if (this.sandboxMode) { host = TESTING_ENDPOINT; } else if (this.bulk) { host = BULK_ENDPOINT; @@ -328,10 +361,10 @@ export default class MailtrapClient { */ public async send(mail: Mail): Promise { const host = this.determineHost(); - this.validateTestInboxIdPresence(); + this.validateSandboxIdPresence(); const url = `${host}/api/send${ - this.sandbox && this.testInboxId ? `/${this.testInboxId}` : "" + this.sandboxMode && this.sandboxId ? `/${this.sandboxId}` : "" }`; const preparedMail = encodeMailBuffers(mail); @@ -349,10 +382,10 @@ export default class MailtrapClient { const { requests, base } = request; const host = this.determineHost(); - this.validateTestInboxIdPresence(); + this.validateSandboxIdPresence(); const sandbox = - this.sandbox && this.testInboxId ? `/${this.testInboxId}` : ""; + this.sandboxMode && this.sandboxId ? `/${this.sandboxId}` : ""; const url = `${host}/api/batch${sandbox}`; diff --git a/src/lib/api/Domains.ts b/src/lib/api/Domains.ts new file mode 100644 index 00000000..ae9e84fd --- /dev/null +++ b/src/lib/api/Domains.ts @@ -0,0 +1,27 @@ +import { AxiosInstance } from "axios"; + +import DomainsApi from "./resources/Domains"; + +export default class DomainsBaseAPI { + public get: DomainsApi["get"]; + + public getList: DomainsApi["getList"]; + + public create: DomainsApi["create"]; + + public update: DomainsApi["update"]; + + public delete: DomainsApi["delete"]; + + public sendSetupInstructions: DomainsApi["sendSetupInstructions"]; + + constructor(client: AxiosInstance, accountId: number) { + const domains = new DomainsApi(client, accountId); + this.get = domains.get.bind(domains); + this.getList = domains.getList.bind(domains); + this.create = domains.create.bind(domains); + this.update = domains.update.bind(domains); + this.delete = domains.delete.bind(domains); + this.sendSetupInstructions = domains.sendSetupInstructions.bind(domains); + } +} diff --git a/src/lib/api/Sandbox.ts b/src/lib/api/Sandbox.ts new file mode 100644 index 00000000..064e0ace --- /dev/null +++ b/src/lib/api/Sandbox.ts @@ -0,0 +1,23 @@ +import { AxiosInstance } from "axios"; + +import ProjectsApi from "./resources/Projects"; +import SandboxesApi from "./resources/Sandboxes"; +import MessagesApi from "./resources/Messages"; +import AttachmentsApi from "./resources/Attachments"; + +export default class SandboxAPI { + public projects: ProjectsApi; + + public sandboxes: SandboxesApi; + + public messages: MessagesApi; + + public attachments: AttachmentsApi; + + constructor(client: AxiosInstance, accountId: number) { + this.projects = new ProjectsApi(client, accountId); + this.sandboxes = new SandboxesApi(client, accountId); + this.messages = new MessagesApi(client, accountId); + this.attachments = new AttachmentsApi(client, accountId); + } +} diff --git a/src/lib/api/SendingDomains.ts b/src/lib/api/SendingDomains.ts index 0810bca3..fa1a3a87 100644 --- a/src/lib/api/SendingDomains.ts +++ b/src/lib/api/SendingDomains.ts @@ -1,31 +1,4 @@ -import { AxiosInstance } from "axios"; +import DomainsBaseAPI from "./Domains"; -import SendingDomainsApi from "./resources/SendingDomains"; - -export default class SendingDomainsBaseAPI { - private client: AxiosInstance; - - public get: SendingDomainsApi["get"]; - - public getList: SendingDomainsApi["getList"]; - - public create: SendingDomainsApi["create"]; - - public update: SendingDomainsApi["update"]; - - public delete: SendingDomainsApi["delete"]; - - public sendSetupInstructions: SendingDomainsApi["sendSetupInstructions"]; - - constructor(client: AxiosInstance, accountId: number) { - this.client = client; - const sendingDomains = new SendingDomainsApi(this.client, accountId); - this.get = sendingDomains.get.bind(sendingDomains); - this.getList = sendingDomains.getList.bind(sendingDomains); - this.create = sendingDomains.create.bind(sendingDomains); - this.update = sendingDomains.update.bind(sendingDomains); - this.delete = sendingDomains.delete.bind(sendingDomains); - this.sendSetupInstructions = - sendingDomains.sendSetupInstructions.bind(sendingDomains); - } -} +/** @deprecated Use `DomainsBaseAPI` (`client.domains`) instead. */ +export default class SendingDomainsBaseAPI extends DomainsBaseAPI {} diff --git a/src/lib/api/Testing.ts b/src/lib/api/Testing.ts index 7569fd24..e31afba9 100644 --- a/src/lib/api/Testing.ts +++ b/src/lib/api/Testing.ts @@ -1,23 +1,22 @@ import { AxiosInstance } from "axios"; -import ProjectsApi from "./resources/Projects"; +import SandboxAPI from "./Sandbox"; import InboxesApi from "./resources/Inboxes"; -import MessagesApi from "./resources/Messages"; -import AttachmentsApi from "./resources/Attachments"; +import warnDeprecated from "../deprecation"; -export default class TestingAPI { - public projects: ProjectsApi; +/** @deprecated Use `SandboxAPI` (`client.sandbox`) instead. */ +export default class TestingAPI extends SandboxAPI { + private inboxesApi: InboxesApi; - public inboxes: InboxesApi; - - public messages: MessagesApi; + constructor(client: AxiosInstance, accountId: number) { + super(client, accountId); + this.inboxesApi = new InboxesApi(client, accountId); + } - public attachments: AttachmentsApi; + /** @deprecated Use `client.sandbox.sandboxes` instead. */ + get inboxes() { + warnDeprecated("client.testing.inboxes", "client.sandbox.sandboxes"); - constructor(client: AxiosInstance, accountId: number) { - this.projects = new ProjectsApi(client, accountId); - this.inboxes = new InboxesApi(client, accountId); - this.messages = new MessagesApi(client, accountId); - this.attachments = new AttachmentsApi(client, accountId); + return this.inboxesApi; } } diff --git a/src/lib/api/resources/Attachments.ts b/src/lib/api/resources/Attachments.ts index f6622bb4..7a102d62 100644 --- a/src/lib/api/resources/Attachments.ts +++ b/src/lib/api/resources/Attachments.ts @@ -10,27 +10,27 @@ const { GENERAL_ENDPOINT } = CLIENT_SETTINGS; export default class AttachmentsApi { private client: AxiosInstance; - private inboxesURL: string; + private sandboxesURL: string; constructor(client: AxiosInstance, accountId: number) { this.client = client; - this.inboxesURL = `${GENERAL_ENDPOINT}/api/accounts/${accountId}/inboxes`; + this.sandboxesURL = `${GENERAL_ENDPOINT}/api/accounts/${accountId}/inboxes`; } /** - * Get message attachments by `inboxId` and `messageId`. + * Get message attachments by `sandboxId` and `messageId`. */ - public async getList(inboxId: number, messageId: number) { - const url = `${this.inboxesURL}/${inboxId}/messages/${messageId}/attachments`; + public async getList(sandboxId: number, messageId: number) { + const url = `${this.sandboxesURL}/${sandboxId}/messages/${messageId}/attachments`; return this.client.get(url); } /** - * Get message attachments by `inboxId`.`messageId` and `attachmentId`. + * Get message attachments by `sandboxId`.`messageId` and `attachmentId`. */ - public async get(inboxId: number, messageId: number, attachmentId: number) { - const url = `${this.inboxesURL}/${inboxId}/messages/${messageId}/attachments/${attachmentId}`; + public async get(sandboxId: number, messageId: number, attachmentId: number) { + const url = `${this.sandboxesURL}/${sandboxId}/messages/${messageId}/attachments/${attachmentId}`; return this.client.get(url); } diff --git a/src/lib/api/resources/CompanyInfo.ts b/src/lib/api/resources/CompanyInfo.ts index 03468a0b..b7f6d795 100644 --- a/src/lib/api/resources/CompanyInfo.ts +++ b/src/lib/api/resources/CompanyInfo.ts @@ -21,9 +21,9 @@ export default class CompanyInfoApi { } /** - * Get the company info associated with a sending domain. - * @param domainId Sending domain ID - * @returns Returns the company info of the sending domain + * Get the company info associated with a domain. + * @param domainId Domain ID + * @returns Returns the company info of the domain */ public async get(domainId: number) { const url = this.companyInfoURL(domainId); @@ -32,9 +32,9 @@ export default class CompanyInfoApi { } /** - * Create the company info for a sending domain. Company info is required for + * Create the company info for a domain. Company info is required for * domain compliance verification. - * @param domainId Sending domain ID + * @param domainId Domain ID * @param params Company info attributes * @returns Returns the created company info */ @@ -49,9 +49,9 @@ export default class CompanyInfoApi { } /** - * Update the company info for a sending domain. Only the fields provided are + * Update the company info for a domain. Only the fields provided are * updated. - * @param domainId Sending domain ID + * @param domainId Domain ID * @param params Company info attributes to update * @returns Returns the updated company info */ diff --git a/src/lib/api/resources/Domains.ts b/src/lib/api/resources/Domains.ts new file mode 100644 index 00000000..b0447c80 --- /dev/null +++ b/src/lib/api/resources/Domains.ts @@ -0,0 +1,89 @@ +import { AxiosInstance } from "axios"; + +import CONFIG from "../../../config"; +import { + CreateDomainParams, + Domain, + DomainsResponse, + UpdateDomainParams, +} from "../../../types/api/domains"; + +const { CLIENT_SETTINGS } = CONFIG; +const { GENERAL_ENDPOINT } = CLIENT_SETTINGS; + +export default class DomainsApi { + private client: AxiosInstance; + + private domainsURL: string; + + constructor(client: AxiosInstance, accountId: number) { + this.client = client; + this.domainsURL = `${GENERAL_ENDPOINT}/api/accounts/${accountId}/sending_domains`; + } + + /** + * Get a list of domains. + * @returns Returns the list of domains for the account. + */ + public async getList() { + const url = this.domainsURL; + + return this.client.get(url); + } + + /** + * Get a single domain by ID. + * @param id Domain ID + * @returns Returns a single domain + */ + public async get(id: number) { + const url = `${this.domainsURL}/${id}`; + + return this.client.get(url); + } + + /** + * Create a new domain. + */ + public async create(params: CreateDomainParams) { + const url = this.domainsURL; + const data = { sending_domain: params }; + + return this.client.post(url, data); + } + + /** + * Update configuration settings for a domain. + * @param id Domain ID + * @param params Settings to update + * @returns Returns the updated domain + */ + public async update(id: number, params: UpdateDomainParams) { + const url = `${this.domainsURL}/${id}`; + const data = { sending_domain: params }; + + return this.client.patch(url, data); + } + + /** + * Delete a domain by ID. + * @param id Domain ID + */ + public async delete(id: number) { + const url = `${this.domainsURL}/${id}`; + + return this.client.delete(url); + } + + /** + * Send setup instructions for a domain to an email address. + * @param id Domain ID + * @param email Email address to send setup instructions to + * @returns Returns a success message + */ + public async sendSetupInstructions(id: number, email: string) { + const url = `${this.domainsURL}/${id}/send_setup_instructions`; + + return this.client.post(url, { email }); + } +} diff --git a/src/lib/api/resources/EmailCampaigns.ts b/src/lib/api/resources/EmailCampaigns.ts index d2d1b7a1..ed2bcb58 100644 --- a/src/lib/api/resources/EmailCampaigns.ts +++ b/src/lib/api/resources/EmailCampaigns.ts @@ -51,7 +51,7 @@ export default class EmailCampaignsApi { /** * Create a new email campaign in the `draft` state. The campaign must - * reference an existing sending domain via `domain_id` and include + * reference an existing domain via `domain_id` and include * a template `subject` within `template_attributes`. */ public async create(params: CreateEmailCampaignParams) { diff --git a/src/lib/api/resources/Inboxes.ts b/src/lib/api/resources/Inboxes.ts index 4c53fda4..63f5886a 100644 --- a/src/lib/api/resources/Inboxes.ts +++ b/src/lib/api/resources/Inboxes.ts @@ -1,117 +1,37 @@ -import { AxiosInstance } from "axios"; +import SandboxesApi from "./Sandboxes"; +import warnDeprecated from "../../deprecation"; -import CONFIG from "../../../config"; +import { UpdateSandboxParams } from "../../../types/api/sandboxes"; -import { Inbox, UpdateInboxParams } from "../../../types/api/inboxes"; - -const { CLIENT_SETTINGS } = CONFIG; -const { GENERAL_ENDPOINT } = CLIENT_SETTINGS; - -export default class InboxesApi { - private client: AxiosInstance; - - private accountId: number; - - private inboxesURL: string; - - constructor(client: AxiosInstance, accountId: number) { - this.client = client; - this.accountId = accountId; - this.inboxesURL = `${GENERAL_ENDPOINT}/api/accounts/${this.accountId}/inboxes`; - } - - /** - * Creates an inbox in a project. - */ - public async create(projectId: number, inboxName: string) { - const url = `${GENERAL_ENDPOINT}/api/accounts/${this.accountId}/projects/${projectId}/inboxes`; - const data = { inbox: { name: inboxName } }; - - return this.client.post(url, data); - } - - /** - * Gets inbox attributes by inbox id. - */ +/** @deprecated Use `SandboxesApi` (`client.sandbox.sandboxes`) instead. */ +export default class InboxesApi extends SandboxesApi { + /** @deprecated Use `getSandboxAttributes` instead. */ public async getInboxAttributes(inboxId: number) { - const url = `${this.inboxesURL}/${inboxId}`; + warnDeprecated( + "client.testing.inboxes.getInboxAttributes", + "client.sandbox.sandboxes.getSandboxAttributes" + ); - return this.client.get(url); + return this.getSandboxAttributes(inboxId); } - /** - * Deletes an inbox with all its emails. - */ - public async delete(inboxId: number) { - const url = `${this.inboxesURL}/${inboxId}`; + /** @deprecated Use `updateSandbox` instead. */ + public async updateInbox(inboxId: number, params: UpdateSandboxParams) { + warnDeprecated( + "client.testing.inboxes.updateInbox", + "client.sandbox.sandboxes.updateSandbox" + ); - return this.client.delete(url); + return this.updateSandbox(inboxId, params); } - /** - * Updates inbox name, inbox email username. - */ - public async updateInbox(inboxId: number, params: UpdateInboxParams) { - const url = `${this.inboxesURL}/${inboxId}`; - const data = { - inbox: { - name: params.name, - email_username: params.emailUsername, - }, - }; - - return this.client.patch(url, data); - } - - /** - * Deletes all messages (emails) from inbox. - */ + /** @deprecated Use `cleanSandbox` instead. */ public async cleanInbox(inboxId: number) { - const url = `${this.inboxesURL}/${inboxId}/clean`; - - return this.client.patch(url); - } - - /** - * Marks all messages in the inbox as read. - */ - public async markAsRead(inboxId: number) { - const url = `${this.inboxesURL}/${inboxId}/all_read`; - - return this.client.patch(url); - } - - /** - * Resets SMTP credentials of the inbox. - */ - public async resetCredentials(inboxId: number) { - const url = `${this.inboxesURL}/${inboxId}/reset_credentials`; - - return this.client.patch(url); - } - - /** - * Turns the email address of the inbox on/off. - */ - public async enableEmailAddress(inboxId: number) { - const url = `${this.inboxesURL}/${inboxId}/toggle_email_username`; - - return this.client.patch(url); - } - - /** - * Resets username of email address per inbox. - */ - public async resetEmailAddress(inboxId: number) { - const url = `${this.inboxesURL}/${inboxId}/reset_email_username`; - - return this.client.patch(url); - } + warnDeprecated( + "client.testing.inboxes.cleanInbox", + "client.sandbox.sandboxes.cleanSandbox" + ); - /** - * Gets a list of inboxes. - */ - public async getList() { - return this.client.get(this.inboxesURL); + return this.cleanSandbox(inboxId); } } diff --git a/src/lib/api/resources/Messages.ts b/src/lib/api/resources/Messages.ts index cb8186eb..d87f0df1 100644 --- a/src/lib/api/resources/Messages.ts +++ b/src/lib/api/resources/Messages.ts @@ -27,8 +27,8 @@ export default class MessagesApi { /** * Gets email message by given `messageId`. */ - public async showEmailMessage(inboxId: number, messageId: number) { - const url = `${this.messagesURL}/${inboxId}/messages/${messageId}`; + public async showEmailMessage(sandboxId: number, messageId: number) { + const url = `${this.messagesURL}/${sandboxId}/messages/${messageId}`; return this.client.get(url); } @@ -37,30 +37,30 @@ export default class MessagesApi { * Updates message attributes (right now only the is_read attribute is available for modification). */ public async updateMessage( - inboxId: number, + sandboxId: number, messageId: number, params: MessageUpdateParams ) { - const url = `${this.messagesURL}/${inboxId}/messages/${messageId}`; + const url = `${this.messagesURL}/${sandboxId}/messages/${messageId}`; const data = { message: { is_read: params.isRead } }; return this.client.patch(url, data); } /** - * Deletes message from inbox. + * Deletes message from sandbox. */ - public async deleteMessage(inboxId: number, messageId: number) { - const url = `${this.messagesURL}/${inboxId}/messages/${messageId}`; + public async deleteMessage(sandboxId: number, messageId: number) { + const url = `${this.messagesURL}/${sandboxId}/messages/${messageId}`; return this.client.delete(url); } /** - * Gets all messages in inboxes. + * Gets all messages in a sandbox. */ - public async get(inboxId: number, options?: MessageListOptions) { - const url = `${this.messagesURL}/${inboxId}/messages`; + public async get(sandboxId: number, options?: MessageListOptions) { + const url = `${this.messagesURL}/${sandboxId}/messages`; const params = { ...(options?.last_id !== undefined && { last_id: options.last_id }), @@ -75,11 +75,11 @@ export default class MessagesApi { * Forwards message to an email address. The email address must be confirmed by the recipient in advance. */ public async forward( - inboxId: number, + sandboxId: number, messageId: number, emailToForward: string ) { - const url = `${this.messagesURL}/${inboxId}/messages/${messageId}/forward`; + const url = `${this.messagesURL}/${sandboxId}/messages/${messageId}/forward`; const data = { email: emailToForward }; return this.client.post(url, data); @@ -88,8 +88,8 @@ export default class MessagesApi { /** * Gets a brief spam report by given `messageId`. */ - public async getSpamScore(inboxId: number, messageId: number) { - const url = `${this.messagesURL}/${inboxId}/messages/${messageId}/spam_report`; + public async getSpamScore(sandboxId: number, messageId: number) { + const url = `${this.messagesURL}/${sandboxId}/messages/${messageId}/spam_report`; return this.client.get(url); } @@ -97,8 +97,8 @@ export default class MessagesApi { /** * Gets a brief HTML report by message ID. */ - public async getHtmlAnalysis(inboxId: number, messageId: number) { - const url = `${this.messagesURL}/${inboxId}/messages/${messageId}/analyze`; + public async getHtmlAnalysis(sandboxId: number, messageId: number) { + const url = `${this.messagesURL}/${sandboxId}/messages/${messageId}/analyze`; return this.client.get(url); } @@ -106,8 +106,8 @@ export default class MessagesApi { /** * Gets text email body, if it exists. */ - public async getTextMessage(inboxId: number, messageId: number) { - const url = `${this.messagesURL}/${inboxId}/messages/${messageId}/body.txt`; + public async getTextMessage(sandboxId: number, messageId: number) { + const url = `${this.messagesURL}/${sandboxId}/messages/${messageId}/body.txt`; return this.client.get(url); } @@ -115,8 +115,8 @@ export default class MessagesApi { /** * Gets raw email body. */ - public async getRawMessage(inboxId: number, messageId: number) { - const url = `${this.messagesURL}/${inboxId}/messages/${messageId}/body.raw`; + public async getRawMessage(sandboxId: number, messageId: number) { + const url = `${this.messagesURL}/${sandboxId}/messages/${messageId}/body.raw`; return this.client.get(url); } @@ -124,8 +124,8 @@ export default class MessagesApi { /** * Gets HTML source of email. */ - public async getMessageHtmlSource(inboxId: number, messageId: number) { - const url = `${this.messagesURL}/${inboxId}/messages/${messageId}/body.htmlsource`; + public async getMessageHtmlSource(sandboxId: number, messageId: number) { + const url = `${this.messagesURL}/${sandboxId}/messages/${messageId}/body.htmlsource`; return this.client.get(url); } @@ -133,8 +133,8 @@ export default class MessagesApi { /** * Gets formatted HTML email body. Not applicable for plain text emails. */ - public async getHtmlMessage(inboxId: number, messageId: number) { - const url = `${this.messagesURL}/${inboxId}/messages/${messageId}/body.html`; + public async getHtmlMessage(sandboxId: number, messageId: number) { + const url = `${this.messagesURL}/${sandboxId}/messages/${messageId}/body.html`; return this.client.get(url); } @@ -142,8 +142,8 @@ export default class MessagesApi { /** * Gets email message in .eml format. */ - public async getMessageAsEml(inboxId: number, messageId: number) { - const url = `${this.messagesURL}/${inboxId}/messages/${messageId}/body.eml`; + public async getMessageAsEml(sandboxId: number, messageId: number) { + const url = `${this.messagesURL}/${sandboxId}/messages/${messageId}/body.eml`; return this.client.get(url); } @@ -151,8 +151,8 @@ export default class MessagesApi { /** * Gets mail headers of a message. */ - public async getMailHeaders(inboxId: number, messageId: number) { - const url = `${this.messagesURL}/${inboxId}/messages/${messageId}/mail_headers`; + public async getMailHeaders(sandboxId: number, messageId: number) { + const url = `${this.messagesURL}/${sandboxId}/messages/${messageId}/mail_headers`; return this.client.get(url); } diff --git a/src/lib/api/resources/Permissions.ts b/src/lib/api/resources/Permissions.ts index 4829da93..87377700 100644 --- a/src/lib/api/resources/Permissions.ts +++ b/src/lib/api/resources/Permissions.ts @@ -47,7 +47,7 @@ export default class PermissionsApi { } /** - * Get all resources in your account (Inboxes, Projects, Domains, Billing and Account itself) to which the token has admin access. + * Get all resources in your account (Sandboxes, Projects, Domains, Billing and Account itself) to which the token has admin access. * @returns Returns the resources nested according to their hierarchy. */ public async getResources() { diff --git a/src/lib/api/resources/Projects.ts b/src/lib/api/resources/Projects.ts index e34952ee..c5aad927 100644 --- a/src/lib/api/resources/Projects.ts +++ b/src/lib/api/resources/Projects.ts @@ -27,14 +27,14 @@ export default class ProjectsApi { } /** - * Lists projects and their inboxes to which the API token has access. + * Lists projects and their sandboxes to which the API token has access. */ public async getList() { return this.client.get(this.projectsURL); } /** - * Gets the project and it's inboxes. + * Gets the project and its sandboxes. */ public async getById(projectId: number) { const url = `${this.projectsURL}/${projectId}`; diff --git a/src/lib/api/resources/Sandboxes.ts b/src/lib/api/resources/Sandboxes.ts new file mode 100644 index 00000000..3c888dc4 --- /dev/null +++ b/src/lib/api/resources/Sandboxes.ts @@ -0,0 +1,117 @@ +import { AxiosInstance } from "axios"; + +import CONFIG from "../../../config"; + +import { Sandbox, UpdateSandboxParams } from "../../../types/api/sandboxes"; + +const { CLIENT_SETTINGS } = CONFIG; +const { GENERAL_ENDPOINT } = CLIENT_SETTINGS; + +export default class SandboxesApi { + private client: AxiosInstance; + + private accountId: number; + + private sandboxesURL: string; + + constructor(client: AxiosInstance, accountId: number) { + this.client = client; + this.accountId = accountId; + this.sandboxesURL = `${GENERAL_ENDPOINT}/api/accounts/${this.accountId}/inboxes`; + } + + /** + * Creates a sandbox in a project. + */ + public async create(projectId: number, sandboxName: string) { + const url = `${GENERAL_ENDPOINT}/api/accounts/${this.accountId}/projects/${projectId}/inboxes`; + const data = { inbox: { name: sandboxName } }; + + return this.client.post(url, data); + } + + /** + * Gets sandbox attributes by sandbox id. + */ + public async getSandboxAttributes(sandboxId: number) { + const url = `${this.sandboxesURL}/${sandboxId}`; + + return this.client.get(url); + } + + /** + * Deletes a sandbox with all its emails. + */ + public async delete(sandboxId: number) { + const url = `${this.sandboxesURL}/${sandboxId}`; + + return this.client.delete(url); + } + + /** + * Updates sandbox name, sandbox email username. + */ + public async updateSandbox(sandboxId: number, params: UpdateSandboxParams) { + const url = `${this.sandboxesURL}/${sandboxId}`; + const data = { + inbox: { + name: params.name, + email_username: params.emailUsername, + }, + }; + + return this.client.patch(url, data); + } + + /** + * Deletes all messages (emails) from sandbox. + */ + public async cleanSandbox(sandboxId: number) { + const url = `${this.sandboxesURL}/${sandboxId}/clean`; + + return this.client.patch(url); + } + + /** + * Marks all messages in the sandbox as read. + */ + public async markAsRead(sandboxId: number) { + const url = `${this.sandboxesURL}/${sandboxId}/all_read`; + + return this.client.patch(url); + } + + /** + * Resets SMTP credentials of the sandbox. + */ + public async resetCredentials(sandboxId: number) { + const url = `${this.sandboxesURL}/${sandboxId}/reset_credentials`; + + return this.client.patch(url); + } + + /** + * Turns the email address of the sandbox on/off. + */ + public async enableEmailAddress(sandboxId: number) { + const url = `${this.sandboxesURL}/${sandboxId}/toggle_email_username`; + + return this.client.patch(url); + } + + /** + * Resets username of email address per sandbox. + */ + public async resetEmailAddress(sandboxId: number) { + const url = `${this.sandboxesURL}/${sandboxId}/reset_email_username`; + + return this.client.patch(url); + } + + /** + * Gets a list of sandboxes. + */ + public async getList() { + return this.client.get(this.sandboxesURL); + } +} diff --git a/src/lib/api/resources/SendingDomains.ts b/src/lib/api/resources/SendingDomains.ts index 5c39b6e2..0a05b6ed 100644 --- a/src/lib/api/resources/SendingDomains.ts +++ b/src/lib/api/resources/SendingDomains.ts @@ -1,89 +1,4 @@ -import { AxiosInstance } from "axios"; +import DomainsApi from "./Domains"; -import CONFIG from "../../../config"; -import { - CreateSendingDomainParams, - SendingDomain, - SendingDomainsResponse, - UpdateSendingDomainParams, -} from "../../../types/api/sending-domains"; - -const { CLIENT_SETTINGS } = CONFIG; -const { GENERAL_ENDPOINT } = CLIENT_SETTINGS; - -export default class SendingDomainsApi { - private client: AxiosInstance; - - private sendingDomainsURL: string; - - constructor(client: AxiosInstance, accountId: number) { - this.client = client; - this.sendingDomainsURL = `${GENERAL_ENDPOINT}/api/accounts/${accountId}/sending_domains`; - } - - /** - * Get a list of sending domains. - * @returns Returns the list of sending domains for the account. - */ - public async getList() { - const url = this.sendingDomainsURL; - - return this.client.get(url); - } - - /** - * Get a single sending domain by ID. - * @param id Sending domain ID - * @returns Returns a single sending domain - */ - public async get(id: number) { - const url = `${this.sendingDomainsURL}/${id}`; - - return this.client.get(url); - } - - /** - * Create a new sending domain. - */ - public async create(params: CreateSendingDomainParams) { - const url = this.sendingDomainsURL; - const data = { sending_domain: params }; - - return this.client.post(url, data); - } - - /** - * Update configuration settings for a sending domain. - * @param id Sending domain ID - * @param params Settings to update - * @returns Returns the updated sending domain - */ - public async update(id: number, params: UpdateSendingDomainParams) { - const url = `${this.sendingDomainsURL}/${id}`; - const data = { sending_domain: params }; - - return this.client.patch(url, data); - } - - /** - * Delete a sending domain by ID. - * @param id Sending domain ID - */ - public async delete(id: number) { - const url = `${this.sendingDomainsURL}/${id}`; - - return this.client.delete(url); - } - - /** - * Send setup instructions for a sending domain to an email address. - * @param id Sending domain ID - * @param email Email address to send setup instructions to - * @returns Returns a success message - */ - public async sendSetupInstructions(id: number, email: string) { - const url = `${this.sendingDomainsURL}/${id}/send_setup_instructions`; - - return this.client.post(url, { email }); - } -} +/** @deprecated Use `DomainsApi` instead. */ +export default class SendingDomainsApi extends DomainsApi {} diff --git a/src/lib/api/resources/TrackingOptOuts.ts b/src/lib/api/resources/TrackingOptOuts.ts index 93721b60..83be0e1d 100644 --- a/src/lib/api/resources/TrackingOptOuts.ts +++ b/src/lib/api/resources/TrackingOptOuts.ts @@ -42,7 +42,7 @@ export default class TrackingOptOutsApi { } /** - * Add an email address to the tracking opt-out list for a sending domain. + * Add an email address to the tracking opt-out list for a domain. */ public async create(params: CreateTrackingOptOutParams) { return this.client.post< diff --git a/src/lib/deprecation.ts b/src/lib/deprecation.ts new file mode 100644 index 00000000..e02c08d5 --- /dev/null +++ b/src/lib/deprecation.ts @@ -0,0 +1,15 @@ +const warned = new Set(); + +/** + * Emits a `DeprecationWarning` for a renamed API, once per process per old name, + * so a deprecated call inside a loop warns only the first time. + */ +export default function warnDeprecated(oldName: string, newName: string) { + if (warned.has(oldName)) return; + + warned.add(oldName); + process.emitWarning( + `${oldName} is deprecated and will be removed in a future major release; use ${newName} instead.`, + { type: "DeprecationWarning", code: "MAILTRAP_DEPRECATED_NAME" } + ); +} diff --git a/src/types/api/domains.ts b/src/types/api/domains.ts new file mode 100644 index 00000000..3b4b6368 --- /dev/null +++ b/src/types/api/domains.ts @@ -0,0 +1,51 @@ +export interface DnsRecord { + key: string; + domain: string; + type: string; + value: string; + status: string; + name: string; +} + +export interface DomainPermissions { + can_read: boolean; + can_update: boolean; + can_destroy: boolean; +} + +export interface Domain { + id: number; + domain_name: string; + demo: boolean; + compliance_status: string; + dns_verified: boolean; + dns_verified_at: string | null; + dns_records: DnsRecord[]; + open_tracking_enabled: boolean; + click_tracking_enabled: boolean; + tracking_opt_out_enabled: boolean; + auto_unsubscribe_link_enabled: boolean; + custom_domain_tracking_enabled: boolean; + health_alerts_enabled: boolean; + critical_alerts_enabled: boolean; + alert_recipient_email: string | null; + inbound_enabled: boolean; + inbound_verified: boolean; + permissions: DomainPermissions; +} + +export interface CreateDomainParams { + domain_name: string; +} + +export interface DomainsResponse { + data: Domain[]; +} + +export interface UpdateDomainParams { + open_tracking_enabled?: boolean; + click_tracking_enabled?: boolean; + tracking_opt_out_enabled?: boolean; + auto_unsubscribe_link_enabled?: boolean; + inbound_enabled?: boolean; +} diff --git a/src/types/api/email-campaigns.ts b/src/types/api/email-campaigns.ts index e62671e0..52b6ed08 100644 --- a/src/types/api/email-campaigns.ts +++ b/src/types/api/email-campaigns.ts @@ -91,7 +91,7 @@ export type CampaignTemplate = { export type EmailCampaign = { id: number; - /** ID of the sending domain, as returned by the Sending Domains endpoints. */ + /** ID of the domain, as returned by `client.domains`. */ domain_id: number; domain_name: string; name: string; @@ -125,7 +125,7 @@ export type ListEmailCampaignsParams = { export type CreateEmailCampaignParams = { name: string; - /** ID of the verified sending domain, as returned by the Sending Domains endpoints. */ + /** ID of the verified domain, as returned by `client.domains`. */ domain_id: number; from_local_part: string; from_display_name?: string; @@ -139,7 +139,7 @@ export type CreateEmailCampaignParams = { export type UpdateEmailCampaignParams = { name?: string; - /** ID of the verified sending domain, as returned by the Sending Domains endpoints. */ + /** ID of the verified domain, as returned by `client.domains`. */ domain_id?: number; from_local_part?: string; from_display_name?: string; diff --git a/src/types/api/inboxes.ts b/src/types/api/inboxes.ts index f6a3378c..dc22168f 100644 --- a/src/types/api/inboxes.ts +++ b/src/types/api/inboxes.ts @@ -1,37 +1,7 @@ -export type UpdateInboxParams = { - name: string; - emailUsername: string; -}; +import { Sandbox, UpdateSandboxParams } from "./sandboxes"; -type Permissions = { - can_read: boolean; - can_update: boolean; - can_destroy: boolean; - can_leave: boolean; -}; +/** @deprecated Use `Sandbox` instead. */ +export type Inbox = Sandbox; -export type Inbox = { - id: number; - name: string; - username: string; - password: string; - max_size: number; - status: string; - email_username: string; - email_username_enabled: boolean; - sent_messages_count: number; - forwarded_messages_count: number; - used: boolean; - forward_from_email_address: string; - project_id: number; - domain: string; - pop3_domain: string; - email_domain: string; - smtp_ports: number[]; - pop3_ports: number[]; - emails_count: number; - emails_unread_count: number; - last_message_sent_at: string | null; - max_message_size: number; - permissions: Permissions; -}; +/** @deprecated Use `UpdateSandboxParams` instead. */ +export type UpdateInboxParams = UpdateSandboxParams; diff --git a/src/types/api/marketing-stats.ts b/src/types/api/marketing-stats.ts index e509da80..3cd09ed5 100644 --- a/src/types/api/marketing-stats.ts +++ b/src/types/api/marketing-stats.ts @@ -28,7 +28,7 @@ export type MarketingStatsFilterParams = { start_date: string; /** End of the period (inclusive), `YYYY-MM-DD`. */ end_date: string; - /** IDs of the sending domains to include, as returned by the Sending Domains endpoints. */ + /** IDs of the domains to include, as returned by `client.domains`. */ sending_domain_ids?: number[]; /** One source narrows the results to it; omit, or pass both, for all Email Marketing traffic. */ sources?: MarketingStatsSource[]; diff --git a/src/types/api/projects.ts b/src/types/api/projects.ts index 9a637714..151e9f5d 100644 --- a/src/types/api/projects.ts +++ b/src/types/api/projects.ts @@ -1,4 +1,4 @@ -import { Inbox } from "./inboxes"; +import { Sandbox } from "./sandboxes"; type ShareLinks = { admin: string; @@ -16,6 +16,6 @@ export type Project = { id: number; name: string; share_links: ShareLinks; - inboxes: Inbox[]; + inboxes: Sandbox[]; permissions: Permissions; }; diff --git a/src/types/api/sandboxes.ts b/src/types/api/sandboxes.ts new file mode 100644 index 00000000..3f18ea84 --- /dev/null +++ b/src/types/api/sandboxes.ts @@ -0,0 +1,37 @@ +export type UpdateSandboxParams = { + name: string; + emailUsername: string; +}; + +type Permissions = { + can_read: boolean; + can_update: boolean; + can_destroy: boolean; + can_leave: boolean; +}; + +export type Sandbox = { + id: number; + name: string; + username: string; + password: string; + max_size: number; + status: string; + email_username: string; + email_username_enabled: boolean; + sent_messages_count: number; + forwarded_messages_count: number; + used: boolean; + forward_from_email_address: string; + project_id: number; + domain: string; + pop3_domain: string; + email_domain: string; + smtp_ports: number[]; + pop3_ports: number[]; + emails_count: number; + emails_unread_count: number; + last_message_sent_at: string | null; + max_message_size: number; + permissions: Permissions; +}; diff --git a/src/types/api/sending-domains.ts b/src/types/api/sending-domains.ts index 5a9947fe..1cdd38b1 100644 --- a/src/types/api/sending-domains.ts +++ b/src/types/api/sending-domains.ts @@ -1,51 +1,24 @@ -export interface DnsRecord { - key: string; - domain: string; - type: string; - value: string; - status: string; - name: string; -} +import { + CreateDomainParams, + Domain, + DomainPermissions, + DomainsResponse, + UpdateDomainParams, +} from "./domains"; -export interface SendingDomainPermissions { - can_read: boolean; - can_update: boolean; - can_destroy: boolean; -} +export type { DnsRecord } from "./domains"; -export interface SendingDomain { - id: number; - domain_name: string; - demo: boolean; - compliance_status: string; - dns_verified: boolean; - dns_verified_at: string | null; - dns_records: DnsRecord[]; - open_tracking_enabled: boolean; - click_tracking_enabled: boolean; - tracking_opt_out_enabled: boolean; - auto_unsubscribe_link_enabled: boolean; - custom_domain_tracking_enabled: boolean; - health_alerts_enabled: boolean; - critical_alerts_enabled: boolean; - alert_recipient_email: string | null; - inbound_enabled: boolean; - inbound_verified: boolean; - permissions: SendingDomainPermissions; -} +/** @deprecated Use `DomainPermissions` instead. */ +export type SendingDomainPermissions = DomainPermissions; -export interface CreateSendingDomainParams { - domain_name: string; -} +/** @deprecated Use `Domain` instead. */ +export type SendingDomain = Domain; -export interface SendingDomainsResponse { - data: SendingDomain[]; -} +/** @deprecated Use `CreateDomainParams` instead. */ +export type CreateSendingDomainParams = CreateDomainParams; -export interface UpdateSendingDomainParams { - open_tracking_enabled?: boolean; - click_tracking_enabled?: boolean; - tracking_opt_out_enabled?: boolean; - auto_unsubscribe_link_enabled?: boolean; - inbound_enabled?: boolean; -} +/** @deprecated Use `DomainsResponse` instead. */ +export type SendingDomainsResponse = DomainsResponse; + +/** @deprecated Use `UpdateDomainParams` instead. */ +export type UpdateSendingDomainParams = UpdateDomainParams; diff --git a/src/types/mailtrap.ts b/src/types/mailtrap.ts index ecce670a..d0fa7ed2 100644 --- a/src/types/mailtrap.ts +++ b/src/types/mailtrap.ts @@ -70,6 +70,9 @@ export type SendError = { export type MailtrapClientConfig = { token: string; + /** ID of the sandbox that `sandbox: true` sends to. */ + sandboxId?: number; + /** @deprecated Use `sandboxId` instead. */ testInboxId?: number; accountId?: number; organizationId?: number;