From 21fdcd66a8b388adf7cb8f14e5ec2eef2aa903b8 Mon Sep 17 00:00:00 2001 From: "fern-api[bot]" <115122769+fern-api[bot]@users.noreply.github.com> Date: Wed, 13 May 2026 15:43:57 +0000 Subject: [PATCH] SDK regeneration --- .fern/metadata.json | 11 +- .fern/verify.sh | 5 + package.json | 4 +- pnpm-lock.yaml | 614 +++--- reference.md | 1921 ++++++++++++++++- src/BaseClient.ts | 29 +- src/api/resources/account/client/Client.ts | 34 +- .../account/types/GetAccountResponse.ts | 22 +- src/api/resources/balance/client/Client.ts | 116 +- .../requests/BeginTransactionRequest.ts | 33 +- .../requests/CreateBalanceOrderRequest.ts | 15 +- .../requests/GetContactBalancesRequest.ts | 15 +- ...yBalanceProgramsPidActiveBalanceRequest.ts | 14 +- ...nceProgramsPidTransactionHistoryRequest.ts | 12 +- .../balance/client/requests/index.ts | 4 +- .../types/GetContactBalancesRequestSort.ts | 8 + .../GetContactBalancesRequestSortField.ts | 8 + ...anceProgramsPidActiveBalanceRequestSort.ts | 8 + ...BalanceProgramsPidActiveBalanceResponse.ts | 34 + ...ceProgramsPidTransactionHistoryResponse.ts | 11 + .../types/GetSubscriptionBalancesResponse.ts | 9 +- ...ramsPidSubscriptionsCidBalancesResponse.ts | 28 +- src/api/resources/balance/types/index.ts | 4 + src/api/resources/companies/client/Client.ts | 78 +- .../client/requests/GetCompaniesRequest.ts | 8 +- .../requests/PatchCompaniesIdRequest.ts | 2 +- .../requests/PostCompaniesImportRequest.ts | 2 +- .../requests/PostCrmAttributesRequest.ts | 4 +- .../GetCrmAttributesCompaniesResponseItem.ts | 26 +- src/api/resources/contacts/client/Client.ts | 164 +- .../client/requests/CreateContactRequest.ts | 4 + .../client/requests/GetContactInfoRequest.ts | 4 +- .../client/requests/GetContactStatsRequest.ts | 4 +- .../client/requests/GetContactsRequest.ts | 4 +- .../client/requests/GetListRequest.ts | 2 +- .../client/requests/UpdateContactRequest.ts | 6 +- .../contacts/types/GetAttributesResponse.ts | 4 +- .../contacts/types/GetContactInfoResponse.ts | 6 +- .../contacts/types/GetSegmentsResponse.ts | 4 +- .../resources/conversations/client/Client.ts | 46 +- ...PostConversationsAgentOnlinePingRequest.ts | 16 +- .../PostConversationsMessagesRequest.ts | 22 +- .../PostConversationsPushedMessagesRequest.ts | 20 +- .../PutConversationsMessagesIdRequest.ts | 2 +- ...PutConversationsPushedMessagesIdRequest.ts | 4 +- src/api/resources/coupons/client/Client.ts | 24 +- .../resources/customObjects/client/Client.ts | 134 +- .../BatchDeleteObjectRecordsRequest.ts | 4 +- .../client/requests/GetrecordsRequest.ts | 2 +- .../client/requests/UpsertrecordsRequest.ts | 155 +- .../customObjects/client/requests/index.ts | 2 +- .../customObjects/types/GetrecordsResponse.ts | 19 +- src/api/resources/deals/client/Client.ts | 80 +- .../client/requests/GetCrmDealsRequest.ts | 8 +- .../client/requests/PatchCrmDealsIdRequest.ts | 2 +- .../requests/PostCrmDealsImportRequest.ts | 2 +- .../GetCrmAttributesDealsResponseItem.ts | 26 +- src/api/resources/domains/client/Client.ts | 10 +- src/api/resources/ecommerce/client/Client.ts | 99 +- .../requests/CreateBatchOrderRequest.ts | 4 +- .../CreateUpdateBatchProductsRequest.ts | 6 +- .../requests/CreateUpdateProductRequest.ts | 6 +- .../GetEcommerceAttributionMetricsRequest.ts | 3 +- .../client/requests/GetProductsRequest.ts | 20 +- .../types/CreateUpdateCategoryResponse.ts | 2 +- .../types/CreateUpdateProductResponse.ts | 4 +- .../types/GetProductsRequestSortByField.ts | 10 + src/api/resources/ecommerce/types/index.ts | 1 + .../resources/emailCampaigns/client/Client.ts | 71 +- .../requests/CreateEmailCampaignRequest.ts | 14 +- .../requests/GetEmailCampaignRequest.ts | 2 +- .../requests/GetEmailCampaignsRequest.ts | 10 +- .../types/GetEmailCampaignResponse.ts | 35 +- .../types/GetEmailCampaignsResponse.ts | 33 +- src/api/resources/event/client/Client.ts | 26 +- .../requests/CreateBatchEventsRequest.ts | 85 + .../client/requests/CreateEventRequest.ts | 6 +- .../resources/event/client/requests/index.ts | 1 + src/api/resources/event/index.ts | 1 - .../types/CreateBatchEventsRequestItem.ts | 66 - src/api/resources/event/types/index.ts | 1 - .../resources/externalFeeds/client/Client.ts | 14 +- .../types/GetAllExternalFeedsResponse.ts | 10 +- .../types/GetExternalFeedByUuidResponse.ts | 12 +- src/api/resources/files/client/Client.ts | 24 +- .../resources/inboundParsing/client/Client.ts | 15 +- .../requests/GetInboundEmailEventsRequest.ts | 4 +- .../GetInboundEmailEventsByUuidResponse.ts | 4 +- src/api/resources/index.ts | 1 - .../resources/masterAccount/client/Client.ts | 130 +- src/api/resources/notes/client/Client.ts | 28 +- .../client/requests/PatchCrmNotesIdRequest.ts | 2 +- .../notes/types/PostCrmNotesResponse.ts | 2 +- src/api/resources/payments/client/Client.ts | 12 +- src/api/resources/process/client/Client.ts | 39 +- .../process/types/GetProcessResponse.ts | 56 +- .../process/types/GetProcessesResponse.ts | 56 +- src/api/resources/program/client/Client.ts | 40 +- .../client/requests/GetLpListRequest.ts | 4 +- .../SubscribeToLoyaltyProgramRequest.ts | 8 +- .../program/types/GetLpListRequestSort.ts | 7 + .../GetParameterSubscriptionInfoResponse.ts | 2 + .../SubscribeMemberToASubscriptionResponse.ts | 8 +- .../SubscribeToLoyaltyProgramResponse.ts | 18 +- src/api/resources/program/types/index.ts | 1 + src/api/resources/reward/client/Client.ts | 36 +- .../client/requests/CreateVoucherRequest.ts | 2 + .../client/requests/RedeemVoucherRequest.ts | 2 + .../reward/types/CreateRewardResponse.ts | 14 +- .../reward/types/CreateVoucherResponse.ts | 2 + ...LoyaltyOfferProgramsPidVouchersResponse.ts | 2 + src/api/resources/senders/client/Client.ts | 18 +- .../resources/senders/types/GetIpsResponse.ts | 4 +- .../resources/smsCampaigns/client/Client.ts | 40 +- .../client/requests/GetSmsCampaignsRequest.ts | 6 +- .../types/GetSmsCampaignResponse.ts | 45 +- .../types/GetSmsCampaignsResponse.ts | 8 +- .../resources/smsTemplates/client/Client.ts | 6 +- src/api/resources/tasks/client/Client.ts | 53 +- .../client/requests/PostCrmTasksRequest.ts | 2 +- ...onse.ts => GetCrmTasktypesResponseItem.ts} | 5 +- src/api/resources/tasks/types/index.ts | 2 +- src/api/resources/tier/client/Client.ts | 32 +- .../client/requests/CreateTierGroupRequest.ts | 66 + .../transactionalEmails/client/Client.ts | 153 +- .../DeleteScheduledEmailByIdRequest.ts | 2 +- .../DeleteSmtpLogIdentifierRequest.ts | 6 +- .../GetAggregatedSmtpReportRequest.ts | 2 +- .../requests/GetEmailEventReportRequest.ts | 2 +- .../requests/GetScheduledEmailByIdRequest.ts | 4 +- .../client/requests/GetSmtpReportRequest.ts | 2 +- .../client/requests/GetSmtpTemplateRequest.ts | 6 +- .../requests/GetSmtpTemplatesRequest.ts | 2 + .../requests/UpdateSmtpTemplateRequest.ts | 6 +- .../types/GetSmtpTemplateRequestTemplateId.ts | 3 + .../types/GetTransacEmailContentResponse.ts | 4 +- .../PostPreviewSmtpEmailTemplatesRequest.ts | 3 + .../UpdateSmtpTemplateRequestTemplateId.ts | 3 + .../transactionalEmails/types/index.ts | 3 + .../transactionalSms/client/Client.ts | 36 +- .../transactionalWhatsApp/client/Client.ts | 8 +- src/api/resources/user/client/Client.ts | 20 +- src/api/resources/webhooks/client/Client.ts | 17 +- .../client/requests/CreateWebhookRequest.ts | 35 +- .../requests/ExportWebhooksHistoryRequest.ts | 2 +- .../whatsAppCampaigns/client/Client.ts | 32 +- .../types/GetWhatsAppCampaignResponse.ts | 16 + .../types/GetWhatsAppTemplatesResponse.ts | 2 + src/api/types/BalanceDefinition.ts | 117 +- src/api/types/BalanceLimit.ts | 52 +- src/api/types/Company.ts | 2 +- src/api/types/ConversationsMessage.ts | 80 +- src/api/types/Deal.ts | 8 +- src/api/types/FileData.ts | 14 +- src/api/types/GetCampaignRecipients.ts | 4 + src/api/types/GetCampaignStats.ts | 8 +- src/api/types/GetContactDetails.ts | 2 + src/api/types/GetEventsList.ts | 2 - src/api/types/GetExtendedCampaignOverview.ts | 35 +- src/api/types/GetExtendedCampaignStats.ts | 19 +- src/api/types/GetProductDetails.ts | 4 +- src/api/types/GetSmsCampaignOverview.ts | 8 +- src/api/types/GetSmtpTemplateOverview.ts | 4 +- src/api/types/GetWebhook.ts | 15 +- src/api/types/LoyaltyProgram.ts | 43 +- src/api/types/Note.ts | 18 +- src/api/types/NoteData.ts | 2 +- src/api/types/Order.ts | 2 +- src/api/types/Pipeline.ts | 6 +- src/api/types/SendTransacSms.ts | 23 +- src/api/types/Task.ts | 28 +- src/api/types/TierGroup.ts | 70 + src/api/types/Transaction.ts | 54 +- src/core/auth/AuthProvider.ts | 9 + src/core/auth/index.ts | 2 +- src/core/fetcher/Fetcher.ts | 25 +- src/core/fetcher/requestWithRetries.ts | 6 +- src/core/url/QueryStringBuilder.ts | 87 + src/core/url/index.ts | 1 + src/core/url/qs.ts | 37 +- src/version.ts | 2 +- tests/unit/fetcher/createRequestUrl.test.ts | 4 + .../fetcher/makePassthroughRequest.test.ts | 2 +- tests/unit/fetcher/redacting.test.ts | 106 + tests/unit/fetcher/requestWithRetries.test.ts | 66 +- tests/unit/url/QueryStringBuilder.test.ts | 236 ++ tests/unit/url/qs.test.ts | 102 +- tests/wire/account.test.ts | 16 +- tests/wire/balance.test.ts | 335 +-- tests/wire/companies.test.ts | 28 +- tests/wire/contacts.test.ts | 75 +- tests/wire/conversations.test.ts | 400 ++-- tests/wire/customObjects.test.ts | 154 +- tests/wire/deals.test.ts | 58 +- tests/wire/ecommerce.test.ts | 8 +- tests/wire/emailCampaigns.test.ts | 106 +- tests/wire/event.test.ts | 81 +- tests/wire/externalFeeds.test.ts | 44 +- tests/wire/files.test.ts | 18 +- tests/wire/inboundParsing.test.ts | 21 + tests/wire/masterAccount.test.ts | 74 +- tests/wire/notes.test.ts | 30 +- tests/wire/process.test.ts | 81 +- tests/wire/program.test.ts | 137 +- tests/wire/reward.test.ts | 6 +- tests/wire/senders.test.ts | 8 +- tests/wire/smsCampaigns.test.ts | 19 +- tests/wire/tasks.test.ts | 49 +- tests/wire/tier.test.ts | 42 + tests/wire/transactionalEmails.test.ts | 66 +- tests/wire/transactionalSms.test.ts | 23 + tests/wire/webhooks.test.ts | 16 +- tests/wire/whatsAppCampaigns.test.ts | 3 + 213 files changed, 6624 insertions(+), 2155 deletions(-) create mode 100755 .fern/verify.sh create mode 100644 src/api/resources/balance/types/GetContactBalancesRequestSort.ts create mode 100644 src/api/resources/balance/types/GetContactBalancesRequestSortField.ts create mode 100644 src/api/resources/balance/types/GetLoyaltyBalanceProgramsPidActiveBalanceRequestSort.ts create mode 100644 src/api/resources/balance/types/GetLoyaltyBalanceProgramsPidActiveBalanceResponse.ts create mode 100644 src/api/resources/ecommerce/types/GetProductsRequestSortByField.ts create mode 100644 src/api/resources/event/client/requests/CreateBatchEventsRequest.ts delete mode 100644 src/api/resources/event/types/CreateBatchEventsRequestItem.ts delete mode 100644 src/api/resources/event/types/index.ts create mode 100644 src/api/resources/program/types/GetLpListRequestSort.ts rename src/api/resources/tasks/types/{GetCrmTasktypesResponse.ts => GetCrmTasktypesResponseItem.ts} (71%) create mode 100644 src/api/resources/transactionalEmails/types/GetSmtpTemplateRequestTemplateId.ts create mode 100644 src/api/resources/transactionalEmails/types/PostPreviewSmtpEmailTemplatesRequest.ts create mode 100644 src/api/resources/transactionalEmails/types/UpdateSmtpTemplateRequestTemplateId.ts create mode 100644 src/core/url/QueryStringBuilder.ts create mode 100644 tests/unit/url/QueryStringBuilder.test.ts diff --git a/.fern/metadata.json b/.fern/metadata.json index fc438ba..d51bc28 100644 --- a/.fern/metadata.json +++ b/.fern/metadata.json @@ -1,7 +1,7 @@ { - "cliVersion": "4.65.2", + "cliVersion": "5.23.3", "generatorName": "fernapi/fern-typescript-sdk", - "generatorVersion": "3.63.3", + "generatorVersion": "3.70.6", "generatorConfig": { "generateWireTests": true, "namespaceExport": "Brevo", @@ -15,6 +15,9 @@ } } }, - "originGitCommit": "d2e18d0bd27160206c8251e11269b139a3b4ea10", - "sdkVersion": "5.0.4" + "originGitCommit": "626852ab9868892d33b75b16b34f5db02dcb70ca", + "originGitCommitIsDirty": true, + "invokedBy": "manual", + "requestedVersion": "6.0.0", + "sdkVersion": "6.0.0" } diff --git a/.fern/verify.sh b/.fern/verify.sh new file mode 100755 index 0000000..a224ac8 --- /dev/null +++ b/.fern/verify.sh @@ -0,0 +1,5 @@ +#!/bin/bash +set -euo pipefail +pnpm install +pnpm build +pnpm test diff --git a/package.json b/package.json index a3986f1..03b45f8 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@getbrevo/brevo", - "version": "5.0.4", + "version": "6.0.0", "private": false, "repository": { "type": "git", @@ -402,7 +402,7 @@ "ts-loader": "^9.5.4", "vitest": "^4.1.1", "msw": "2.11.2", - "@types/node": "^18.19.70", + "@types/node": "^20.0.0", "typescript": "~5.9.3", "@biomejs/biome": "2.4.10" }, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 255bd14..de64b6a 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -12,23 +12,23 @@ importers: specifier: 2.4.10 version: 2.4.10 '@types/node': - specifier: ^18.19.70 - version: 18.19.130 + specifier: ^20.0.0 + version: 20.19.41 msw: specifier: 2.11.2 - version: 2.11.2(@types/node@18.19.130)(typescript@5.9.3) + version: 2.11.2(@types/node@20.19.41)(typescript@5.9.3) ts-loader: specifier: ^9.5.4 - version: 9.5.7(typescript@5.9.3)(webpack@5.106.0) + version: 9.5.7(typescript@5.9.3)(webpack@5.106.2) typescript: specifier: ~5.9.3 version: 5.9.3 vitest: specifier: ^4.1.1 - version: 4.1.4(@types/node@18.19.130)(msw@2.11.2(@types/node@18.19.130)(typescript@5.9.3))(vite@8.0.8(@types/node@18.19.130)(terser@5.46.1)) + version: 4.1.6(@types/node@20.19.41)(msw@2.11.2(@types/node@20.19.41)(typescript@5.9.3))(vite@8.0.12(@types/node@20.19.41)(terser@5.47.1)) webpack: specifier: ^5.105.4 - version: 5.106.0 + version: 5.106.2 packages: @@ -95,11 +95,11 @@ packages: '@bundled-es-modules/statuses@1.0.1': resolution: {integrity: sha512-yn7BklA5acgcBr+7w064fGV+SGIFySjCKpqjcWgBAIfrAkY+4GQTJJHQMeT3V/sgz23VTEVV8TtOmkvJAhFVfg==} - '@emnapi/core@1.9.2': - resolution: {integrity: sha512-UC+ZhH3XtczQYfOlu3lNEkdW/p4dsJ1r/bP7H8+rhao3TTTMO1ATq/4DdIi23XuGoFY+Cz0JmCbdVl0hz9jZcA==} + '@emnapi/core@1.10.0': + resolution: {integrity: sha512-yq6OkJ4p82CAfPl0u9mQebQHKPJkY7WrIuk205cTYnYe+k2Z8YBh11FrbRG/H6ihirqcacOgl2BIO8oyMQLeXw==} - '@emnapi/runtime@1.9.2': - resolution: {integrity: sha512-3U4+MIWHImeyu1wnmVygh5WlgfYDtyf0k8AbLhMFxOipihf6nrWC4syIm/SwEeec0mNSafiiNnMJwbza/Is6Lw==} + '@emnapi/runtime@1.10.0': + resolution: {integrity: sha512-ewvYlk86xUoGI0zQRNq/mC+16R1QeDlKQy21Ki3oSYXNgLb45GV1P6A0M+/s6nyCuNDqe5VpaY84BzXGwVbwFA==} '@emnapi/wasi-threads@1.2.1': resolution: {integrity: sha512-uTII7OYF+/Mes/MrcIOYp5yOtSMLBWSIoLPpcgwipoiKbli6k322tcoFsxoIIxPDqW01SQGAgko4EzZi2BNv2w==} @@ -159,8 +159,8 @@ packages: resolution: {integrity: sha512-2+BzZbjRO7Ct61k8fMNHEtoKjeWI9pIlHFTqBwZ5icHpqszIgEZbjb1MW5Z0+bITTCTl3gk4PDBxs9tA/csXvA==} engines: {node: '>=18'} - '@napi-rs/wasm-runtime@1.1.3': - resolution: {integrity: sha512-xK9sGVbJWYb08+mTJt3/YV24WxvxpXcXtP6B172paPZ+Ts69Re9dAr7lKwJoeIx8OoeuimEiRZ7umkiUVClmmQ==} + '@napi-rs/wasm-runtime@1.1.4': + resolution: {integrity: sha512-3NQNNgA1YSlJb/kMH1ildASP9HW7/7kYnRI2szWJaofaS1hWmbGI4H+d3+22aGzXXN9IJ+n+GiFVcGipJP18ow==} peerDependencies: '@emnapi/core': ^1.7.1 '@emnapi/runtime': ^1.7.1 @@ -174,112 +174,112 @@ packages: '@open-draft/until@2.1.0': resolution: {integrity: sha512-U69T3ItWHvLwGg5eJ0n3I62nWuE6ilHlmz7zM0npLBRvPRd7e6NYmg54vvRtP5mZG7kZqZCFVdsTWo7BPtBujg==} - '@oxc-project/types@0.124.0': - resolution: {integrity: sha512-VBFWMTBvHxS11Z5Lvlr3IWgrwhMTXV+Md+EQF0Xf60+wAdsGFTBx7X7K/hP4pi8N7dcm1RvcHwDxZ16Qx8keUg==} + '@oxc-project/types@0.129.0': + resolution: {integrity: sha512-3oz8m3FGdr2nDXVqmFUw7jolKliC4MoyXYIG2c7gpjBnzUWQpUGIYcXYKxTdTi+N2jusvt610ckTMkxdwHkYEg==} - '@rolldown/binding-android-arm64@1.0.0-rc.15': - resolution: {integrity: sha512-YYe6aWruPZDtHNpwu7+qAHEMbQ/yRl6atqb/AhznLTnD3UY99Q1jE7ihLSahNWkF4EqRPVC4SiR4O0UkLK02tA==} + '@rolldown/binding-android-arm64@1.0.0': + resolution: {integrity: sha512-TWMZnRLMe63C2Lhyicviu7ZHaU4kxa6PS3rofvc9GmcvptzNN11BcfQ4Sl7MwTOsisQoa2keB/EBdNCAnUo8vA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [android] - '@rolldown/binding-darwin-arm64@1.0.0-rc.15': - resolution: {integrity: sha512-oArR/ig8wNTPYsXL+Mzhs0oxhxfuHRfG7Ikw7jXsw8mYOtk71W0OkF2VEVh699pdmzjPQsTjlD1JIOoHkLP1Fg==} + '@rolldown/binding-darwin-arm64@1.0.0': + resolution: {integrity: sha512-6XcD+8k0gPVItNagEw78/qqcBDwKcwDYS8V2hRmVsfUSIrd8cWe/CBvRDI5toqFyPfj+FJr6t8U6Xj2P2prEew==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [darwin] - '@rolldown/binding-darwin-x64@1.0.0-rc.15': - resolution: {integrity: sha512-YzeVqOqjPYvUbJSWJ4EDL8ahbmsIXQpgL3JVipmN+MX0XnXMeWomLN3Fb+nwCmP/jfyqte5I3XRSm7OfQrbyxw==} + '@rolldown/binding-darwin-x64@1.0.0': + resolution: {integrity: sha512-iN/tWVXRQDWvmZlKdceP1Dwug9GDpEymhb9p4xnEe6zvCg5lFmzVljl+1qR1NVx3yfGpr2Na+CuLmv5IU8uzfQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [darwin] - '@rolldown/binding-freebsd-x64@1.0.0-rc.15': - resolution: {integrity: sha512-9Erhx956jeQ0nNTyif1+QWAXDRD38ZNjr//bSHrt6wDwB+QkAfl2q6Mn1k6OBPerznjRmbM10lgRb1Pli4xZPw==} + '@rolldown/binding-freebsd-x64@1.0.0': + resolution: {integrity: sha512-jjQMDvvwSOuhOwMszD/klSOjyWMM3zI64hWTj9KT5x4MxRbZAf+7vLQ6qouRhtsLVFHr3f0ILaJAfgENPiQdAQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [freebsd] - '@rolldown/binding-linux-arm-gnueabihf@1.0.0-rc.15': - resolution: {integrity: sha512-cVwk0w8QbZJGTnP/AHQBs5yNwmpgGYStL88t4UIaqcvYJWBfS0s3oqVLZPwsPU6M0zlW4GqjP0Zq5MnAGwFeGA==} + '@rolldown/binding-linux-arm-gnueabihf@1.0.0': + resolution: {integrity: sha512-d//Dtg2x6/m3mbV64yUGNnDGNZaDGRpDLLNGerHQUVObuNaIQaaDp25yUiqGXtHEXX+NP2d0wAlmKgpYgIAJ2A==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm] os: [linux] - '@rolldown/binding-linux-arm64-gnu@1.0.0-rc.15': - resolution: {integrity: sha512-eBZ/u8iAK9SoHGanqe/jrPnY0JvBN6iXbVOsbO38mbz+ZJsaobExAm1Iu+rxa4S1l2FjG0qEZn4Rc6X8n+9M+w==} + '@rolldown/binding-linux-arm64-gnu@1.0.0': + resolution: {integrity: sha512-n7Ofp0mx+aB2cC+Sdy5YtMnXtY9lchnHbY+3Yt0uq9JsWQExf4f5Whu0tK0R8Jdc9S6RchTHjIFY7uc92puOVQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [linux] libc: [glibc] - '@rolldown/binding-linux-arm64-musl@1.0.0-rc.15': - resolution: {integrity: sha512-ZvRYMGrAklV9PEkgt4LQM6MjQX2P58HPAuecwYObY2DhS2t35R0I810bKi0wmaYORt6m/2Sm+Z+nFgb0WhXNcQ==} + '@rolldown/binding-linux-arm64-musl@1.0.0': + resolution: {integrity: sha512-EIVjy2cgd7uuMMo94FVkBp7F6DhcZAUwNURkSG3RwUmvAXR6s0ISxM81U+IydcZByPG0pZIHsf1b6kTxoFDgJA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [linux] libc: [musl] - '@rolldown/binding-linux-ppc64-gnu@1.0.0-rc.15': - resolution: {integrity: sha512-VDpgGBzgfg5hLg+uBpCLoFG5kVvEyafmfxGUV0UHLcL5irxAK7PKNeC2MwClgk6ZAiNhmo9FLhRYgvMmedLtnQ==} + '@rolldown/binding-linux-ppc64-gnu@1.0.0': + resolution: {integrity: sha512-JEwwOPcwTLAcpDQlqSmjEmfs63xJnSiUNIGvLcDLUHCWK4XowpS/7c7tUsUH6uT/ct6bMUTdXKfI8967FYj6mg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [ppc64] os: [linux] libc: [glibc] - '@rolldown/binding-linux-s390x-gnu@1.0.0-rc.15': - resolution: {integrity: sha512-y1uXY3qQWCzcPgRJATPSOUP4tCemh4uBdY7e3EZbVwCJTY3gLJWnQABgeUetvED+bt1FQ01OeZwvhLS2bpNrAQ==} + '@rolldown/binding-linux-s390x-gnu@1.0.0': + resolution: {integrity: sha512-0wjCFhLrihtAubnT9iA0N++0pSV0z5Hg7tNGdNJ4RFaINceHadoF+kiFGyY1qSSNVIAZtLotG8Ju1bgDPkjnFA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [s390x] os: [linux] libc: [glibc] - '@rolldown/binding-linux-x64-gnu@1.0.0-rc.15': - resolution: {integrity: sha512-023bTPBod7J3Y/4fzAN6QtpkSABR0rigtrwaP+qSEabUh5zf6ELr9Nc7GujaROuPY3uwdSIXWrvhn1KxOvurWA==} + '@rolldown/binding-linux-x64-gnu@1.0.0': + resolution: {integrity: sha512-Dfn7iak9BcMMePxcoJfpSbWqnEyrp/dRF63/8qW/eHBdOZov6x5aShLLEYGYdIeSJ6vMLK/XCVB+lGIxm41bQA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [linux] libc: [glibc] - '@rolldown/binding-linux-x64-musl@1.0.0-rc.15': - resolution: {integrity: sha512-witB2O0/hU4CgfOOKUoeFgQ4GktPi1eEbAhaLAIpgD6+ZnhcPkUtPsoKKHRzmOoWPZue46IThdSgdo4XneOLYw==} + '@rolldown/binding-linux-x64-musl@1.0.0': + resolution: {integrity: sha512-5/utzzDmD/pD/bmuaUcbTf/sZYy0aztwIVlfpoW1fTjCZ0BaPOMVWGZL1zvgxyi7ZIVYWlxKONHmSbHuiOh8Jw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [linux] libc: [musl] - '@rolldown/binding-openharmony-arm64@1.0.0-rc.15': - resolution: {integrity: sha512-UCL68NJ0Ud5zRipXZE9dF5PmirzJE4E4BCIOOssEnM7wLDsxjc6Qb0sGDxTNRTP53I6MZpygyCpY8Aa8sPfKPg==} + '@rolldown/binding-openharmony-arm64@1.0.0': + resolution: {integrity: sha512-ouJs8VcUomfLfpbUECqFMRqdV4x6aeAK3MA4m6vTrJJjKyWTV5KnxZx7Jd9G+GlDaQQxubcba00x16OyJ1meig==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [openharmony] - '@rolldown/binding-wasm32-wasi@1.0.0-rc.15': - resolution: {integrity: sha512-ApLruZq/ig+nhaE7OJm4lDjayUnOHVUa77zGeqnqZ9pn0ovdVbbNPerVibLXDmWeUZXjIYIT8V3xkT58Rm9u5Q==} - engines: {node: '>=14.0.0'} + '@rolldown/binding-wasm32-wasi@1.0.0': + resolution: {integrity: sha512-E+oHKGiDA+lsKMmFtffDDw91EryDT7uJocrIuCHqhm6bCTM6xFK+3gaCkYOHfPwQr0cCNarSM2xaELoQDz9jJg==} + engines: {node: ^20.19.0 || >=22.12.0} cpu: [wasm32] - '@rolldown/binding-win32-arm64-msvc@1.0.0-rc.15': - resolution: {integrity: sha512-KmoUoU7HnN+Si5YWJigfTws1jz1bKBYDQKdbLspz0UaqjjFkddHsqorgiW1mxcAj88lYUE6NC/zJNwT+SloqtA==} + '@rolldown/binding-win32-arm64-msvc@1.0.0': + resolution: {integrity: sha512-yYK02n8Rngo+gbm1y6G0+7jk1sJ/2Wt7K0me0Y7k/ErBpyf+LJ2gFpqWVTcRV1rUepBlQRmpgWkTQCiiwrK0Ow==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [win32] - '@rolldown/binding-win32-x64-msvc@1.0.0-rc.15': - resolution: {integrity: sha512-3P2A8L+x75qavWLe/Dll3EYBJLQmtkJN8rfh+U/eR3MqMgL/h98PhYI+JFfXuDPgPeCB7iZAKiqii5vqOvnA0g==} + '@rolldown/binding-win32-x64-msvc@1.0.0': + resolution: {integrity: sha512-14bpChMahXRRXiTwahSl+zzHPW6qQTXtkMuJBFlbo+pqSAews2d4BdCSHfrJ/MBsCZtpmTafsY+1QhBzitcmdg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [win32] - '@rolldown/pluginutils@1.0.0-rc.15': - resolution: {integrity: sha512-UromN0peaE53IaBRe9W7CjrZgXl90fqGpK+mIZbA3qSTeYqg3pqpROBdIPvOG3F5ereDHNwoHBI2e50n1BDr1g==} + '@rolldown/pluginutils@1.0.0': + resolution: {integrity: sha512-aKs/3GSWyV0mrhNmt/96/Z3yczC3yvrzYATCiCXQebBsGyYzjNdUphRVLeJQ67ySKVXRfMxt2lm12pmXvbPFQQ==} '@standard-schema/spec@1.1.0': resolution: {integrity: sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==} - '@tybys/wasm-util@0.10.1': - resolution: {integrity: sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg==} + '@tybys/wasm-util@0.10.2': + resolution: {integrity: sha512-RoBvJ2X0wuKlWFIjrwffGw1IqZHKQqzIchKaadZZfnNpsAYp2mM0h36JtPCjNDAHGgYez/15uMBpfGwchhiMgg==} '@types/chai@5.2.3': resolution: {integrity: sha512-Mw558oeA9fFbv65/y4mHtXDs9bPnFMZAL/jxdPFUpOHHIXX91mcgEHbS5Lahr+pwZFR8A7GQleRWeI6cGFC2UA==} @@ -296,23 +296,23 @@ packages: '@types/eslint@9.6.1': resolution: {integrity: sha512-FXx2pKgId/WyYo2jXw63kk7/+TY7u7AziEJxJAnSFzHlqTAS3Ync6SvgYAN/k4/PQpnnVuzoMuVnByKK2qp0ag==} - '@types/estree@1.0.8': - resolution: {integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==} + '@types/estree@1.0.9': + resolution: {integrity: sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg==} '@types/json-schema@7.0.15': resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} - '@types/node@18.19.130': - resolution: {integrity: sha512-GRaXQx6jGfL8sKfaIDD6OupbIHBr9jv7Jnaml9tB7l4v068PAOXqfcujMMo5PhbIs6ggR1XODELqahT2R8v0fg==} + '@types/node@20.19.41': + resolution: {integrity: sha512-ECymXOukMnOoVkC2bb1Vc/w/836DXncOg5m8Xj1RH7xSHZJWNYY6Zh7EH477vcnD5egKNNfy2RpNOmuChhFPgQ==} '@types/statuses@2.0.6': resolution: {integrity: sha512-xMAgYwceFhRA2zY+XbEA7mxYbA093wdiW8Vu6gZPGWy9cmOyU9XesH1tNcEWsKFd5Vzrqx5T3D38PWx1FIIXkA==} - '@vitest/expect@4.1.4': - resolution: {integrity: sha512-iPBpra+VDuXmBFI3FMKHSFXp3Gx5HfmSCE8X67Dn+bwephCnQCaB7qWK2ldHa+8ncN8hJU8VTMcxjPpyMkUjww==} + '@vitest/expect@4.1.6': + resolution: {integrity: sha512-7EHDquPthALSV0jhhjgEW8FXaviMx7rSqu8W6oqCoAuOhKov814P99QDV1pxMA3QPv21YudvJngIhjrNI4opLg==} - '@vitest/mocker@4.1.4': - resolution: {integrity: sha512-R9HTZBhW6yCSGbGQnDnH3QHfJxokKN4KB+Yvk9Q1le7eQNYwiCyKxmLmurSpFy6BzJanSLuEUDrD+j97Q+ZLPg==} + '@vitest/mocker@4.1.6': + resolution: {integrity: sha512-MCFc63czMjEInOlcY2cpQCvCN+KgbAn+60xu9cMgP4sKaLC5JNAKw7JH8QdAnoAC88hW1IiSNZ+GgVXlN1UcMQ==} peerDependencies: msw: ^2.4.9 vite: ^6.0.0 || ^7.0.0 || ^8.0.0 @@ -322,20 +322,20 @@ packages: vite: optional: true - '@vitest/pretty-format@4.1.4': - resolution: {integrity: sha512-ddmDHU0gjEUyEVLxtZa7xamrpIefdEETu3nZjWtHeZX4QxqJ7tRxSteHVXJOcr8jhiLoGAhkK4WJ3WqBpjx42A==} + '@vitest/pretty-format@4.1.6': + resolution: {integrity: sha512-h5SxD/IzNhZYnrSZRsUZQIC+vD0GY8cUvq0iwsmkFKixRCKLLWqCXa/FIQ4S1R+sI+PGoojkHsdNrbZiM9Qpgw==} - '@vitest/runner@4.1.4': - resolution: {integrity: sha512-xTp7VZ5aXP5ZJrn15UtJUWlx6qXLnGtF6jNxHepdPHpMfz/aVPx+htHtgcAL2mDXJgKhpoo2e9/hVJsIeFbytQ==} + '@vitest/runner@4.1.6': + resolution: {integrity: sha512-nOPCmn2+yD0ZNmKdsXGv/UxMMWbMuKeD6GyYncNwdkYDxpQvrPSKYj2rWuDjC2Y4b6w6hjip5dBKFzEUuZe3vA==} - '@vitest/snapshot@4.1.4': - resolution: {integrity: sha512-MCjCFgaS8aZz+m5nTcEcgk/xhWv0rEH4Yl53PPlMXOZ1/Ka2VcZU6CJ+MgYCZbcJvzGhQRjVrGQNZqkGPttIKw==} + '@vitest/snapshot@4.1.6': + resolution: {integrity: sha512-YhsdE6xAVfTDmzjxL2ZDUvjj+ZsgyOKe+TdQzqkD72wIOmHka8NuGQ6NpTNZv9D2Z63fbwWKJPeVpEw4EQgYxw==} - '@vitest/spy@4.1.4': - resolution: {integrity: sha512-XxNdAsKW7C+FLydqFJLb5KhJtl3PGCMmYwFRfhvIgxJvLSXhhVI1zM8f1qD3Zg7RCjTSzDVyct6sghs9UEgBEQ==} + '@vitest/spy@4.1.6': + resolution: {integrity: sha512-JFKxMx6udhwKh/Ldo270e17QX710vgunMkuPAvXjHSvC6oqLWAHhVhjg/I71q0u0CBSErIODV1Kjv0FQNSWjdg==} - '@vitest/utils@4.1.4': - resolution: {integrity: sha512-13QMT+eysM5uVGa1rG4kegGYNp6cnQcsTc67ELFbhNLQO+vgsygtYJx2khvdt4gVQqSSpC/KT5FZZxUpP3Oatw==} + '@vitest/utils@4.1.6': + resolution: {integrity: sha512-FxIY+U81R3LGKCxaHHFRQ5+g6/iRgGLmeHWdp2Amj4ljQRrEIWHmZyDfDYBRZlpyqA7qKxtS9DD1dhk8RnRIVQ==} '@webassemblyjs/ast@1.14.1': resolution: {integrity: sha512-nuBEDgQfm1ccRp/8bCQrx1frohyufl4JlbMMZ4P1wpeOfDhF6FQkxZJ1b/e+PLwr6X1Nhw6OLme5usuBWYBvuQ==} @@ -412,8 +412,8 @@ packages: peerDependencies: ajv: ^8.8.2 - ajv@8.18.0: - resolution: {integrity: sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A==} + ajv@8.20.0: + resolution: {integrity: sha512-Thbli+OlOj+iMPYFBVBfJ3OmCAnaSyNn4M1vz9T6Gka5Jt9ba/HIR56joy65tY6kx/FCF5VXNB819Y7/GUrBGA==} ansi-regex@5.0.1: resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} @@ -427,8 +427,8 @@ packages: resolution: {integrity: sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==} engines: {node: '>=12'} - baseline-browser-mapping@2.10.17: - resolution: {integrity: sha512-HdrkN8eVG2CXxeifv/VdJ4A4RSra1DTW8dc/hdxzhGHN8QePs6gKaWM9pHPcpCoxYZJuOZ8drHmbdpLHjCYjLA==} + baseline-browser-mapping@2.10.29: + resolution: {integrity: sha512-Asa2krT+XTPZINCS+2QcyS8WTkObE77RwkydwF7h6DmnKqbvlalz93m/dnphUyCa6SWSP51VgtEUf2FN+gelFQ==} engines: {node: '>=6.0.0'} hasBin: true @@ -444,8 +444,8 @@ packages: buffer-from@1.1.2: resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} - caniuse-lite@1.0.30001787: - resolution: {integrity: sha512-mNcrMN9KeI68u7muanUpEejSLghOKlVhRqS/Za2IeyGllJ9I9otGpR9g3nsw7n4W378TE/LyIteA0+/FOZm4Kg==} + caniuse-lite@1.0.30001792: + resolution: {integrity: sha512-hVLMUZFgR4JJ6ACt1uEESvQN1/dBVqPAKY0hgrV70eN3391K6juAfTjKZLKvOMsx8PxA7gsY1/tLMMTcfFLLpw==} chai@6.2.2: resolution: {integrity: sha512-NUPRluOfOiTKBKvWPtSD4PhFvWCqOi0BGStNWs57X9js7XGTprSmFoz5F0tWhR4WPjNeR9jXqdC7/UpSJTnlRg==} @@ -488,18 +488,18 @@ packages: resolution: {integrity: sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==} engines: {node: '>=8'} - electron-to-chromium@1.5.334: - resolution: {integrity: sha512-mgjZAz7Jyx1SRCwEpy9wefDS7GvNPazLthHg8eQMJ76wBdGQQDW33TCrUTvQ4wzpmOrv2zrFoD3oNufMdyMpog==} + electron-to-chromium@1.5.353: + resolution: {integrity: sha512-kOrWphBi8TOZyiJZqsgqIle0lw+tzmnQK83pV9dZUd01Nm2POECSyFQMAuarzZdYqQW7FH9RaYOuaRo3h+bQ3w==} emoji-regex@8.0.0: resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} - enhanced-resolve@5.20.1: - resolution: {integrity: sha512-Qohcme7V1inbAfvjItgw0EaxVX5q2rdVEZHRBrEQdRZTssLDGsL8Lwrznl8oQ/6kuTJONLaDcGjkNP247XEhcA==} + enhanced-resolve@5.21.3: + resolution: {integrity: sha512-QyL119InA+XXEkNLNTPCXPugSvOfhwv0JOlGNzvxs0hZaiHLNvXSpudUWsOlsXGWJh8G6ckCScEkVHfX3kw/2Q==} engines: {node: '>=10.13.0'} - es-module-lexer@2.0.0: - resolution: {integrity: sha512-5POEcUuZybH7IdmGsD8wlf0AI55wMecM9rVBTI/qEAy2c1kTOm3DjFYjrBdI2K3BaJjJYfYFeRtM0t9ssnRuxw==} + es-module-lexer@2.1.0: + resolution: {integrity: sha512-n27zTYMjYu1aj4MjCWzSP7G9r75utsaoc8m61weK+W8JMBGGQybd43GstCXZ3WNmSFtGT9wi59qQTW6mhTR5LQ==} escalade@3.2.0: resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} @@ -535,8 +535,8 @@ packages: fast-deep-equal@3.1.3: resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} - fast-uri@3.1.0: - resolution: {integrity: sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA==} + fast-uri@3.1.2: + resolution: {integrity: sha512-rVjf7ArG3LTk+FS6Yw81V1DLuZl1bRbNrev6Tmd/9RaroeeRRJhAt7jg/6YFxbvAQXUCavSoZhPPj6oOx+5KjQ==} fdir@6.5.0: resolution: {integrity: sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==} @@ -566,8 +566,8 @@ packages: graceful-fs@4.2.11: resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} - graphql@16.13.2: - resolution: {integrity: sha512-5bJ+nf/UCpAjHM8i06fl7eLyVC9iuNAjm9qzkiu2ZGhM0VscSvS6WDPfAwkdkBuoXGM9FJSbKl6wylMwP9Ktig==} + graphql@16.14.0: + resolution: {integrity: sha512-BBvQ/406p+4CZbTpCbVPSxfzrZrbnuWSP1ELYgyS6B+hNeKzgrdB4JczCa5VZUBQrDa9hUngm0KnexY6pJRN5Q==} engines: {node: ^12.22.0 || ^14.16.0 || ^16.0.0 || >=17.0.0} has-flag@4.0.0: @@ -592,9 +592,6 @@ packages: resolution: {integrity: sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==} engines: {node: '>= 10.13.0'} - json-parse-even-better-errors@2.3.1: - resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==} - json-schema-traverse@1.0.0: resolution: {integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==} @@ -672,8 +669,8 @@ packages: resolution: {integrity: sha512-NXYBzinNrblfraPGyrbPoD19C1h9lfI/1mzgWYvXUTe414Gz/X1FD2XBZSZM7rRTrMA8JL3OtAaGifrIKhQ5yQ==} engines: {node: '>= 12.0.0'} - loader-runner@4.3.1: - resolution: {integrity: sha512-IWqP2SCPhyVFTBtRcgMHdzlf9ul25NwaFx4wCEH/KjAXuuHY4yNjvPXsBokp8jCB936PyWRaPKUNh8NvylLp2Q==} + loader-runner@4.3.2: + resolution: {integrity: sha512-DFEqQ3ihfS9blba08cLfYf1NRAIEm+dDjic073DRDc3/JspI/8wYmtDsHwd3+4hwvdxSK7PGaElfTmm0awWJ4w==} engines: {node: '>=6.11.5'} magic-string@0.30.21: @@ -686,12 +683,8 @@ packages: resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} engines: {node: '>=8.6'} - mime-db@1.52.0: - resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} - engines: {node: '>= 0.6'} - - mime-types@2.1.35: - resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} + mime-db@1.54.0: + resolution: {integrity: sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==} engines: {node: '>= 0.6'} msw@2.11.2: @@ -708,16 +701,16 @@ packages: resolution: {integrity: sha512-WWdIxpyjEn+FhQJQQv9aQAYlHoNVdzIzUySNV1gHUPDSdZJ3yZn7pAAbQcV7B56Mvu881q9FZV+0Vx2xC44VWA==} engines: {node: ^18.17.0 || >=20.5.0} - nanoid@3.3.11: - resolution: {integrity: sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==} + nanoid@3.3.12: + resolution: {integrity: sha512-ZB9RH/39qpq5Vu6Y+NmUaFhQR6pp+M2Xt76XBnEwDaGcVAqhlvxrl3B2bKS5D3NH3QR76v3aSrKaF/Kiy7lEtQ==} engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} hasBin: true neo-async@2.6.2: resolution: {integrity: sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==} - node-releases@2.0.37: - resolution: {integrity: sha512-1h5gKZCF+pO/o3Iqt5Jp7wc9rH3eJJ0+nh/CIoiRwjRxde/hAHyLPXYN4V3CqKAbiZPSeJFSWHmJsbkicta0Eg==} + node-releases@2.0.44: + resolution: {integrity: sha512-5WUyunoPMsvvEhS8AxHtRzP+oA8UCkJ7YRxatWKjngndhDGLiqEVAQKWjFAiAiuL8zMRGzGSJxFnLetoa43qGQ==} obug@2.1.1: resolution: {integrity: sha512-uTqF9MuPraAQ+IsnPf366RG4cP9RtUi7MLO1N3KEc+wb0a6yKpeL0lmk2IB1jY5KHPAlTc6T/JRdC/YqxHNwkQ==} @@ -742,8 +735,8 @@ packages: resolution: {integrity: sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==} engines: {node: '>=12'} - postcss@8.5.9: - resolution: {integrity: sha512-7a70Nsot+EMX9fFU3064K/kdHWZqGVY+BADLyXc8Dfv+mTLLVl6JzJpPaCZ2kQL9gIJvKXSLMHhqdRRjwQeFtw==} + postcss@8.5.14: + resolution: {integrity: sha512-SoSL4+OSEtR99LHFZQiJLkT59C5B1amGO1NzTwj7TT1qCUgUO6hxOvzkOYxD+vMrXBM3XJIKzokoERdqQq/Zmg==} engines: {node: ^10 || ^12 || >=14} require-directory@2.1.1: @@ -757,8 +750,8 @@ packages: rettime@0.7.0: resolution: {integrity: sha512-LPRKoHnLKd/r3dVxcwO7vhCW+orkOGj9ViueosEBK6ie89CijnfRlhaDhHq/3Hxu4CkWQtxwlBG0mzTQY6uQjw==} - rolldown@1.0.0-rc.15: - resolution: {integrity: sha512-Ff31guA5zT6WjnGp0SXw76X6hzGRk/OQq2hE+1lcDe+lJdHSgnSX6nK3erbONHyCbpSj9a9E+uX/OvytZoWp2g==} + rolldown@1.0.0: + resolution: {integrity: sha512-yD986aXDESFGS95spT1LAv0jssywP4npMEjmMHyN2/5+eE8qQJUype2AaKkRiLgBgyD0LFlubwAht7VmY8rGoA==} engines: {node: ^20.19.0 || >=22.12.0} hasBin: true @@ -766,8 +759,8 @@ packages: resolution: {integrity: sha512-eflK8wEtyOE6+hsaRVPxvUKYCpRgzLqDTb8krvAsRIwOGlHoSgYLgBXoubGgLd2fT41/OUYdb48v4k4WWHQurA==} engines: {node: '>= 10.13.0'} - semver@7.7.4: - resolution: {integrity: sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==} + semver@7.8.0: + resolution: {integrity: sha512-AcM7dV/5ul4EekoQ29Agm5vri8JNqRyj39o0qpX6vDF2GZrtutZl5RwgD1XnZjiTAfncsJhMI48QQH3sN87YNA==} engines: {node: '>=10'} hasBin: true @@ -800,8 +793,8 @@ packages: resolution: {integrity: sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==} engines: {node: '>= 0.8'} - std-env@4.0.0: - resolution: {integrity: sha512-zUMPtQ/HBY3/50VbpkupYHbRroTRZJPRLvreamgErJVys0ceuzMkD44J/QjqhHjOzK42GQ3QZIeFG1OYfOtKqQ==} + std-env@4.1.0: + resolution: {integrity: sha512-Rq7ybcX2RuC55r9oaPVEW7/xu3tj8u4GeBYHBWCychFtzMIr86A7e3PPEBPT37sHStKX3+TiX/Fr/ACmJLVlLQ==} strict-event-emitter@0.5.1: resolution: {integrity: sha512-vMgjE/GGEPEFnhFub6pa4FmJBRBVOLpIII2hvCZ8Kzb7K0hlHo7mQv6xYrBvCL2LtAIBwFUK8wvuJgTVSQ5MFQ==} @@ -822,36 +815,63 @@ packages: resolution: {integrity: sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==} engines: {node: '>=10'} - tapable@2.3.2: - resolution: {integrity: sha512-1MOpMXuhGzGL5TTCZFItxCc0AARf1EZFQkGqMm7ERKj8+Hgr5oLvJOVFcC+lRmR8hCe2S3jC4T5D7Vg/d7/fhA==} + tapable@2.3.3: + resolution: {integrity: sha512-uxc/zpqFg6x7C8vOE7lh6Lbda8eEL9zmVm/PLeTPBRhh1xCgdWaQ+J1CUieGpIfm2HdtsUpRv+HshiasBMcc6A==} engines: {node: '>=6'} - terser-webpack-plugin@5.4.0: - resolution: {integrity: sha512-Bn5vxm48flOIfkdl5CaD2+1CiUVbonWQ3KQPyP7/EuIl9Gbzq/gQFOzaMFUEgVjB1396tcK0SG8XcNJ/2kDH8g==} + terser-webpack-plugin@5.6.0: + resolution: {integrity: sha512-Eum+5ajkaOhf5KbM26osvv21kLD7BaGqQ1UA4Ami4arYwylmGUQTgHFpHDdmJod1q4QXa66p0to/FBKID+J1vA==} engines: {node: '>= 10.13.0'} peerDependencies: + '@minify-html/node': '*' '@swc/core': '*' + '@swc/css': '*' + '@swc/html': '*' + clean-css: '*' + cssnano: '*' + csso: '*' esbuild: '*' + html-minifier-terser: '*' + lightningcss: '*' + postcss: '*' uglify-js: '*' webpack: ^5.1.0 peerDependenciesMeta: + '@minify-html/node': + optional: true '@swc/core': optional: true + '@swc/css': + optional: true + '@swc/html': + optional: true + clean-css: + optional: true + cssnano: + optional: true + csso: + optional: true esbuild: optional: true + html-minifier-terser: + optional: true + lightningcss: + optional: true + postcss: + optional: true uglify-js: optional: true - terser@5.46.1: - resolution: {integrity: sha512-vzCjQO/rgUuK9sf8VJZvjqiqiHFaZLnOiimmUuOKODxWL8mm/xua7viT7aqX7dgPY60otQjUotzFMmCB4VdmqQ==} + terser@5.47.1: + resolution: {integrity: sha512-tPbLXTI6ohPASb/1YViL428oEHu6/qv1OxqYnfaonVCFHqx4+wCd95pHrQWsL5X4pl90CTyW9piSAsS2L0VoMw==} engines: {node: '>=10'} hasBin: true tinybench@2.9.0: resolution: {integrity: sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==} - tinyexec@1.1.1: - resolution: {integrity: sha512-VKS/ZaQhhkKFMANmAOhhXVoIfBXblQxGX1myCQ2faQrfmobMftXeJPcZGp0gS07ocvGJWDLZGyOZDadDBqYIJg==} + tinyexec@1.1.2: + resolution: {integrity: sha512-dAqSqE/RabpBKI8+h26GfLq6Vb3JVXs30XYQjdMjaj/c2tS8IYYMbIzP599KtRj7c57/wYApb3QjgRgXmrCukA==} engines: {node: '>=18'} tinyglobby@0.2.16: @@ -862,11 +882,11 @@ packages: resolution: {integrity: sha512-Bf+ILmBgretUrdJxzXM0SgXLZ3XfiaUuOj/IKQHuTXip+05Xn+uyEYdVg0kYDipTBcLrCVyUzAPz7QmArb0mmw==} engines: {node: '>=14.0.0'} - tldts-core@7.0.28: - resolution: {integrity: sha512-7W5Efjhsc3chVdFhqtaU0KtK32J37Zcr9RKtID54nG+tIpcY79CQK/veYPODxtD/LJ4Lue66jvrQzIX2Z2/pUQ==} + tldts-core@7.0.30: + resolution: {integrity: sha512-uiHN8PIB1VmWyS98eZYja4xzlYqeFZVjb4OuYlJQnZAuJhMw4PbKQOKgHKhBdJR3FE/t5mUQ1Kd80++B+qhD1Q==} - tldts@7.0.28: - resolution: {integrity: sha512-+Zg3vWhRUv8B1maGSTFdev9mjoo8Etn2Ayfs4cnjlD3CsGkxXX4QyW3j2WJ0wdjYcYmy7Lx2RDsZMhgCWafKIw==} + tldts@7.0.30: + resolution: {integrity: sha512-ELrFxuqsDdHUwoh0XxDbxuLD3Wnz49Z57IFvTtvWy1hJdcMZjXLIuonjilCiWHlT2GbE4Wlv1wKVTzDFnXH1aw==} hasBin: true to-regex-range@5.0.1: @@ -896,8 +916,8 @@ packages: engines: {node: '>=14.17'} hasBin: true - undici-types@5.26.5: - resolution: {integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==} + undici-types@6.21.0: + resolution: {integrity: sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==} update-browserslist-db@1.2.3: resolution: {integrity: sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==} @@ -905,13 +925,13 @@ packages: peerDependencies: browserslist: '>= 4.21.0' - vite@8.0.8: - resolution: {integrity: sha512-dbU7/iLVa8KZALJyLOBOQ88nOXtNG8vxKuOT4I2mD+Ya70KPceF4IAmDsmU0h1Qsn5bPrvsY9HJstCRh3hG6Uw==} + vite@8.0.12: + resolution: {integrity: sha512-w2dDofOWv2QB09ZITZBsvKTVAlYvPR4IAmrY/v0ir9KvLs0xybR7i48wxhM1/oyBWO34wPns+bPGw5ZrZqDpZg==} engines: {node: ^20.19.0 || >=22.12.0} hasBin: true peerDependencies: '@types/node': ^20.19.0 || >=22.12.0 - '@vitejs/devtools': ^0.1.0 + '@vitejs/devtools': ^0.1.18 esbuild: ^0.27.0 || ^0.28.0 jiti: '>=1.21.0' less: ^4.0.0 @@ -948,20 +968,20 @@ packages: yaml: optional: true - vitest@4.1.4: - resolution: {integrity: sha512-tFuJqTxKb8AvfyqMfnavXdzfy3h3sWZRWwfluGbkeR7n0HUev+FmNgZ8SDrRBTVrVCjgH5cA21qGbCffMNtWvg==} + vitest@4.1.6: + resolution: {integrity: sha512-6lvjbS3p9b4CrdCmguzbh2/4uoXhGE2q71R4OX5sqF9R1bo9Xd6fGrMAfvp5wnCzlBnFVdCOp6onuTQVbo8iUQ==} engines: {node: ^20.0.0 || ^22.0.0 || >=24.0.0} hasBin: true peerDependencies: '@edge-runtime/vm': '*' '@opentelemetry/api': ^1.9.0 '@types/node': ^20.0.0 || ^22.0.0 || >=24.0.0 - '@vitest/browser-playwright': 4.1.4 - '@vitest/browser-preview': 4.1.4 - '@vitest/browser-webdriverio': 4.1.4 - '@vitest/coverage-istanbul': 4.1.4 - '@vitest/coverage-v8': 4.1.4 - '@vitest/ui': 4.1.4 + '@vitest/browser-playwright': 4.1.6 + '@vitest/browser-preview': 4.1.6 + '@vitest/browser-webdriverio': 4.1.6 + '@vitest/coverage-istanbul': 4.1.6 + '@vitest/coverage-v8': 4.1.6 + '@vitest/ui': 4.1.6 happy-dom: '*' jsdom: '*' vite: ^6.0.0 || ^7.0.0 || ^8.0.0 @@ -993,12 +1013,12 @@ packages: resolution: {integrity: sha512-Zn5uXdcFNIA1+1Ei5McRd+iRzfhENPCe7LeABkJtNulSxjma+l7ltNx55BWZkRlwRnpOgHqxnjyaDgJnNXnqzg==} engines: {node: '>=10.13.0'} - webpack-sources@3.3.4: - resolution: {integrity: sha512-7tP1PdV4vF+lYPnkMR0jMY5/la2ub5Fc/8VQrrU+lXkiM6C4TjVfGw7iKfyhnTQOsD+6Q/iKw0eFciziRgD58Q==} + webpack-sources@3.4.1: + resolution: {integrity: sha512-eACpxRN02yaawnt+uUNIF7Qje6A9zArxBbcAJjK1PK3S9Ycg5jIuJ8pW4q8EMnwNZCEGltcjkRx1QzOxOkKD8A==} engines: {node: '>=10.13.0'} - webpack@5.106.0: - resolution: {integrity: sha512-Pkx5joZ9RrdgO5LBkyX1L2ZAJeK/Taz3vqZ9CbcP0wS5LEMx5QkKsEwLl29QJfihZ+DKRBFldzy1O30pJ1MDpA==} + webpack@5.106.2: + resolution: {integrity: sha512-wGN3qcrBQIFmQ/c0AiOAQBvrZ5lmY8vbbMv4Mxfgzqd/B6+9pXtLo73WuS1dSGXM5QYY3hZnIbvx+K1xxe6FyA==} engines: {node: '>=10.13.0'} hasBin: true peerDependencies: @@ -1081,13 +1101,13 @@ snapshots: dependencies: statuses: 2.0.2 - '@emnapi/core@1.9.2': + '@emnapi/core@1.10.0': dependencies: '@emnapi/wasi-threads': 1.2.1 tslib: 2.8.1 optional: true - '@emnapi/runtime@1.9.2': + '@emnapi/runtime@1.10.0': dependencies: tslib: 2.8.1 optional: true @@ -1099,31 +1119,31 @@ snapshots: '@inquirer/ansi@1.0.2': {} - '@inquirer/confirm@5.1.21(@types/node@18.19.130)': + '@inquirer/confirm@5.1.21(@types/node@20.19.41)': dependencies: - '@inquirer/core': 10.3.2(@types/node@18.19.130) - '@inquirer/type': 3.0.10(@types/node@18.19.130) + '@inquirer/core': 10.3.2(@types/node@20.19.41) + '@inquirer/type': 3.0.10(@types/node@20.19.41) optionalDependencies: - '@types/node': 18.19.130 + '@types/node': 20.19.41 - '@inquirer/core@10.3.2(@types/node@18.19.130)': + '@inquirer/core@10.3.2(@types/node@20.19.41)': dependencies: '@inquirer/ansi': 1.0.2 '@inquirer/figures': 1.0.15 - '@inquirer/type': 3.0.10(@types/node@18.19.130) + '@inquirer/type': 3.0.10(@types/node@20.19.41) cli-width: 4.1.0 mute-stream: 2.0.0 signal-exit: 4.1.0 wrap-ansi: 6.2.0 yoctocolors-cjs: 2.1.3 optionalDependencies: - '@types/node': 18.19.130 + '@types/node': 20.19.41 '@inquirer/figures@1.0.15': {} - '@inquirer/type@3.0.10(@types/node@18.19.130)': + '@inquirer/type@3.0.10(@types/node@20.19.41)': optionalDependencies: - '@types/node': 18.19.130 + '@types/node': 20.19.41 '@jridgewell/gen-mapping@0.3.13': dependencies: @@ -1153,11 +1173,11 @@ snapshots: outvariant: 1.4.3 strict-event-emitter: 0.5.1 - '@napi-rs/wasm-runtime@1.1.3(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)': + '@napi-rs/wasm-runtime@1.1.4(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)': dependencies: - '@emnapi/core': 1.9.2 - '@emnapi/runtime': 1.9.2 - '@tybys/wasm-util': 0.10.1 + '@emnapi/core': 1.10.0 + '@emnapi/runtime': 1.10.0 + '@tybys/wasm-util': 0.10.2 optional: true '@open-draft/deferred-promise@2.2.0': {} @@ -1169,62 +1189,62 @@ snapshots: '@open-draft/until@2.1.0': {} - '@oxc-project/types@0.124.0': {} + '@oxc-project/types@0.129.0': {} - '@rolldown/binding-android-arm64@1.0.0-rc.15': + '@rolldown/binding-android-arm64@1.0.0': optional: true - '@rolldown/binding-darwin-arm64@1.0.0-rc.15': + '@rolldown/binding-darwin-arm64@1.0.0': optional: true - '@rolldown/binding-darwin-x64@1.0.0-rc.15': + '@rolldown/binding-darwin-x64@1.0.0': optional: true - '@rolldown/binding-freebsd-x64@1.0.0-rc.15': + '@rolldown/binding-freebsd-x64@1.0.0': optional: true - '@rolldown/binding-linux-arm-gnueabihf@1.0.0-rc.15': + '@rolldown/binding-linux-arm-gnueabihf@1.0.0': optional: true - '@rolldown/binding-linux-arm64-gnu@1.0.0-rc.15': + '@rolldown/binding-linux-arm64-gnu@1.0.0': optional: true - '@rolldown/binding-linux-arm64-musl@1.0.0-rc.15': + '@rolldown/binding-linux-arm64-musl@1.0.0': optional: true - '@rolldown/binding-linux-ppc64-gnu@1.0.0-rc.15': + '@rolldown/binding-linux-ppc64-gnu@1.0.0': optional: true - '@rolldown/binding-linux-s390x-gnu@1.0.0-rc.15': + '@rolldown/binding-linux-s390x-gnu@1.0.0': optional: true - '@rolldown/binding-linux-x64-gnu@1.0.0-rc.15': + '@rolldown/binding-linux-x64-gnu@1.0.0': optional: true - '@rolldown/binding-linux-x64-musl@1.0.0-rc.15': + '@rolldown/binding-linux-x64-musl@1.0.0': optional: true - '@rolldown/binding-openharmony-arm64@1.0.0-rc.15': + '@rolldown/binding-openharmony-arm64@1.0.0': optional: true - '@rolldown/binding-wasm32-wasi@1.0.0-rc.15': + '@rolldown/binding-wasm32-wasi@1.0.0': dependencies: - '@emnapi/core': 1.9.2 - '@emnapi/runtime': 1.9.2 - '@napi-rs/wasm-runtime': 1.1.3(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2) + '@emnapi/core': 1.10.0 + '@emnapi/runtime': 1.10.0 + '@napi-rs/wasm-runtime': 1.1.4(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0) optional: true - '@rolldown/binding-win32-arm64-msvc@1.0.0-rc.15': + '@rolldown/binding-win32-arm64-msvc@1.0.0': optional: true - '@rolldown/binding-win32-x64-msvc@1.0.0-rc.15': + '@rolldown/binding-win32-x64-msvc@1.0.0': optional: true - '@rolldown/pluginutils@1.0.0-rc.15': {} + '@rolldown/pluginutils@1.0.0': {} '@standard-schema/spec@1.1.0': {} - '@tybys/wasm-util@0.10.1': + '@tybys/wasm-util@0.10.2': dependencies: tslib: 2.8.1 optional: true @@ -1241,62 +1261,62 @@ snapshots: '@types/eslint-scope@3.7.7': dependencies: '@types/eslint': 9.6.1 - '@types/estree': 1.0.8 + '@types/estree': 1.0.9 '@types/eslint@9.6.1': dependencies: - '@types/estree': 1.0.8 + '@types/estree': 1.0.9 '@types/json-schema': 7.0.15 - '@types/estree@1.0.8': {} + '@types/estree@1.0.9': {} '@types/json-schema@7.0.15': {} - '@types/node@18.19.130': + '@types/node@20.19.41': dependencies: - undici-types: 5.26.5 + undici-types: 6.21.0 '@types/statuses@2.0.6': {} - '@vitest/expect@4.1.4': + '@vitest/expect@4.1.6': dependencies: '@standard-schema/spec': 1.1.0 '@types/chai': 5.2.3 - '@vitest/spy': 4.1.4 - '@vitest/utils': 4.1.4 + '@vitest/spy': 4.1.6 + '@vitest/utils': 4.1.6 chai: 6.2.2 tinyrainbow: 3.1.0 - '@vitest/mocker@4.1.4(msw@2.11.2(@types/node@18.19.130)(typescript@5.9.3))(vite@8.0.8(@types/node@18.19.130)(terser@5.46.1))': + '@vitest/mocker@4.1.6(msw@2.11.2(@types/node@20.19.41)(typescript@5.9.3))(vite@8.0.12(@types/node@20.19.41)(terser@5.47.1))': dependencies: - '@vitest/spy': 4.1.4 + '@vitest/spy': 4.1.6 estree-walker: 3.0.3 magic-string: 0.30.21 optionalDependencies: - msw: 2.11.2(@types/node@18.19.130)(typescript@5.9.3) - vite: 8.0.8(@types/node@18.19.130)(terser@5.46.1) + msw: 2.11.2(@types/node@20.19.41)(typescript@5.9.3) + vite: 8.0.12(@types/node@20.19.41)(terser@5.47.1) - '@vitest/pretty-format@4.1.4': + '@vitest/pretty-format@4.1.6': dependencies: tinyrainbow: 3.1.0 - '@vitest/runner@4.1.4': + '@vitest/runner@4.1.6': dependencies: - '@vitest/utils': 4.1.4 + '@vitest/utils': 4.1.6 pathe: 2.0.3 - '@vitest/snapshot@4.1.4': + '@vitest/snapshot@4.1.6': dependencies: - '@vitest/pretty-format': 4.1.4 - '@vitest/utils': 4.1.4 + '@vitest/pretty-format': 4.1.6 + '@vitest/utils': 4.1.6 magic-string: 0.30.21 pathe: 2.0.3 - '@vitest/spy@4.1.4': {} + '@vitest/spy@4.1.6': {} - '@vitest/utils@4.1.4': + '@vitest/utils@4.1.6': dependencies: - '@vitest/pretty-format': 4.1.4 + '@vitest/pretty-format': 4.1.6 convert-source-map: 2.0.0 tinyrainbow: 3.1.0 @@ -1386,19 +1406,19 @@ snapshots: acorn@8.16.0: {} - ajv-formats@2.1.1(ajv@8.18.0): + ajv-formats@2.1.1(ajv@8.20.0): optionalDependencies: - ajv: 8.18.0 + ajv: 8.20.0 - ajv-keywords@5.1.0(ajv@8.18.0): + ajv-keywords@5.1.0(ajv@8.20.0): dependencies: - ajv: 8.18.0 + ajv: 8.20.0 fast-deep-equal: 3.1.3 - ajv@8.18.0: + ajv@8.20.0: dependencies: fast-deep-equal: 3.1.3 - fast-uri: 3.1.0 + fast-uri: 3.1.2 json-schema-traverse: 1.0.0 require-from-string: 2.0.2 @@ -1410,7 +1430,7 @@ snapshots: assertion-error@2.0.1: {} - baseline-browser-mapping@2.10.17: {} + baseline-browser-mapping@2.10.29: {} braces@3.0.3: dependencies: @@ -1418,15 +1438,15 @@ snapshots: browserslist@4.28.2: dependencies: - baseline-browser-mapping: 2.10.17 - caniuse-lite: 1.0.30001787 - electron-to-chromium: 1.5.334 - node-releases: 2.0.37 + baseline-browser-mapping: 2.10.29 + caniuse-lite: 1.0.30001792 + electron-to-chromium: 1.5.353 + node-releases: 2.0.44 update-browserslist-db: 1.2.3(browserslist@4.28.2) buffer-from@1.1.2: {} - caniuse-lite@1.0.30001787: {} + caniuse-lite@1.0.30001792: {} chai@6.2.2: {} @@ -1459,16 +1479,16 @@ snapshots: detect-libc@2.1.2: {} - electron-to-chromium@1.5.334: {} + electron-to-chromium@1.5.353: {} emoji-regex@8.0.0: {} - enhanced-resolve@5.20.1: + enhanced-resolve@5.21.3: dependencies: graceful-fs: 4.2.11 - tapable: 2.3.2 + tapable: 2.3.3 - es-module-lexer@2.0.0: {} + es-module-lexer@2.1.0: {} escalade@3.2.0: {} @@ -1487,7 +1507,7 @@ snapshots: estree-walker@3.0.3: dependencies: - '@types/estree': 1.0.8 + '@types/estree': 1.0.9 events@3.3.0: {} @@ -1495,7 +1515,7 @@ snapshots: fast-deep-equal@3.1.3: {} - fast-uri@3.1.0: {} + fast-uri@3.1.2: {} fdir@6.5.0(picomatch@4.0.4): optionalDependencies: @@ -1514,7 +1534,7 @@ snapshots: graceful-fs@4.2.11: {} - graphql@16.13.2: {} + graphql@16.14.0: {} has-flag@4.0.0: {} @@ -1528,12 +1548,10 @@ snapshots: jest-worker@27.5.1: dependencies: - '@types/node': 18.19.130 + '@types/node': 20.19.41 merge-stream: 2.0.0 supports-color: 8.1.1 - json-parse-even-better-errors@2.3.1: {} - json-schema-traverse@1.0.0: {} lightningcss-android-arm64@1.32.0: @@ -1585,7 +1603,7 @@ snapshots: lightningcss-win32-arm64-msvc: 1.32.0 lightningcss-win32-x64-msvc: 1.32.0 - loader-runner@4.3.1: {} + loader-runner@4.3.2: {} magic-string@0.30.21: dependencies: @@ -1598,23 +1616,19 @@ snapshots: braces: 3.0.3 picomatch: 2.3.2 - mime-db@1.52.0: {} - - mime-types@2.1.35: - dependencies: - mime-db: 1.52.0 + mime-db@1.54.0: {} - msw@2.11.2(@types/node@18.19.130)(typescript@5.9.3): + msw@2.11.2(@types/node@20.19.41)(typescript@5.9.3): dependencies: '@bundled-es-modules/cookie': 2.0.1 '@bundled-es-modules/statuses': 1.0.1 - '@inquirer/confirm': 5.1.21(@types/node@18.19.130) + '@inquirer/confirm': 5.1.21(@types/node@20.19.41) '@mswjs/interceptors': 0.39.8 '@open-draft/deferred-promise': 2.2.0 '@open-draft/until': 2.1.0 '@types/cookie': 0.6.0 '@types/statuses': 2.0.6 - graphql: 16.13.2 + graphql: 16.14.0 headers-polyfill: 4.0.3 is-node-process: 1.2.0 outvariant: 1.4.3 @@ -1632,11 +1646,11 @@ snapshots: mute-stream@2.0.0: {} - nanoid@3.3.11: {} + nanoid@3.3.12: {} neo-async@2.6.2: {} - node-releases@2.0.37: {} + node-releases@2.0.44: {} obug@2.1.1: {} @@ -1652,9 +1666,9 @@ snapshots: picomatch@4.0.4: {} - postcss@8.5.9: + postcss@8.5.14: dependencies: - nanoid: 3.3.11 + nanoid: 3.3.12 picocolors: 1.1.1 source-map-js: 1.2.1 @@ -1664,35 +1678,35 @@ snapshots: rettime@0.7.0: {} - rolldown@1.0.0-rc.15: + rolldown@1.0.0: dependencies: - '@oxc-project/types': 0.124.0 - '@rolldown/pluginutils': 1.0.0-rc.15 + '@oxc-project/types': 0.129.0 + '@rolldown/pluginutils': 1.0.0 optionalDependencies: - '@rolldown/binding-android-arm64': 1.0.0-rc.15 - '@rolldown/binding-darwin-arm64': 1.0.0-rc.15 - '@rolldown/binding-darwin-x64': 1.0.0-rc.15 - '@rolldown/binding-freebsd-x64': 1.0.0-rc.15 - '@rolldown/binding-linux-arm-gnueabihf': 1.0.0-rc.15 - '@rolldown/binding-linux-arm64-gnu': 1.0.0-rc.15 - '@rolldown/binding-linux-arm64-musl': 1.0.0-rc.15 - '@rolldown/binding-linux-ppc64-gnu': 1.0.0-rc.15 - '@rolldown/binding-linux-s390x-gnu': 1.0.0-rc.15 - '@rolldown/binding-linux-x64-gnu': 1.0.0-rc.15 - '@rolldown/binding-linux-x64-musl': 1.0.0-rc.15 - '@rolldown/binding-openharmony-arm64': 1.0.0-rc.15 - '@rolldown/binding-wasm32-wasi': 1.0.0-rc.15 - '@rolldown/binding-win32-arm64-msvc': 1.0.0-rc.15 - '@rolldown/binding-win32-x64-msvc': 1.0.0-rc.15 + '@rolldown/binding-android-arm64': 1.0.0 + '@rolldown/binding-darwin-arm64': 1.0.0 + '@rolldown/binding-darwin-x64': 1.0.0 + '@rolldown/binding-freebsd-x64': 1.0.0 + '@rolldown/binding-linux-arm-gnueabihf': 1.0.0 + '@rolldown/binding-linux-arm64-gnu': 1.0.0 + '@rolldown/binding-linux-arm64-musl': 1.0.0 + '@rolldown/binding-linux-ppc64-gnu': 1.0.0 + '@rolldown/binding-linux-s390x-gnu': 1.0.0 + '@rolldown/binding-linux-x64-gnu': 1.0.0 + '@rolldown/binding-linux-x64-musl': 1.0.0 + '@rolldown/binding-openharmony-arm64': 1.0.0 + '@rolldown/binding-wasm32-wasi': 1.0.0 + '@rolldown/binding-win32-arm64-msvc': 1.0.0 + '@rolldown/binding-win32-x64-msvc': 1.0.0 schema-utils@4.3.3: dependencies: '@types/json-schema': 7.0.15 - ajv: 8.18.0 - ajv-formats: 2.1.1(ajv@8.18.0) - ajv-keywords: 5.1.0(ajv@8.18.0) + ajv: 8.20.0 + ajv-formats: 2.1.1(ajv@8.20.0) + ajv-keywords: 5.1.0(ajv@8.20.0) - semver@7.7.4: {} + semver@7.8.0: {} siginfo@2.0.0: {} @@ -1713,7 +1727,7 @@ snapshots: statuses@2.0.2: {} - std-env@4.0.0: {} + std-env@4.1.0: {} strict-event-emitter@0.5.1: {} @@ -1735,17 +1749,17 @@ snapshots: dependencies: has-flag: 4.0.0 - tapable@2.3.2: {} + tapable@2.3.3: {} - terser-webpack-plugin@5.4.0(webpack@5.106.0): + terser-webpack-plugin@5.6.0(webpack@5.106.2): dependencies: '@jridgewell/trace-mapping': 0.3.31 jest-worker: 27.5.1 schema-utils: 4.3.3 - terser: 5.46.1 - webpack: 5.106.0 + terser: 5.47.1 + webpack: 5.106.2 - terser@5.46.1: + terser@5.47.1: dependencies: '@jridgewell/source-map': 0.3.11 acorn: 8.16.0 @@ -1754,7 +1768,7 @@ snapshots: tinybench@2.9.0: {} - tinyexec@1.1.1: {} + tinyexec@1.1.2: {} tinyglobby@0.2.16: dependencies: @@ -1763,11 +1777,11 @@ snapshots: tinyrainbow@3.1.0: {} - tldts-core@7.0.28: {} + tldts-core@7.0.30: {} - tldts@7.0.28: + tldts@7.0.30: dependencies: - tldts-core: 7.0.28 + tldts-core: 7.0.30 to-regex-range@5.0.1: dependencies: @@ -1775,17 +1789,17 @@ snapshots: tough-cookie@6.0.1: dependencies: - tldts: 7.0.28 + tldts: 7.0.30 - ts-loader@9.5.7(typescript@5.9.3)(webpack@5.106.0): + ts-loader@9.5.7(typescript@5.9.3)(webpack@5.106.2): dependencies: chalk: 4.1.2 - enhanced-resolve: 5.20.1 + enhanced-resolve: 5.21.3 micromatch: 4.0.8 - semver: 7.7.4 + semver: 7.8.0 source-map: 0.7.6 typescript: 5.9.3 - webpack: 5.106.0 + webpack: 5.106.2 tslib@2.8.1: optional: true @@ -1794,7 +1808,7 @@ snapshots: typescript@5.9.3: {} - undici-types@5.26.5: {} + undici-types@6.21.0: {} update-browserslist-db@1.2.3(browserslist@4.28.2): dependencies: @@ -1802,42 +1816,42 @@ snapshots: escalade: 3.2.0 picocolors: 1.1.1 - vite@8.0.8(@types/node@18.19.130)(terser@5.46.1): + vite@8.0.12(@types/node@20.19.41)(terser@5.47.1): dependencies: lightningcss: 1.32.0 picomatch: 4.0.4 - postcss: 8.5.9 - rolldown: 1.0.0-rc.15 + postcss: 8.5.14 + rolldown: 1.0.0 tinyglobby: 0.2.16 optionalDependencies: - '@types/node': 18.19.130 + '@types/node': 20.19.41 fsevents: 2.3.3 - terser: 5.46.1 - - vitest@4.1.4(@types/node@18.19.130)(msw@2.11.2(@types/node@18.19.130)(typescript@5.9.3))(vite@8.0.8(@types/node@18.19.130)(terser@5.46.1)): - dependencies: - '@vitest/expect': 4.1.4 - '@vitest/mocker': 4.1.4(msw@2.11.2(@types/node@18.19.130)(typescript@5.9.3))(vite@8.0.8(@types/node@18.19.130)(terser@5.46.1)) - '@vitest/pretty-format': 4.1.4 - '@vitest/runner': 4.1.4 - '@vitest/snapshot': 4.1.4 - '@vitest/spy': 4.1.4 - '@vitest/utils': 4.1.4 - es-module-lexer: 2.0.0 + terser: 5.47.1 + + vitest@4.1.6(@types/node@20.19.41)(msw@2.11.2(@types/node@20.19.41)(typescript@5.9.3))(vite@8.0.12(@types/node@20.19.41)(terser@5.47.1)): + dependencies: + '@vitest/expect': 4.1.6 + '@vitest/mocker': 4.1.6(msw@2.11.2(@types/node@20.19.41)(typescript@5.9.3))(vite@8.0.12(@types/node@20.19.41)(terser@5.47.1)) + '@vitest/pretty-format': 4.1.6 + '@vitest/runner': 4.1.6 + '@vitest/snapshot': 4.1.6 + '@vitest/spy': 4.1.6 + '@vitest/utils': 4.1.6 + es-module-lexer: 2.1.0 expect-type: 1.3.0 magic-string: 0.30.21 obug: 2.1.1 pathe: 2.0.3 picomatch: 4.0.4 - std-env: 4.0.0 + std-env: 4.1.0 tinybench: 2.9.0 - tinyexec: 1.1.1 + tinyexec: 1.1.2 tinyglobby: 0.2.16 tinyrainbow: 3.1.0 - vite: 8.0.8(@types/node@18.19.130)(terser@5.46.1) + vite: 8.0.12(@types/node@20.19.41)(terser@5.47.1) why-is-node-running: 2.3.0 optionalDependencies: - '@types/node': 18.19.130 + '@types/node': 20.19.41 transitivePeerDependencies: - msw @@ -1846,12 +1860,12 @@ snapshots: glob-to-regexp: 0.4.1 graceful-fs: 4.2.11 - webpack-sources@3.3.4: {} + webpack-sources@3.4.1: {} - webpack@5.106.0: + webpack@5.106.2: dependencies: '@types/eslint-scope': 3.7.7 - '@types/estree': 1.0.8 + '@types/estree': 1.0.9 '@types/json-schema': 7.0.15 '@webassemblyjs/ast': 1.14.1 '@webassemblyjs/wasm-edit': 1.14.1 @@ -1860,24 +1874,32 @@ snapshots: acorn-import-phases: 1.0.4(acorn@8.16.0) browserslist: 4.28.2 chrome-trace-event: 1.0.4 - enhanced-resolve: 5.20.1 - es-module-lexer: 2.0.0 + enhanced-resolve: 5.21.3 + es-module-lexer: 2.1.0 eslint-scope: 5.1.1 events: 3.3.0 glob-to-regexp: 0.4.1 graceful-fs: 4.2.11 - json-parse-even-better-errors: 2.3.1 - loader-runner: 4.3.1 - mime-types: 2.1.35 + loader-runner: 4.3.2 + mime-db: 1.54.0 neo-async: 2.6.2 schema-utils: 4.3.3 - tapable: 2.3.2 - terser-webpack-plugin: 5.4.0(webpack@5.106.0) + tapable: 2.3.3 + terser-webpack-plugin: 5.6.0(webpack@5.106.2) watchpack: 2.5.1 - webpack-sources: 3.3.4 + webpack-sources: 3.4.1 transitivePeerDependencies: + - '@minify-html/node' - '@swc/core' + - '@swc/css' + - '@swc/html' + - clean-css + - cssnano + - csso - esbuild + - html-minifier-terser + - lightningcss + - postcss - uglify-js why-is-node-running@2.3.0: diff --git a/reference.md b/reference.md index 0932e24..e0541dd 100644 --- a/reference.md +++ b/reference.md @@ -19,25 +19,22 @@ Retrieves details of your Brevo account. - Check plan details (type, credits, expiration) - Get relay information (for transactional emails) - Check Marketing Automation status -- View date/time preferences and account settings - Access organization and user identifiers **Key information returned:** - Complete account details (organization ID, user ID, company information) - Address and contact information - Plan configurations and credit allocations across different verticals -- Marketing Automation settings and tracker key +- Marketing Automation settings and tracker key (when enabled) - SMTP relay configuration for transactional emails -- Date/time preferences and account settings - Enterprise features availability status **Important considerations:** - Provides comprehensive account overview for billing and configuration management - Essential for understanding current plan limitations and feature availability -- Marketing Automation key required for advanced automation features -- Plan verticals show detailed breakdown across Marketing, Chat, and CRM categories +- Marketing Automation key is only returned when Marketing Automation is enabled on the account +- Plan verticals show detailed breakdown across Marketing, Chat, and CRM categories (only returned when plan verticals are available) - Relay configuration crucial for transactional email setup and deliverability -- Date/time preferences affect campaign scheduling and reporting displays - Enterprise status determines access to advanced features and sub-account management @@ -1261,6 +1258,20 @@ await client.masterAccount.getSubAccountDetails({
+#### 📝 Description + +
+
+ +
+
+ +Permanently deletes a sub-account from the corporate master account. Once deleted, all data associated with the sub-account organization is removed and cannot be recovered, so ensure the sub-account is no longer needed before proceeding. +
+
+
+
+ #### 🔌 Usage
@@ -1931,6 +1942,20 @@ await client.masterAccount.changeAdminUserPermissions({
+#### 📝 Description + +
+
+ +
+
+ +Retrieves the list of all users associated with your organization, including both active and pending invited users. Each user entry includes their email address, owner status, current invitation status, and feature access levels for marketing, CRM, and conversations. +
+
+
+
+ #### 🔌 Usage
@@ -1972,6 +1997,20 @@ await client.user.getInvitedUsersList();
+#### 📝 Description + +
+
+ +
+
+ +Revokes all permissions for an invited user in the organization, effectively removing their access to the platform. If the user''s plan change generated credit notes, they are returned in the response for billing reconciliation. +
+
+
+
+ #### 🔌 Usage
@@ -2157,6 +2196,20 @@ await client.user.inviteuser({
+#### 📝 Description + +
+
+ +
+
+ +Resends or cancels a pending invitation for a user in the organization, depending on the action path parameter. Use `resend` to send a new invitation email to the user, or `cancel` to revoke the pending invitation entirely and remove the user''s pending access. +
+
+
+
+ #### 🔌 Usage
@@ -2342,6 +2395,20 @@ await client.user.editUserPermission({
+#### 📝 Description + +
+
+ +
+
+ +Retrieves the granular feature-level permissions assigned to a specific user in the organization, identified by their email address. The response includes the user''s current status (active or pending) and a detailed list of privileges specifying which features and permission levels are granted. +
+
+
+
+ #### 🔌 Usage
@@ -2412,20 +2479,19 @@ Retrieves a list of background processes from your Brevo account with filtering - Identify failed or stuck processes for troubleshooting **Key information returned:** -- Process details (ID, name, type, status) -- Process creation and completion timestamps -- Process progress and completion status -- Error information for failed processes -- Process result data and download links +- Process details (ID, name, status) +- Export download URLs for completed export processes +- Import details with CSV report URLs for completed import processes +- Total count of processes for pagination **Important considerations:** - Background processes handle long-running operations like imports and exports -- Process status indicates current state (queued, processing, completed, failed, cancelled) +- Process status indicates current state (queued, processing, completed) - Export processes provide download URLs when completed -- Failed processes include error messages for troubleshooting +- Import processes provide CSV report URLs with details about problematic records - Use pagination for accounts with many historical processes - Sort options available for creation order (ascending or descending) -- Different process types handle specific operations (imports, exports, calculations) +- Default limit is 10 results per page, maximum is 50
@@ -2498,18 +2564,14 @@ Retrieves detailed information about a specific background process. - Track process execution times **Key information returned:** -- Complete process details and status -- Import/export statistics and results -- Error information for troubleshooting -- Download URLs for export processes -- Process timing and performance data +- Complete process details (ID, name, status) +- Download URLs for completed export processes +- Import details with CSV report URLs for completed import processes **Important considerations:** -- Process ID must exist in your account -- Completed processes provide detailed statistics and results -- Export processes include download URLs when successful -- Failed processes contain error messages for debugging -- Timing information helps with performance analysis +- Process ID must exist in your account and not be deleted +- Completed export processes include download URLs +- Completed import processes include CSV report URLs with details about problematic records - Different process types return different result structures
@@ -3588,7 +3650,6 @@ Key information returned: ```typescript await client.webhooks.createWebhook({ - events: ["sent"], url: "http://requestb.in/173lyyx1" }); @@ -4377,24 +4438,51 @@ await client.externalFeeds.deleteExternalFeed({ Custom objects are only available to Enterprise plans. This feature is in beta. These are subject to change. -This API allows bulk upsert of object records in a single request. Each object record may include - - Attributes - - Identifiers - - Associations -**Response:** - The API processes the request asynchronously and returns a processId that you can use to track the background process status. -**API and Schema Limitation:** - - Size: - - Max 1000 objects records per request - - Max request body size: 1 MB - - Max 500 attributes defined per object record upsert request - - This is coherent with schema limitation: an object cannot have more than 500 attributes. - - Worth noting: Nothing happens If an attribute is mentioned in the request, but was not previously defined for the object schema (no error, no attribute creation) - - Max 10 associations defined per associated object type, in each record of the request - - This is not a schema limitation. You can associate an object record to an unlimited number of other object records by running multiple requests. +Performs bulk create or update (upsert) operations for object records in a single asynchronous request. This endpoint is optimized for high-volume data imports and synchronization scenarios. + +**How Upsert Works:** +- **Create**: Omit `identifiers`, or provide only `ext_id` (if it doesn't already exist). A new record is created with a Brevo-generated `id`. +- **Update**: Provide `id` (Brevo internal ID) or an `ext_id` that already exists. The matching record is updated with the new attribute values. +- **Important:** `id` is for **updates only**. Providing an `id` that does not belong to an existing record will fail during async processing (the HTTP response will still be 202, but the record will be rejected in the background). To create a new record with a stable external reference, use `ext_id` instead. + +**Request Structure:** +Each object record in the `records` array can include: +- `identifiers`: Either `id` (internal Brevo ID) or `ext_id` (your external system ID) — required for updates. **Note:** use `id` (singular), not `ids`. +- `attributes`: Key-value pairs where each key is the attribute **key** (e.g., `company_name`), not the attribute label (e.g., "Company Name"). +- `associations`: Controls linking and unlinking of associated records (optional). Each entry specifies: + - `object_type`: The type of the associated object + - `action`: `link` (default) to create the association, or `unlink` to remove it + - `records`: The associated records to link or unlink (each identified by `ext_id` or `id`) + - **Unlink is idempotent** — unlinking a non-existing association is a no-op (no error returned) + - `link` and `unlink` actions can be submitted for the same `object_type` in a single record entry + - Both associated records must already exist before a link can be created + +> **Common mistake:** Passing the attribute **label** (the display name you see in the UI) instead of the attribute **key** will cause the attribute to be silently ignored and the record may not be created as expected. + +**Asynchronous Processing:** +- Returns immediately with a `processId` (HTTP 202 Accepted) +- Use the processId to track status via the Get process API + +**API and Schema Limitations:** +- Max 1000 object records per request +- Max request body size: 1 MB +- Max 500 attributes per object record (matches the schema limit of 500 attributes per object) +- Unknown attribute keys are silently ignored (no error, no attribute creation) +- Max 10 association records per associated object-type in each record of the request. If you need more, send multiple requests. + +**Important Behaviors:** +- The object schema must be created before upserting records +- Unknown attribute keys are silently ignored (no error, no creation) +- Both associated object records must already exist before creating a link association +- Unlink operations are idempotent: attempting to unlink a non-existing association returns success +- `link` and `unlink` actions can be submitted for the same `object_type` in a single record entry +- Contact objects cannot be created via this endpoint +- For `category` and `multiple_category` attributes, pass the option **key** as the value (not the option label or option ID). +- The `id` identifier (internal Brevo ID) can only be used for **updating** existing records. To create new records, either omit identifiers (Brevo auto-generates an ID) or provide an `ext_id`. + **Errors:** - - Make sure both object records exist before associating them, else the API will return an error. - - This route does not create objects. The object where the object records are upserted by this API must be created already else the API will return an error "invalid object type". +- Make sure both object records exist before associating them, else the API will return an error. +- This route does not create objects. The object where the object records are upserted by this API must be created already else the API will return an error "invalid object type".
@@ -4411,7 +4499,34 @@ This API allows bulk upsert of object records in a single request. Each object r ```typescript await client.customObjects.upsertrecords({ object_type: "vehicle", - records: [{}] + records: [{ + associations: [{ + object_type: "garage", + action: "link", + records: [{ + identifiers: { + id: 435435 + } + }] + }, { + object_type: "garage", + action: "unlink", + records: [{ + identifiers: { + ext_id: "old-garage-001" + } + }] + }], + attributes: { + "make": "Toyota", + "model": "Camry", + "year": 2020, + "engine_type": "hybrid" + }, + identifiers: { + ext_id: "VIN123" + } + }] }); ``` @@ -4530,8 +4645,8 @@ await client.customObjects.getrecords({
Use this endpoint to delete multiple object records of the same object-type in one request. -The request is accepted and processed asynchronously. You can track the status of the deletion process using the returned **processId**. -**API and Schema Limitations:** - Each request can contain up to **1000** object record identifiers - If more records must be deleted → send multiple batch requests +The request is accepted and processed asynchronously. You can track the status of the deletion process using the returned **processId**. +**Limitations:** - Each request can contain up to **1000** object record identifiers - Either `ids` or `ext_ids` must be provided, but **not both** in the same request - Deletion of Brevo standard object records is not supported via this endpoint - If more records must be deleted, send multiple batch requests
@@ -4592,6 +4707,20 @@ await client.customObjects.batchDeleteObjectRecords({
+#### 📝 Description + +
+
+ +
+
+ +Retrieve all contacts from your Brevo account with support for pagination, filtering, and sorting. Results default to 50 contacts per page (maximum 1000) sorted in descending order of creation, and can be filtered by modification date, creation date, contact IDs (up to 20), list IDs, segment ID, or contact attributes using the equals operator. Note that either listIds or segmentId can be passed but not both simultaneously. +
+
+
+
+ #### 🔌 Usage
@@ -4706,6 +4835,20 @@ await client.contacts.createContact();
+#### 📝 Description + +
+
+ +
+
+ +Retrieve all contact attributes defined in your Brevo account, grouped by category (normal, transactional, category, calculated, global). Each attribute includes its name, type, and category, along with enumeration values for category-type attributes and options for multiple-choice-type attributes. +
+
+
+
+ #### 🔌 Usage
@@ -4747,6 +4890,20 @@ await client.contacts.getAttributes();
+#### 📝 Description + +
+
+ +
+
+ +Create a new contact attribute under the specified category and name. The required body properties depend on the category: use "type" for normal, transactional, or category attributes; use "value" for calculated or global attributes; use "enumeration" for category attributes; and use "multiCategoryOptions" for normal multiple-choice attributes. None of the category or multicategory option values can exceed 200 characters. +
+
+
+
+ #### 🔌 Usage
@@ -4799,6 +4956,20 @@ await client.contacts.createAttribute({
+#### 📝 Description + +
+
+ +
+
+ +Update an existing contact attribute identified by its category and name. For category-type attributes, you can update the enumeration values; for calculated or global attributes, update the computed value formula; and for normal multiple-choice attributes, update the multicategory options. None of the category or multicategory option values can exceed 200 characters. +
+
+
+
+ #### 🔌 Usage
@@ -4851,6 +5022,20 @@ await client.contacts.updateAttribute({
+#### 📝 Description + +
+
+ +
+
+ +Permanently delete an existing contact attribute by its category and name. The attribute must exist in the specified category (normal, transactional, category, calculated, or global), otherwise a 404 error is returned. +
+
+
+
+ #### 🔌 Usage
@@ -4903,6 +5088,20 @@ await client.contacts.deleteAttribute({
+#### 📝 Description + +
+
+ +
+
+ +Delete a specific option from an existing multiple-choice contact attribute. The attribute type must be "multiple-choice", and both the attribute name and the option to delete must already exist in your account. +
+
+
+
+ #### 🔌 Usage
@@ -4956,6 +5155,20 @@ await client.contacts.deleteMultiAttributeOptions({
+#### 📝 Description + +
+
+ +
+
+ +Update multiple contacts in a single API call by passing an array of contact objects. Each contact in the array must be identified by one of: email, id, or sms (only one identifier per contact). You can update attributes, blacklist status, list memberships, ext_id, and transactional email forbidden senders for each contact in the batch. +
+
+
+
+ #### 🔌 Usage
@@ -5205,6 +5418,20 @@ await client.contacts.getFolders();
+#### 📝 Description + +
+
+ +
+
+ +Create a new folder to organize your contact lists. Folders serve as containers for grouping related lists together. The folder name is required and must be provided in the request body. +
+
+
+
+ #### 🔌 Usage
@@ -5321,6 +5548,20 @@ await client.contacts.getFolder({
+#### 📝 Description + +
+
+ +
+
+ +Update the name of an existing folder identified by its ID. The new folder name must be provided in the request body. Returns a 404 error if the folder ID does not exist. +
+
+
+
+ #### 🔌 Usage
@@ -5373,6 +5614,20 @@ await client.contacts.updateFolder({
+#### 📝 Description + +
+
+ +
+
+ +Permanently delete a folder identified by its ID. Deleting a folder will also delete all the contact lists contained within it. This action cannot be undone. +
+
+
+
+ #### 🔌 Usage
@@ -5619,6 +5874,20 @@ await client.contacts.getLists();
+#### 📝 Description + +
+
+ +
+
+ +Create a new contact list inside a specified folder. Both the list name and the parent folder ID are required. The newly created list will be empty and ready to receive contacts via the add contacts endpoint. +
+
+
+
+ #### 🔌 Usage
@@ -5671,6 +5940,20 @@ await client.contacts.createList({
+#### 📝 Description + +
+
+ +
+
+ +Retrieve the details of a specific contact list by its ID, including its name, folder ID, creation date, subscriber counts, and campaign statistics. You can optionally filter campaign statistics by providing startDate and endDate parameters (both must be used together in YYYY-MM-DD format). +
+
+
+
+ #### 🔌 Usage
@@ -5722,6 +6005,20 @@ await client.contacts.getList({
+#### 📝 Description + +
+
+ +
+
+ +Update an existing contact list identified by its ID. You can update the list name, move it to a different folder by providing a new folderId, or both. Only one of the two parameters (name, folderId) needs to be provided per request. +
+
+
+
+ #### 🔌 Usage
@@ -5773,6 +6070,20 @@ await client.contacts.updateList({
+#### 📝 Description + +
+
+ +
+
+ +Permanently delete a contact list identified by its ID. The contacts in the list are not deleted; they are only removed from this list. Returns a 404 error if the list ID does not exist. +
+
+
+
+ #### 🔌 Usage
@@ -5824,7 +6135,7 @@ await client.contacts.deleteList({
-#### 🔌 Usage +#### 📝 Description
@@ -5832,10 +6143,24 @@ await client.contacts.deleteList({
-```typescript -await client.contacts.getContactsFromList({ - listId: 1000000 -}); +Retrieve all contacts belonging to a specific list, identified by its list ID. Results are paginated with a default of 50 contacts per page (maximum 500) and sorted in descending order of creation. You can optionally filter contacts by their modification date using the modifiedSince parameter. +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```typescript +await client.contacts.getContactsFromList({ + listId: 1000000 +}); ```
@@ -5983,6 +6308,20 @@ await client.contacts.removeContactFromList({
+#### 📝 Description + +
+
+ +
+
+ +Retrieve all contact segments defined in your Brevo account with support for pagination and sorting. Results default to 10 segments per page (maximum 50) sorted in descending order of creation. Each segment includes its ID, name, category name, and last update timestamp. +
+
+
+
+ #### 🔌 Usage
@@ -6231,6 +6570,20 @@ await client.contacts.deleteContact({
+#### 📝 Description + +
+
+ +
+
+ +Retrieve email campaign statistics for a specific contact identified by email address or numeric ID. Statistics include messages sent, opens, clicks, hard/soft bounces, deliveries, unsubscriptions, complaints, and transactional attributes. By default, data covers the last 90 days; use startDate and endDate parameters (YYYY-MM-DD) to specify a custom range with a maximum span of 90 days. +
+
+
+
+ #### 🔌 Usage
@@ -6291,7 +6644,7 @@ await client.contacts.getContactStats({
-We recommend pinging this endpoint every minute for as long as the agent has to be considered online. +Sets the agent's status to online for 2-3 minutes. We recommend pinging this endpoint every minute for as long as the agent has to be considered online. You must provide either `agentId` alone, or all three of `agentEmail` + `agentName` + `receivedFrom`.
@@ -6348,6 +6701,20 @@ await client.conversations.setsAgentsStatusToOnlineFor23Minutes({
+#### 📝 Description + +
+
+ +
+
+ +Send a message as an agent to an existing visitor's conversation. You must provide either `agentId` alone, or all three of `agentEmail` + `agentName` + `receivedFrom` to identify the agent. +
+
+
+
+ #### 🔌 Usage
@@ -6401,6 +6768,20 @@ await client.conversations.sendAMessageAsAnAgent({
+#### 📝 Description + +
+
+ +
+
+ +Retrieve a single message by its ID. +
+
+
+
+ #### 🔌 Usage
@@ -6460,7 +6841,7 @@ await client.conversations.getAMessage({
-Only agents’ messages can be edited. +Update the text of a message sent by an agent. Only messages of type `agent` can be edited. The `text` and `html` fields of the message will be updated.
@@ -6526,7 +6907,7 @@ await client.conversations.updateAMessageSentByAnAgent({
-Only agents’ messages can be deleted. +Delete a message sent by an agent. Only messages of type `agent` can be deleted.
@@ -6591,7 +6972,7 @@ await client.conversations.deleteAMessageSentByAnAgent({
-Example of automated messages: order status, announce new features in your web app, etc. +Send an automated (pushed) message to a visitor on behalf of an agent. Example use cases: order status updates, announcing new features in your web app, etc.
@@ -6608,7 +6989,7 @@ Example of automated messages: order status, announce new features in your web a ```typescript await client.conversations.sendAnAutomatedMessageToAVisitor({ groupId: "PjRBMhWGen6aRHjif", - text: "Your order has shipped! Here\u2019s your tracking number: 9114 5847 3325 9667 4328 88", + text: "Your order has shipped! Here's your tracking number: 9114 5847 3325 9667 4328 88", visitorId: "kZMvWhf8npAu3H6qd57w2Hv6nh6rnxvg" }); @@ -6650,6 +7031,20 @@ await client.conversations.sendAnAutomatedMessageToAVisitor({
+#### 📝 Description + +
+
+ +
+
+ +Retrieve a single automated (pushed) message by its ID. +
+
+
+
+ #### 🔌 Usage
@@ -6701,6 +7096,20 @@ await client.conversations.getAnAutomatedMessage({
+#### 📝 Description + +
+
+ +
+
+ +Update the text of an automated (pushed) message. The `text` and `html` fields of the message will be updated. +
+
+
+
+ #### 🔌 Usage
@@ -6712,7 +7121,7 @@ await client.conversations.getAnAutomatedMessage({ ```typescript await client.conversations.updateAnAutomatedMessage({ id: "id", - text: "Your order has shipped! Here\u2019s your tracking number: 9114 5847 4668 7775 9233 54" + text: "Your order has shipped! Here's your tracking number: 9114 5847 4668 7775 9233 54" }); ``` @@ -6753,6 +7162,20 @@ await client.conversations.updateAnAutomatedMessage({
+#### 📝 Description + +
+
+ +
+
+ +Delete an automated (pushed) message by its ID. +
+
+
+
+ #### 🔌 Usage
@@ -6870,6 +7293,20 @@ await client.conversations.setVisitorGroupAssignment({
+#### 📝 Description + +
+
+ +
+
+ +Retrieve a paginated list of all ecommerce categories stored in your Brevo account. Results are sorted by creation date in descending order by default, and can be filtered by category IDs, name, modification date, creation date, or deletion status. The response includes a `count` field with the total number of matching categories, and pagination defaults to 50 categories per page (maximum 100). +
+
+
+
+ #### 🔌 Usage
@@ -6919,6 +7356,20 @@ await client.ecommerce.getCategories();
+#### 📝 Description + +
+
+ +
+
+ +Create a new ecommerce category or update an existing one, identified by the mandatory `id` field. When `updateEnabled` is set to `false` (the default), the endpoint performs an insert and returns `201`; if the category ID already exists, a `400` error is returned. When `updateEnabled` is `true`, the endpoint performs an upsert, returning `201` for a new category or `204` when an existing category is updated. The `name` field is mandatory for creation but optional for updates. +
+
+
+
+ #### 🔌 Usage
@@ -6970,6 +7421,20 @@ await client.ecommerce.createUpdateCategory({
+#### 📝 Description + +
+
+ +
+
+ +Create or update multiple ecommerce categories in a single request. The `categories` array accepts up to 100 category objects, each requiring a unique `id`. When `updateEnabled` is `false` (the default), all categories are inserted as new; if any ID already exists, a `400` error is returned. When `updateEnabled` is `true`, existing categories are updated and new ones are created via upsert. Duplicate IDs within the same request payload are rejected. The response returns the count of created and updated categories. +
+
+
+
+ #### 🔌 Usage
@@ -7023,6 +7488,20 @@ await client.ecommerce.createUpdateBatchCategory({
+#### 📝 Description + +
+
+ +
+
+ +Retrieve the full details of a single ecommerce category by its unique ID. The response includes the category name, URL, creation and modification timestamps, and deletion status. Returns a `404` error if no category matches the provided ID. +
+
+
+
+ #### 🔌 Usage
@@ -7129,6 +7608,20 @@ await client.ecommerce.activateTheECommerceApp();
+#### 📝 Description + +
+
+ +
+
+ +Retrieve aggregated ecommerce attribution metrics for one or more Brevo email campaigns, SMS campaigns, or automation workflows. You can optionally filter by a date range using `periodFrom` and `periodTo` in RFC3339 format. The response includes per-source metrics (orders count, revenue, and average basket) as well as aggregated totals across all requested sources. +
+
+
+
+ #### 🔌 Usage
@@ -7140,7 +7633,8 @@ await client.ecommerce.activateTheECommerceApp(); ```typescript await client.ecommerce.getAttributionMetricsForOneOrMoreBrevoCampaignsOrWorkflows({ periodFrom: "2022-01-02T00:00:00Z", - periodTo: "2022-01-03T00:00:00Z" + periodTo: "2022-01-03T00:00:00Z", + "emailCampaignId[]": ["sale"] }); ``` @@ -7181,6 +7675,20 @@ await client.ecommerce.getAttributionMetricsForOneOrMoreBrevoCampaignsOrWorkflow
+#### 📝 Description + +
+
+ +
+
+ +Retrieve detailed attribution metrics for a single Brevo campaign or automation workflow, identified by its conversion source type and ID. The response includes orders count, revenue, average basket value, and the number of new customers attributed to that specific campaign or workflow. +
+
+
+
+ #### 🔌 Usage
@@ -7233,6 +7741,20 @@ await client.ecommerce.getDetailedAttributionMetricsForASingleBrevoCampaignOrWor
+#### 📝 Description + +
+
+ +
+
+ +Retrieve the list of products whose sales have been attributed to a specific Brevo campaign or automation workflow. Each product entry includes its ID, name, SKU, image URL, product URL, price, revenue, and orders count. The conversion source type must be one of `email_campaign`, `sms_campaign`, `automation_workflow_email`, or `automation_workflow_sms`. +
+
+
+
+ #### 🔌 Usage
@@ -7285,6 +7807,20 @@ await client.ecommerce.getAttributedProductSalesForASingleBrevoCampaignOrWorkflo
+#### 📝 Description + +
+
+ +
+
+ +Retrieve the ISO 4217 display currency code currently configured for your Brevo ecommerce account. This currency is used to display monetary values across the ecommerce dashboard and reports. Returns a `403` error if ecommerce is not activated on the account. +
+
+
+
+ #### 🔌 Usage
@@ -7326,6 +7862,20 @@ await client.ecommerce.getTheIso4217CompliantDisplayCurrencyCodeForYourBrevoAcco
+#### 📝 Description + +
+
+ +
+
+ +Set or update the ISO 4217 display currency code for your Brevo ecommerce account. This currency determines how monetary values are displayed in the ecommerce dashboard and reports. The provided currency code must be a valid ISO 4217 code; invalid codes result in a `422` error. Returns a `403` error if ecommerce is not activated on the account. +
+
+
+
+ #### 🔌 Usage
@@ -7588,6 +8138,20 @@ await client.ecommerce.createBatchOrder({
+#### 📝 Description + +
+
+ +
+
+ +Retrieve a paginated list of all ecommerce products stored in your Brevo account. Results are sorted by creation date in descending order by default, and can be filtered by product IDs, name (minimum 3 characters), price range, category IDs, modification date, creation date, or deletion status. Use the `search` parameter to query across SKU, name, and ID simultaneously — results are prioritized as exact SKU match > SKU prefix match > name match > ID match. Pagination defaults to 50 products per page (maximum 1000), and the response includes a `count` field with the total number of matching products. +
+
+
+
+ #### 🔌 Usage
@@ -7637,6 +8201,20 @@ await client.ecommerce.getProducts();
+#### 📝 Description + +
+
+ +
+
+ +Create a new ecommerce product or update an existing one, identified by the mandatory `id` field. When `updateEnabled` is `false` (the default), the endpoint inserts a new product and returns `201`; if the product ID already exists, a `400` error is returned. When `updateEnabled` is `true`, the endpoint performs an upsert, returning `201` for a new product or `204` for an update. The `name` field is mandatory for creation but optional for updates. Product images are downloaded, validated (max 5 MB, formats: jpeg, jpg, png, bmp, gif, webp), and re-hosted on S3. The `metaInfo` object supports up to 20 keys with a cumulative size limit of approximately 1000 KB. +
+
+
+
+ #### 🔌 Usage
@@ -7689,7 +8267,7 @@ await client.ecommerce.createUpdateProduct({
-#### 🔌 Usage +#### 📝 Description
@@ -7697,9 +8275,23 @@ await client.ecommerce.createUpdateProduct({
-```typescript -await client.ecommerce.createUpdateBatchProducts({ - products: [{ +Create or update multiple ecommerce products in a single request. The `products` array accepts up to 100 product objects for creation (or up to 1000 when `updateEnabled` is `true` and the account has an increased limit). Each product requires a unique `id` and `name` (name is mandatory for creation only). When `updateEnabled` is `false`, all products are inserted as new; if any ID already exists, a `400` error is returned. When `updateEnabled` is `true`, existing products are updated and new ones are created via upsert. Duplicate IDs within the same request payload are rejected. The response returns the count of created and updated products. +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```typescript +await client.ecommerce.createUpdateBatchProducts({ + products: [{ id: "P11", name: "Iphone 11" }] @@ -7743,6 +8335,20 @@ await client.ecommerce.createUpdateBatchProducts({
+#### 📝 Description + +
+
+ +
+
+ +Retrieve the full details of a single ecommerce product by its unique ID. The response includes the product name, price, SKU, URL, image URLs (original and thumbnails), categories, stock level, meta information, creation and modification timestamps, and deletion status. Returns a `404` error if no product matches the provided ID. +
+
+
+
+ #### 🔌 Usage
@@ -7794,6 +8400,20 @@ await client.ecommerce.getProductInfo({
+#### 📝 Description + +
+
+ +
+
+ +Register a contact to receive an alert for a specific product event, such as `back_in_stock`. At least one contact identifier (`ext_id`, `email`, or `sms`) must be provided; when multiple are given, priority is `ext_id` > `email` > `sms`. Returns a `404` error if the product ID does not exist, and a `403` error if product alerts are not enabled for the account. +
+
+
+
+ #### 🔌 Usage
@@ -7847,6 +8467,20 @@ await client.ecommerce.createProductAlert({
+#### 📝 Description + +
+
+ +
+
+ +Retrieve a paginated list of all coupon collections in your Brevo account. Results can be sorted by creation date, remaining coupons count, or expiration date, in ascending or descending order. Pagination defaults to 50 collections per page (maximum 100). +
+
+
+
+ #### 🔌 Usage
@@ -7896,6 +8530,20 @@ await client.coupons.getCouponCollections();
+#### 📝 Description + +
+
+ +
+
+ +Create a new coupon collection with a name and a default coupon value. You can optionally set an expiration date in RFC3339 format and configure alert thresholds to receive email notifications when remaining coupons or remaining days before expiration fall below a specified number. The collection ID is auto-generated as a UUID and returned in the response. +
+
+
+
+ #### 🔌 Usage
@@ -7948,6 +8596,20 @@ await client.coupons.createCouponCollection({
+#### 📝 Description + +
+
+ +
+
+ +Retrieve the details of a single coupon collection by its UUID. The response includes the collection name, default coupon value, total and remaining coupon counts, and creation timestamp. Returns a `404` error if no collection matches the provided ID. +
+
+
+
+ #### 🔌 Usage
@@ -7999,6 +8661,20 @@ await client.coupons.getCouponCollection({
+#### 📝 Description + +
+
+ +
+
+ +Update an existing coupon collection by its UUID. You can modify the default coupon value, set or remove the expiration date (pass `null` to remove), and configure or disable alert thresholds for remaining coupons or remaining days. Only the fields included in the request body are updated; omitted fields remain unchanged. +
+
+
+
+ #### 🔌 Usage
@@ -8050,6 +8726,20 @@ await client.coupons.updateCouponCollection({
+#### 📝 Description + +
+
+ +
+
+ +Add coupons to an existing coupon collection. The `coupons` array must contain between 1 and 10,000 unique coupon code strings, all associated with the specified `collectionId`. Coupon creation is processed asynchronously and a `204` status is returned immediately upon acceptance. Returns a `404` error if the specified coupon collection does not exist. +
+
+
+
+ #### 🔌 Usage
@@ -8103,6 +8793,20 @@ await client.coupons.createCoupons({
+#### 📝 Description + +
+
+ +
+
+ +Create a new payment request for a Brevo contact. The request requires a reference (displayed on the payment page), a contact ID, and a cart with currency and amount in cents. You can optionally configure a custom success redirect URL and enable email notifications with reminders. Returns the payment request ID and its public payment URL. A `403` error is returned if Brevo Payments is not activated or the account is not validated. +
+
+
+
+ #### 🔌 Usage
@@ -8159,6 +8863,20 @@ await client.payments.createPaymentRequest({
+#### 📝 Description + +
+
+ +
+
+ +Retrieve the details of a specific payment request by its ID. The response includes the reference, status (created, sent, reminderSent, or paid), cart details, notification configuration, contact ID, and the number of reminders sent. Returns a `404` error if no payment request matches the provided ID. +
+
+
+
+ #### 🔌 Usage
@@ -8210,6 +8928,20 @@ await client.payments.getPaymentRequest({
+#### 📝 Description + +
+
+ +
+
+ +Delete a payment request by its UUID. Once deleted, the payment request can no longer be accessed or paid. Returns a `404` error if no payment request matches the provided ID, and a `403` error if Brevo Payments is not activated or the account is not validated. +
+
+
+
+ #### 🔌 Usage
@@ -8418,10 +9150,12 @@ Create multiple events to track contacts' interactions in a single request.
```typescript -await client.event.createBatchEvents([{ - event_name: "order_created", - identifiers: {} - }]); +await client.event.createBatchEvents({ + events: [{ + event_name: "order_created", + identifiers: {} + }] +}); ```
@@ -8437,7 +9171,7 @@ await client.event.createBatchEvents([{
-**request:** `Brevo.CreateBatchEventsRequestItem[]` +**request:** `Brevo.CreateBatchEventsRequest`
@@ -8470,7 +9204,7 @@ await client.event.createBatchEvents([{
-This endpoint will show the list of all the events for the received emails. +This endpoint will show the list of all the events for the received emails. When no date range is provided, the last 30 days of events are returned by default.
@@ -8652,7 +9386,7 @@ await client.inboundParsing.getInboundEmailAttachment({ ## Balance -
client.balance.getActiveBalancesApi({ ...params }) -> Brevo.BalanceLimit +
client.balance.getActiveBalancesApi({ ...params }) -> Brevo.GetLoyaltyBalanceProgramsPidActiveBalanceResponse
@@ -8681,8 +9415,8 @@ Returns Active Balances ```typescript await client.balance.getActiveBalancesApi({ pid: "pid", - contact_id: 1, - balance_definition_id: "balance_definition_id" + contactId: 1000000, + balanceDefinitionId: "balanceDefinitionId" }); ``` @@ -9340,7 +10074,7 @@ await client.balance.deleteBalanceLimit({
-Returns balance list +Returns contact balances for a given balance definition across all subscriptions.
@@ -9356,7 +10090,8 @@ Returns balance list ```typescript await client.balance.getContactBalances({ - pid: "pid" + pid: "pid", + balanceDefinitionId: "balanceDefinitionId" }); ``` @@ -9426,7 +10161,7 @@ await client.balance.createBalanceOrder({ balanceDefinitionId: "balanceDefinitionId", contactId: 1, dueAt: "dueAt", - source: "source" + source: "engine" }); ``` @@ -9625,7 +10360,7 @@ Returns transaction history ```typescript await client.balance.getTransactionHistoryApi({ pid: "pid", - contactId: 1, + contactId: 1000000, balanceDefinitionId: "balanceDefinitionId" }); @@ -10609,7 +11344,7 @@ Subscribes to a loyalty program ```typescript await client.program.subscribeToLoyaltyProgram({ pid: "pid", - contactId: 1 + contactId: 1000000 }); ``` @@ -11986,7 +12721,7 @@ await client.tier.deleteTier({
The response payload for this endpoint has changed -You now need to specify which type of statistics you would like to retrieve. For more information visit [this page](https://developers.brevo.com/changelog/get-all-marketing-campaigns). +You now need to specify which type of statistics you would like to retrieve. For more information visit [this page](https://developers.brevo.com/changelog/2023/2/7).
@@ -12041,6 +12776,20 @@ await client.emailCampaigns.getEmailCampaigns();
+#### 📝 Description + +
+
+ +
+
+ +Create a new email campaign. The campaign requires at minimum a name and sender details, and is created in draft status by default. You must provide email content via one of three mutually exclusive options: htmlContent (inline HTML), htmlUrl (remote URL), or templateId (existing template); additionally, A/B testing can be enabled by setting abTesting to true with subjectA and subjectB, but this is incompatible with sendAtBestTime. +
+
+
+
+ #### 🔌 Usage
@@ -12093,6 +12842,20 @@ await client.emailCampaigns.createEmailCampaign({
+#### 📝 Description + +
+
+ +
+
+ +Upload an image to your account''s image gallery by providing an absolute URL to the image. The maximum allowed image size is 2MB and supported formats are jpeg, jpg, png, bmp, and gif; local file uploads are not supported. +
+
+
+
+ #### 🔌 Usage
@@ -12144,6 +12907,20 @@ await client.emailCampaigns.uploadImageToGallery({
+#### 📝 Description + +
+
+ +
+
+ +Retrieve detailed information about a specific email campaign by its ID, including recipients, statistics, and HTML content. Use the statistics query parameter to select which statistics to include (globalStats, linksStats, statsByDomain, statsByDevice, or statsByBrowser); statsByDevice and statsByBrowser are only available on this single-campaign endpoint. You can exclude HTML content from the response by setting excludeHtmlContent to true. +
+
+
+
+ #### 🔌 Usage
@@ -12195,6 +12972,20 @@ await client.emailCampaigns.getEmailCampaign({
+#### 📝 Description + +
+
+ +
+
+ +Update an existing email campaign''s properties such as name, subject, content, sender, recipients, schedule, and A/B testing configuration. The campaign must exist and the request body must contain at least one valid field to update. Only draft or scheduled campaigns can be modified; if sendAtBestTime is enabled, IP warmup will be automatically disabled. +
+
+
+
+ #### 🔌 Usage
@@ -12246,6 +13037,20 @@ await client.emailCampaigns.updateEmailCampaign({
+#### 📝 Description + +
+
+ +
+
+ +Delete an email campaign by its campaign ID. Only campaigns that have not been scheduled can be deleted; attempting to delete a campaign that has already been scheduled will return a 403 permission denied error. Related data in templates, newsletter builder, and schedule collections is also cleaned up. +
+
+
+
+ #### 🔌 Usage
@@ -12362,6 +13167,20 @@ await client.emailCampaigns.getAbTestCampaignResult({
+#### 📝 Description + +
+
+ +
+
+ +Export the recipients of a sent email campaign as an asynchronous process, filtered by recipient type (e.g. openers, clickers, hardBounces). The recipientsType field is required and determines which subset of recipients to export. An optional notifyURL webhook will be called once the export is complete, and the response returns a processId to track the export status. +
+
+
+
+ #### 🔌 Usage
@@ -12414,6 +13233,20 @@ await client.emailCampaigns.emailExportRecipients({
+#### 📝 Description + +
+
+ +
+
+ +Send an existing email campaign immediately by scheduling it for the current time. The campaign must have valid recipients and content configured before sending. The system verifies your account''s send limit and credit balance before dispatching; if credits are insufficient, a 402 error is returned. +
+
+
+
+ #### 🔌 Usage
@@ -12536,7 +13369,7 @@ await client.emailCampaigns.sendReport({
-#### 🔌 Usage +#### 📝 Description
@@ -12544,19 +13377,33 @@ await client.emailCampaigns.sendReport({
-```typescript -await client.emailCampaigns.sendTestEmail({ - campaignId: 1000000, - body: {} -}); - -``` +Send a test version of an email campaign to specified email addresses or your entire test list. If the emailTo array is left empty, the test mail will be sent to all addresses in your test list. You can send a maximum of 50 test emails per day.
-#### ⚙️ Parameters +#### 🔌 Usage + +
+
+ +
+
+ +```typescript +await client.emailCampaigns.sendTestEmail({ + campaignId: 1000000, + body: {} +}); + +``` +
+
+
+
+ +#### ⚙️ Parameters
@@ -12653,6 +13500,20 @@ await client.emailCampaigns.getSharedTemplateUrl({
+#### 📝 Description + +
+
+ +
+
+ +Update the status of an email campaign, such as suspending, archiving, or replicating it. Available status values include suspended, archive, darchive, sent, queued, replicate, replicateTemplate, cancel, and draft. Note that the replicateTemplate status is only available for template type campaigns. +
+
+
+
+ #### 🔌 Usage
@@ -12706,6 +13567,20 @@ await client.emailCampaigns.updateCampaignStatus({
+#### 📝 Description + +
+
+ +
+
+ +Retrieve a paginated list of all your SMS campaigns with their statistics and recipient information. Results can be filtered by status and date range, with a default limit of 500 and maximum of 1000 per page. The sort order defaults to descending by creation date; date filters are only available when status is not passed or is set to sent. +
+
+
+
+ #### 🔌 Usage
@@ -12755,6 +13630,20 @@ await client.smsCampaigns.getSmsCampaigns();
+#### 📝 Description + +
+
+ +
+
+ +Create a new SMS campaign with the required name, sender, and content fields. The sender name is limited to 11 alphanumeric characters or 15 numeric characters, and the content should stay within 160 characters per SMS segment. If a scheduledAt date is provided, listIds in recipients become mandatory; accounts under validation are limited to 4 total campaigns and campaigns with more than 10 recipients will be saved as draft. +
+
+
+
+ #### 🔌 Usage
@@ -12808,6 +13697,20 @@ await client.smsCampaigns.createSmsCampaign({
+#### 📝 Description + +
+
+ +
+
+ +Retrieve detailed information about a specific SMS campaign by its ID, including campaign content, sender, recipients with list names, statistics (delivered, sent, bounces, unsubscriptions, answered), and tags. Unlike the list endpoint, recipients are returned as objects with id and name fields rather than plain IDs. +
+
+
+
+ #### 🔌 Usage
@@ -12859,6 +13762,20 @@ await client.smsCampaigns.getSmsCampaign({
+#### 📝 Description + +
+
+ +
+
+ +Update an existing SMS campaign''s properties such as name, sender, content, recipients, scheduled date, organisation prefix, and unsubscribe instructions. The request body must contain at least one valid field to update. The campaign must exist and must be of type SMS; if a scheduledAt is provided, valid recipients must be present either in the request or already configured on the campaign. +
+
+
+
+ #### 🔌 Usage
@@ -12910,6 +13827,20 @@ await client.smsCampaigns.updateSmsCampaign({
+#### 📝 Description + +
+
+ +
+
+ +Delete an SMS campaign by its campaign ID. Only campaigns that have not been scheduled or sent can be deleted; attempting to delete a campaign that is queued, in process, or has been sent with recipients will return a 403 permission denied error. +
+
+
+
+ #### 🔌 Usage
@@ -13027,6 +13958,20 @@ await client.smsCampaigns.requestSmsRecipientExport({
+#### 📝 Description + +
+
+ +
+
+ +Send an existing SMS campaign immediately by scheduling it for the current time. The system verifies your account''s SMS credit balance before dispatching; if credits are insufficient or the remaining credit is less than the number of recipients, a 402 error is returned. The campaign must have valid recipients and content already configured. +
+
+
+
+ #### 🔌 Usage
@@ -13149,6 +14094,20 @@ await client.smsCampaigns.sendSmsReport({
+#### 📝 Description + +
+
+ +
+
+ +Send a test SMS to a specified phone number to preview the campaign before sending it to all recipients. The phone number must belong to one of your existing contacts in your Brevo account and must not be blacklisted. The number should include the country code (e.g. 33689965433). +
+
+
+
+ #### 🔌 Usage
@@ -13200,6 +14159,20 @@ await client.smsCampaigns.sendTestSms({
+#### 📝 Description + +
+
+ +
+
+ +Update the status of an SMS campaign, such as suspending, archiving, or replicating it. Available status values include suspended, archive, darchive, sent, queued, replicate, replicateTemplate, cancel, and draft. Note that the replicateTemplate status is only available for template type campaigns. +
+
+
+
+ #### 🔌 Usage
@@ -13253,6 +14226,20 @@ await client.smsCampaigns.updateSmsCampaignStatus({
+#### 📝 Description + +
+
+ +
+
+ +Retrieve a paginated list of all your WhatsApp campaigns with their statistics and metadata. Results can be filtered by creation date range using startDate and endDate, with a default limit of 50 and maximum of 100 per page. The sort order defaults to descending by modification date. +
+
+
+
+ #### 🔌 Usage
@@ -13499,6 +14486,20 @@ await client.whatsAppCampaigns.createWhatsAppTemplate({
+#### 📝 Description + +
+
+ +
+
+ +Retrieve a paginated list of all your WhatsApp templates with their status, category, language, and metadata. Results can be filtered by creation date range and optionally by source (Automation or Conversations), with a default limit of 50 and maximum of 100 per page. The sort order defaults to descending by modification date. +
+
+
+
+ #### 🔌 Usage
@@ -13752,6 +14753,20 @@ await client.whatsAppCampaigns.updateWhatsAppCampaign({
+#### 📝 Description + +
+
+ +
+
+ +Delete a WhatsApp campaign by its campaign ID. The campaign must exist; if the campaign ID is not found, a 404 error is returned. This action is permanent and cannot be undone. +
+
+
+
+ #### 🔌 Usage
@@ -13804,6 +14819,20 @@ await client.whatsAppCampaigns.deleteWhatsAppCampaign({
+#### 📝 Description + +
+
+ +
+
+ +Retrieve a paginated list of companies with optional filtering, sorting, and search capabilities. Results are sorted by creation date in descending order by default, and can be filtered by attributes, linked contacts, linked deals, or modification/creation timestamps. +
+
+
+
+ #### 🔌 Usage
@@ -13853,6 +14882,20 @@ await client.companies.getAllCompanies();
+#### 📝 Description + +
+
+ +
+
+ +Create a new CRM company with the specified name, attributes, and optional associations to contacts and deals. The company name is required, and you can optionally provide a country code when a phone number attribute is included. +
+
+
+
+ #### 🔌 Usage
@@ -13967,6 +15010,20 @@ await client.companies.importCompaniesCreationAndUpdation({});
+#### 📝 Description + +
+
+ +
+
+ +Link or unlink contacts and deals with a specific company in a single request. You can simultaneously link new contacts/deals and unlink existing ones by providing the respective ID arrays in the request body. +
+
+
+
+ #### 🔌 Usage
@@ -14018,6 +15075,20 @@ await client.companies.linkAndUnlinkCompanyWithContactAndDeal({
+#### 📝 Description + +
+
+ +
+
+ +Retrieve the full details of a single company by its identifier, including its attributes, linked contacts, and linked deals. Returns a 404 error if the company does not exist, or a 403 error if the user lacks permission to view the company. +
+
+
+
+ #### 🔌 Usage
@@ -14069,6 +15140,20 @@ await client.companies.getACompany({
+#### 📝 Description + +
+
+ +
+
+ +Permanently delete a company by its identifier. The requesting user must be the company owner or have manage permission on companies; otherwise, a 403 Forbidden error is returned. +
+
+
+
+ #### 🔌 Usage
@@ -14120,6 +15205,20 @@ await client.companies.deleteACompany({
+#### 📝 Description + +
+
+ +
+
+ +Update an existing company''s attributes, name, linked contacts, or linked deals. Note that passing `linkedContactsIds` or `linkedDealsIds` replaces the entire list of associations, so omitted IDs will be removed. The company name cannot be set to an empty string. +
+
+
+
+ #### 🔌 Usage
@@ -14171,7 +15270,21 @@ await client.companies.updateACompany({
-#### 🔌 Usage +#### 📝 Description + +
+
+ +
+
+ +Create a new custom attribute for companies or deals. The attribute label must be unique within the object type, cannot exceed 50 characters, and cannot use reserved names. For `single-select` or `multi-choice` attribute types, you must also provide the `optionsLabels` array. +
+
+
+
+ +#### 🔌 Usage
@@ -14224,6 +15337,20 @@ await client.companies.createACompanyDealAttribute({
+#### 📝 Description + +
+
+ +
+
+ +Delete an existing custom attribute by its identifier. This permanently removes the attribute definition and cleans up all references to it across companies or deals. System-default and non-editable attributes cannot be deleted. +
+
+
+
+ #### 🔌 Usage
@@ -14275,6 +15402,20 @@ await client.companies.deleteAnAttribute({
+#### 📝 Description + +
+
+ +
+
+ +Update an existing custom attribute''s label or options. You can rename the attribute label or modify the available options for `single-select` and `multi-choice` attribute types. System-default attributes cannot be modified except for specific editable fields. +
+
+
+
+ #### 🔌 Usage
@@ -14326,6 +15467,20 @@ await client.companies.updateAnAttribute({
+#### 📝 Description + +
+
+ +
+
+ +Retrieve the list of all attributes defined for companies, including both system-default and custom attributes. Each attribute includes its label, internal name, type, required status, and available options for select-type attributes. +
+
+
+
+ #### 🔌 Usage
@@ -14368,6 +15523,20 @@ await client.companies.getCompanyAttributes();
+#### 📝 Description + +
+
+ +
+
+ +Retrieve the list of all attributes defined for deals, including both system-default and custom attributes. Each attribute includes its label, internal name, type, required status, and available options for select-type attributes. +
+
+
+
+ #### 🔌 Usage
@@ -14409,6 +15578,20 @@ await client.deals.getDealAttributes();
+#### 📝 Description + +
+
+ +
+
+ +Retrieve a paginated list of deals with optional filtering, sorting, and search capabilities. Results can be filtered by attributes such as deal name or owner, linked companies, linked contacts, or modification/creation timestamps. Default sort order is descending by creation date. +
+
+
+
+ #### 🔌 Usage
@@ -14458,6 +15641,20 @@ await client.deals.getAllDeals();
+#### 📝 Description + +
+
+ +
+
+ +Create a new deal in the CRM with the specified name, attributes, and optional associations to contacts and companies. You can assign the deal to a specific pipeline and stage by providing `pipeline` and `deal_stage` attribute IDs, which can be retrieved from the pipeline details endpoint. +
+
+
+
+ #### 🔌 Usage
@@ -14572,6 +15769,20 @@ await client.deals.importDealsCreationAndUpdation({});
+#### 📝 Description + +
+
+ +
+
+ +Link or unlink contacts and companies with a specific deal in a single request. You can simultaneously link new contacts/companies and unlink existing ones by providing the respective ID arrays in the request body. +
+
+
+
+ #### 🔌 Usage
@@ -14623,6 +15834,20 @@ await client.deals.linkAndUnlinkADealWithContactsAndCompanies({
+#### 📝 Description + +
+
+ +
+
+ +Retrieve the full details of a single deal by its identifier, including its attributes, pipeline stage, linked contacts, and linked companies. Returns a 404 error if the deal does not exist. +
+
+
+
+ #### 🔌 Usage
@@ -14674,6 +15899,20 @@ await client.deals.getADeal({
+#### 📝 Description + +
+
+ +
+
+ +Permanently delete a deal by its identifier. The requesting user must be the deal owner or have manage permission on deals; otherwise, a 403 Forbidden error is returned. +
+
+
+
+ #### 🔌 Usage
@@ -14725,6 +15964,20 @@ await client.deals.deleteADeal({
+#### 📝 Description + +
+
+ +
+
+ +Update an existing deal''s attributes, name, linked contacts, or linked companies. Note that passing `linkedContactsIds` or `linkedCompaniesIds` replaces the entire list of associations, so omitted IDs will be removed. To move a deal to a different pipeline or stage, provide both the `pipeline` and `deal_stage` attribute IDs. +
+
+
+
+ #### 🔌 Usage
@@ -14831,6 +16084,20 @@ await client.deals.getPipelineStages();
+#### 📝 Description + +
+
+ +
+
+ +Retrieve the list of all deal pipelines configured for your account, including each pipeline''s stages and settings. If no pipelines have been configured yet, a default pipeline is automatically created and returned. +
+
+
+
+ #### 🔌 Usage
@@ -14872,6 +16139,20 @@ await client.deals.getAllPipelines();
+#### 📝 Description + +
+
+ +
+
+ +Retrieve the details of a specific deal pipeline by its identifier, including its stages, stage ordering, and configuration. Use this endpoint to obtain the pipeline and stage IDs needed when creating or updating deals. +
+
+
+
+ #### 🔌 Usage
@@ -14924,6 +16205,20 @@ await client.deals.getAPipeline({
+#### 📝 Description + +
+
+ +
+
+ +Retrieve a paginated list of CRM files with optional filtering by entity type, entity IDs, and date range. Results are sorted by creation date in descending order by default, with a default limit of 50 files per page. +
+
+
+
+ #### 🔌 Usage
@@ -14973,6 +16268,20 @@ await client.files.getAllFiles();
+#### 📝 Description + +
+
+ +
+
+ +Upload a file and associate it with a contact, company, or deal. The file must be sent as multipart form data with a maximum size of 10 MB. You can optionally link the file to a specific entity by providing the corresponding entity ID. +
+
+
+
+ #### 🔌 Usage
@@ -15024,6 +16333,20 @@ await client.files.uploadAFile({
+#### 📝 Description + +
+
+ +
+
+ +Get a temporary download URL for a CRM file by its identifier. The returned URL is valid for 5 minutes only and provides direct access to the file content. +
+
+
+
+ #### 🔌 Usage
@@ -15075,6 +16398,20 @@ await client.files.downloadAFile({
+#### 📝 Description + +
+
+ +
+
+ +Permanently delete a CRM file by its identifier. This removes the file from storage and unlinks it from any associated contacts, companies, or deals. +
+
+
+
+ #### 🔌 Usage
@@ -15126,6 +16463,20 @@ await client.files.deleteAFile({
+#### 📝 Description + +
+
+ +
+
+ +Retrieve the metadata and details of a specific CRM file by its identifier. This returns information such as the file name, size, type, creation date, and associated entities, but does not include the file content itself. +
+
+
+
+ #### 🔌 Usage
@@ -15178,6 +16529,20 @@ await client.files.getFileDetails({
+#### 📝 Description + +
+
+ +
+
+ +Retrieve a paginated list of CRM notes with optional filtering by entity type, entity IDs, and date range. Results are sorted by creation date in descending order by default, with a default limit of 50 notes per page. +
+
+
+
+ #### 🔌 Usage
@@ -15227,6 +16592,20 @@ await client.notes.getAllNotes();
+#### 📝 Description + +
+
+ +
+
+ +Create a new CRM note and optionally associate it with contacts, companies, or deals. The note text content is required, and you can link the note to multiple entities simultaneously during creation. +
+
+
+
+ #### 🔌 Usage
@@ -15237,7 +16616,7 @@ await client.notes.getAllNotes(); ```typescript await client.notes.createANote({ - text: "In communication with client_dev for resolution of queries." + text: "

Meeting notes: Action item - visit Brevo for details.

" }); ``` @@ -15278,6 +16657,20 @@ await client.notes.createANote({
+#### 📝 Description + +
+
+ +
+
+ +Retrieve the full details of a single CRM note by its identifier. The response includes the note''s text content, creation date, author, and any associated contacts, companies, or deals. +
+
+
+
+ #### 🔌 Usage
@@ -15329,6 +16722,20 @@ await client.notes.getANote({
+#### 📝 Description + +
+
+ +
+
+ +Permanently delete a CRM note by its identifier. This removes the note and unlinks it from any associated contacts, companies, or deals. +
+
+
+
+ #### 🔌 Usage
@@ -15380,6 +16787,20 @@ await client.notes.deleteANote({
+#### 📝 Description + +
+
+ +
+
+ +Update an existing CRM note''s text content and its associations with contacts, companies, or deals. You can modify the note text, change the pinned status, or update the linked entities. +
+
+
+
+ #### 🔌 Usage
@@ -15392,7 +16813,7 @@ await client.notes.deleteANote({ await client.notes.updateANote({ id: "id", body: { - text: "In communication with client_dev for resolution of queries." + text: "

Meeting notes: Action item - visit Brevo for details.

" } }); @@ -15435,6 +16856,20 @@ await client.notes.updateANote({
+#### 📝 Description + +
+
+ +
+
+ +Retrieve a paginated list of CRM tasks with optional filtering by task type, status, date range, assignee, and linked entities (contacts, deals, companies). Results are sorted by creation date in descending order by default, with a default limit of 50 tasks per page. +
+
+
+
+ #### 🔌 Usage
@@ -15486,6 +16921,20 @@ await client.tasks.getAllTasks({
+#### 📝 Description + +
+
+ +
+
+ +Create a new CRM task with the specified name, type, due date, and optional associations to contacts, companies, or deals. A task requires a name, task type ID, and due date at minimum. You can also set a duration, notes, a reminder, and assign the task to a specific user. +
+
+
+
+ #### 🔌 Usage
@@ -15497,7 +16946,7 @@ await client.tasks.getAllTasks({ ```typescript await client.tasks.createATask({ date: "2021-11-01T17:44:54Z", - name: "Task: Connect with client_dev", + name: "Task: Connect with client", taskTypeId: "61a5cd07ca1347c82306ad09" }); @@ -15533,11 +16982,25 @@ await client.tasks.createATask({
- - -
client.tasks.getATask({ ...params }) -> Brevo.Task -
-
+
+ +
client.tasks.getATask({ ...params }) -> Brevo.Task +
+
+ +#### 📝 Description + +
+
+ +
+
+ +Retrieve the full details of a single CRM task by its identifier. The response includes the task''s name, type, status, due date, duration, notes, assignee, reminder settings, and linked contacts, companies, or deals. +
+
+
+
#### 🔌 Usage @@ -15590,6 +17053,20 @@ await client.tasks.getATask({
+#### 📝 Description + +
+
+ +
+
+ +Permanently delete a CRM task by its identifier. This removes the task and cancels any associated reminders. The requesting user must be the task assignee or have manage permission on tasks. +
+
+
+
+ #### 🔌 Usage
@@ -15641,6 +17118,20 @@ await client.tasks.deleteATask({
+#### 📝 Description + +
+
+ +
+
+ +Update an existing CRM task''s properties such as name, type, due date, status, duration, notes, assignee, reminder, or linked entities. Only the fields provided in the request body will be updated; omitted fields remain unchanged. +
+
+
+
+ #### 🔌 Usage
@@ -15688,10 +17179,24 @@ await client.tasks.updateATask({
-
client.tasks.getAllTaskTypes() -> Brevo.GetCrmTasktypesResponse +
client.tasks.getAllTaskTypes() -> Brevo.GetCrmTasktypesResponseItem[] +
+
+ +#### 📝 Description +
+
+
+ +Retrieve the list of all available task types, such as Email, Call, Meeting, Todo, Lunch, Deadline, and LinkedIn. If no task types exist yet, the default set is automatically created and returned. Use the task type ID when creating or updating tasks. +
+
+
+
+ #### 🔌 Usage
@@ -15867,6 +17372,20 @@ await client.transactionalWhatsApp.getWhatsappEventReport();
+#### 📝 Description + +
+
+ +
+
+ +Retrieve a paginated list of transactional contacts that have been blocked or unsubscribed, along with the reason for blocking (e.g. hard bounce, admin blocked, spam complaint, or unsubscription via email/API/Marketing Automation). Both `startDate` and `endDate` must be provided together when filtering by date range, and neither date can be in the future. Results default to 50 per page (max 100) and are sorted in descending order of record creation unless overridden with the `sort` parameter. +
+
+
+
+ #### 🔌 Usage
@@ -15916,6 +17435,20 @@ await client.transactionalEmails.getTransacBlockedContacts();
+#### 📝 Description + +
+
+ +
+
+ +Unblock or resubscribe a transactional contact by removing their email address from the blacklist. The email address must be URL-encoded in the path parameter and must be a valid email format. If the contact is not found in the blocklist, a 404 error is returned. +
+
+
+
+ #### 🔌 Usage
@@ -16215,6 +17748,20 @@ await client.transactionalEmails.deleteHardbounces();
+#### 📝 Description + +
+
+ +
+
+ +Send a transactional email to one or more recipients, either using inline HTML content or a pre-built template via `templateId`. You can schedule emails for future delivery using `scheduledAt` (UTC, up to 5-minute delay), send multiple personalized versions with `messageVersions` (max 2000 total recipients, 99 per version), and attach files via URL or base64-encoded content. A `sender` and `subject` are required when no `templateId` is provided; when a `templateId` is used, the template''s sender and subject are applied unless overridden. +
+
+
+
+ #### 🔌 Usage
@@ -16537,6 +18084,20 @@ await client.transactionalEmails.getTransacEmailContent({
+#### 📝 Description + +
+
+ +
+
+ +Delete SMTP transactional log entries identified by a message ID (enclosed in angle brackets with an @ sign) or a valid email address. Optionally narrow the deletion to a specific date range using `from_date` and `to_date` query parameters (YYYY-MM-DD format). The operation also removes any associated stored email preview content. +
+
+
+
+ #### 🔌 Usage
@@ -16714,6 +18275,20 @@ await client.transactionalEmails.getEmailEventReport();
+#### 📝 Description + +
+
+ +
+
+ +This endpoint will show the aggregated stats per day for the past 10 days by default if `startDate` and `endDate` OR `days` is not passed. The date range can not exceed 30 days. +
+
+
+
+ #### 🔌 Usage
@@ -16763,6 +18338,20 @@ await client.transactionalEmails.getSmtpReport();
+#### 📝 Description + +
+
+ +
+
+ +Generate a fully rendered preview of a transactional email template by resolving dynamic variables. Provide either an `email` address (to populate variables from the contact''s attributes) or a `params` object with key-value pairs for manual substitution; at least one of these is required alongside the mandatory `templateId`. The response includes the rendered HTML, subject, sender details, preview text, and any feed names used in the template. +
+
+
+
+ #### 🔌 Usage
@@ -16790,7 +18379,7 @@ await client.transactionalEmails.postPreviewSmtpEmailTemplates({
-**request:** `unknown` +**request:** `Brevo.PostPreviewSmtpEmailTemplatesRequest`
@@ -16814,6 +18403,20 @@ await client.transactionalEmails.postPreviewSmtpEmailTemplates({
+#### 📝 Description + +
+
+ +
+
+ +Retrieve a paginated list of all transactional email templates (including automation templates) with their details such as name, subject, sender, status, HTML content, and timestamps. Results default to 50 per page (max 1000) and are sorted in descending creation order unless overridden. You can filter by active/inactive status using `templateStatus` and by editor type using `editorType` (currently only `richTextEditor` is supported). +
+
+
+
+ #### 🔌 Usage
@@ -16863,6 +18466,20 @@ await client.transactionalEmails.getSmtpTemplates();
+#### 📝 Description + +
+
+ +
+
+ +Create a new transactional email template with the specified sender, subject, and content. The `sender`, `subject`, and `templateName` fields are required. Template content can be provided via `htmlContent` (minimum 10 characters) or `htmlUrl`; at least one must be supplied. Templates are created as inactive by default unless `isActive` is explicitly set to `true`. +
+
+
+
+ #### 🔌 Usage
@@ -16916,6 +18533,20 @@ await client.transactionalEmails.createSmtpTemplate({
+#### 📝 Description + +
+
+ +
+
+ +Retrieve the full details of a specific transactional email template by its numeric ID or custom template identifier string. The response includes the template name, subject, sender information, HTML content, active status, creation and modification timestamps, reply-to address, tag, and a `doiTemplate` flag indicating whether the template is a double opt-in template (detected by the presence of optin-related tags or variables in the content). +
+
+
+
+ #### 🔌 Usage
@@ -16967,6 +18598,20 @@ await client.transactionalEmails.getSmtpTemplate({
+#### 📝 Description + +
+
+ +
+
+ +Update an existing transactional email template by its numeric ID or custom template identifier string. All fields in the request body are optional; only the provided fields will be updated. You can update the template name, subject, sender, reply-to address, HTML content (via `htmlContent` or `htmlUrl`), active status, tag, attachment URL, and the personalized `toField`. Only one of sender email or sender ID should be provided per request. +
+
+
+
+ #### 🔌 Usage
@@ -17018,6 +18663,20 @@ await client.transactionalEmails.updateSmtpTemplate({
+#### 📝 Description + +
+
+ +
+
+ +Permanently delete a transactional email template by its numeric ID. Only inactive templates can be deleted; attempting to delete an active template returns a 405 error. To deactivate a template before deletion, use `PUT /smtp/templates/{templateId}` with `isActive` set to `false`. Deletion also removes associated newsletter template data and triggers asynchronous cleanup of shared assets. +
+
+
+
+ #### 🔌 Usage
@@ -17069,6 +18728,20 @@ await client.transactionalEmails.deleteSmtpTemplate({
+#### 📝 Description + +
+
+ +
+
+ +Send a test email of the specified transactional template to one or more recipients. Provide an array of email addresses in the `emailTo` field; if left empty, the test mail is sent to your entire test list. You can send a maximum of 50 test emails per day, and all provided email addresses must be valid. +
+
+
+
+ #### 🔌 Usage
@@ -17190,6 +18863,20 @@ await client.transactionalSms.sendAsyncTransactionalSms({
+#### 📝 Description + +
+
+ +
+
+ +Send a transactional SMS message to a single mobile number. The `sender`, `recipient`, and either `content` or `templateId` fields are required. The sender name is limited to 11 alphanumeric characters or 15 numeric characters, and the recipient must be a valid international phone number (6-15 digits, optional leading +). Tags can be a string or an array of up to 10 strings. The SMS type defaults to `transactional` but can be set to `marketing`; if the content includes a stop code, it is automatically treated as marketing. Returns the message ID, SMS count, credits used, and remaining credits. +
+
+
+
+ #### 🔌 Usage
@@ -17242,6 +18929,20 @@ await client.transactionalSms.sendTransacSms({
+#### 📝 Description + +
+
+ +
+
+ +Retrieve an aggregated report of your transactional SMS activity over a specified time period, including counts for requests, delivered, hard bounces, soft bounces, blocked, unsubscribed, replied, accepted, rejected, and skipped messages. Filter by date range using `startDate` and `endDate` (both required together, YYYY-MM-DD format) or by a number of past `days` (not compatible with date range). You can further narrow results by `tag`. If no date filter is provided, the report covers all available data and returns the auto-detected date range. +
+
+
+
+ #### 🔌 Usage
@@ -17291,6 +18992,20 @@ await client.transactionalSms.getTransacAggregatedSmsReport();
+#### 📝 Description + +
+
+ +
+
+ +Retrieve a paginated list of individual SMS event records (unaggregated), including event type, phone number, message ID, timestamp, tag, and reason or reply content where applicable. Results default to 50 per page (max 100) and are sorted in descending order unless overridden. Filter by date range (`startDate`/`endDate`), past `days` (not compatible with date range), specific `event` type (e.g. delivered, bounces, replies), `phoneNumber`, or `tags`. Bounce events include the failure reason, and reply events include the reply content. +
+
+
+
+ #### 🔌 Usage
@@ -17340,6 +19055,20 @@ await client.transactionalSms.getSmsEvents();
+#### 📝 Description + +
+
+ +
+
+ +Retrieve a day-by-day breakdown of your transactional SMS activity, with each entry containing the date and counts for requests, delivered, hard bounces, soft bounces, blocked, unsubscribed, replied, accepted, rejected, and skipped messages. Filter by date range using `startDate` and `endDate` (both required together, YYYY-MM-DD format), by a number of past `days` (not compatible with date range), or by `tag`. Results are sorted in descending order by default unless overridden with the `sort` parameter. +
+
+
+
+ #### 🔌 Usage
diff --git a/src/BaseClient.ts b/src/BaseClient.ts index 00b1d03..1fcac98 100644 --- a/src/BaseClient.ts +++ b/src/BaseClient.ts @@ -5,6 +5,12 @@ import { mergeHeaders } from "./core/headers.js"; import * as core from "./core/index.js"; import type * as environments from "./environments.js"; +export type AuthOption = + | false + | core.AuthProvider["getAuthRequest"] + | core.AuthProvider + | HeaderAuthProvider.AuthOptions; + export type BaseClientOptions = { environment?: core.Supplier; /** Specify a custom URL to connect the client to. */ @@ -19,6 +25,8 @@ export type BaseClientOptions = { fetch?: typeof fetch; /** Configure logging for the client. */ logging?: core.logging.LogConfig | core.logging.Logger; + /** Override auth. Pass false to disable, a function returning auth headers, an AuthProvider, or auth options. */ + auth?: AuthOption; } & HeaderAuthProvider.AuthOptions; export interface BaseRequestOptions { @@ -51,8 +59,8 @@ export function normalizeClientOptions { const normalized = normalizeClientOptions(options) as NormalizedClientOptionsWithAuth; + + if (options.auth === false) { + normalized.authProvider = new core.NoOpAuthProvider(); + return normalized; + } + if (options.auth != null) { + if (typeof options.auth === "function") { + normalized.authProvider = { getAuthRequest: options.auth }; + return normalized; + } + if (core.isAuthProvider(options.auth)) { + normalized.authProvider = options.auth; + return normalized; + } + Object.assign(normalized, options.auth); + } + const normalizedWithNoOpAuthProvider = withNoOpAuthProvider(normalized); normalized.authProvider ??= new HeaderAuthProvider(normalizedWithNoOpAuthProvider); return normalized; diff --git a/src/api/resources/account/client/Client.ts b/src/api/resources/account/client/Client.ts index 883de54..fce474b 100644 --- a/src/api/resources/account/client/Client.ts +++ b/src/api/resources/account/client/Client.ts @@ -30,29 +30,28 @@ export class AccountClient { * - Check plan details (type, credits, expiration) * - Get relay information (for transactional emails) * - Check Marketing Automation status - * - View date/time preferences and account settings * - Access organization and user identifiers * * **Key information returned:** * - Complete account details (organization ID, user ID, company information) * - Address and contact information * - Plan configurations and credit allocations across different verticals - * - Marketing Automation settings and tracker key + * - Marketing Automation settings and tracker key (when enabled) * - SMTP relay configuration for transactional emails - * - Date/time preferences and account settings * - Enterprise features availability status * * **Important considerations:** * - Provides comprehensive account overview for billing and configuration management * - Essential for understanding current plan limitations and feature availability - * - Marketing Automation key required for advanced automation features - * - Plan verticals show detailed breakdown across Marketing, Chat, and CRM categories + * - Marketing Automation key is only returned when Marketing Automation is enabled on the account + * - Plan verticals show detailed breakdown across Marketing, Chat, and CRM categories (only returned when plan verticals are available) * - Relay configuration crucial for transactional email setup and deliverability - * - Date/time preferences affect campaign scheduling and reporting displays * - Enterprise status determines access to advanced features and sub-account management * * @param {AccountClient.RequestOptions} requestOptions - Request-specific configuration. * + * @throws {@link Brevo.BadRequestError} + * * @example * await client.account.getAccount() */ @@ -80,7 +79,7 @@ export class AccountClient { ), method: "GET", headers: _headers, - queryParameters: requestOptions?.queryParams, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, abortSignal: requestOptions?.abortSignal, @@ -92,11 +91,16 @@ export class AccountClient { } if (_response.error.reason === "status-code") { - throw new errors.BrevoError({ - statusCode: _response.error.statusCode, - body: _response.error.body, - rawResponse: _response.rawResponse, - }); + switch (_response.error.statusCode) { + case 400: + throw new Brevo.BadRequestError(_response.error.body as unknown, _response.rawResponse); + default: + throw new errors.BrevoError({ + statusCode: _response.error.statusCode, + body: _response.error.body, + rawResponse: _response.rawResponse, + }); + } } return handleNonStatusCodeError(_response.error, _response.rawResponse, "GET", "/account"); @@ -163,7 +167,11 @@ export class AccountClient { ), method: "GET", headers: _headers, - queryParameters: { ..._queryParams, ...requestOptions?.queryParams }, + queryString: core.url + .queryBuilder() + .addMany(_queryParams) + .mergeAdditional(requestOptions?.queryParams) + .build(), timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, abortSignal: requestOptions?.abortSignal, diff --git a/src/api/resources/account/types/GetAccountResponse.ts b/src/api/resources/account/types/GetAccountResponse.ts index 4816f3d..44890b7 100644 --- a/src/api/resources/account/types/GetAccountResponse.ts +++ b/src/api/resources/account/types/GetAccountResponse.ts @@ -16,9 +16,7 @@ export interface GetAccountResponse { /** Last Name */ lastName: string; /** Address informations */ - address: GetAccountResponse.Address; - /** User's date and time preferences */ - dateTimePreferences: GetAccountResponse.DateTimePreferences; + address?: GetAccountResponse.Address | undefined; marketingAutomation?: GetAccountResponse.MarketingAutomation | undefined; /** Information about your plans and credits */ plan: GetAccountResponse.Plan.Item[]; @@ -43,18 +41,6 @@ export namespace GetAccountResponse { zipCode: string; } - /** - * User's date and time preferences - */ - export interface DateTimePreferences { - /** User's timezone setting */ - timezone: string; - /** Preferred time format (12 or 24 hour) */ - timeFormat: string; - /** Preferred date format */ - dateFormat: string; - } - export interface MarketingAutomation { /** * Status of Marketing Automation Plateform activation @@ -117,11 +103,11 @@ export namespace GetAccountResponse { /** Current status of the plan */ status: Item.Status; /** Plan start date (Unix timestamp) */ - startDate: string; + startDate?: string | undefined; /** Plan end date (Unix timestamp) */ - endDate: string; + endDate?: string | undefined; /** User seat information for the plan */ - users: Item.Users | null; + users?: (Item.Users | null) | undefined; /** Credits allocated for this plan category (optional, may not be present for all plan categories) */ credits?: string | undefined; } diff --git a/src/api/resources/balance/client/Client.ts b/src/api/resources/balance/client/Client.ts index cdca428..21adfbe 100644 --- a/src/api/resources/balance/client/Client.ts +++ b/src/api/resources/balance/client/Client.ts @@ -37,38 +37,29 @@ export class BalanceClient { * @example * await client.balance.getActiveBalancesApi({ * pid: "pid", - * contact_id: 1, - * balance_definition_id: "balance_definition_id" + * contactId: 1000000, + * balanceDefinitionId: "balanceDefinitionId" * }) */ public getActiveBalancesApi( request: Brevo.GetLoyaltyBalanceProgramsPidActiveBalanceRequest, requestOptions?: BalanceClient.RequestOptions, - ): core.HttpResponsePromise { + ): core.HttpResponsePromise { return core.HttpResponsePromise.fromPromise(this.__getActiveBalancesApi(request, requestOptions)); } private async __getActiveBalancesApi( request: Brevo.GetLoyaltyBalanceProgramsPidActiveBalanceRequest, requestOptions?: BalanceClient.RequestOptions, - ): Promise> { - const { - pid, - limit, - offset, - sort_field: sortField, - sort, - contact_id: contactId, - balance_definition_id: balanceDefinitionId, - includeInternal, - } = request; + ): Promise> { + const { pid, limit, offset, sortField, sort, contactId, balanceDefinitionId, includeInternal } = request; const _queryParams: Record = { limit, offset, - sort_field: sortField, - sort, - contact_id: contactId, - balance_definition_id: balanceDefinitionId, + sortField: sortField != null ? sortField : undefined, + sort: sort != null ? sort : undefined, + contactId, + balanceDefinitionId, includeInternal, }; const _authRequest: core.AuthRequest = await this._options.authProvider.getAuthRequest(); @@ -86,7 +77,11 @@ export class BalanceClient { ), method: "GET", headers: _headers, - queryParameters: { ..._queryParams, ...requestOptions?.queryParams }, + queryString: core.url + .queryBuilder() + .addMany(_queryParams) + .mergeAdditional(requestOptions?.queryParams) + .build(), timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, abortSignal: requestOptions?.abortSignal, @@ -94,7 +89,10 @@ export class BalanceClient { logging: this._options.logging, }); if (_response.ok) { - return { data: _response.body as Brevo.BalanceLimit, rawResponse: _response.rawResponse }; + return { + data: _response.body as Brevo.GetLoyaltyBalanceProgramsPidActiveBalanceResponse, + rawResponse: _response.rawResponse, + }; } if (_response.error.reason === "status-code") { @@ -179,7 +177,11 @@ export class BalanceClient { ), method: "GET", headers: _headers, - queryParameters: { ..._queryParams, ...requestOptions?.queryParams }, + queryString: core.url + .queryBuilder() + .addMany(_queryParams) + .mergeAdditional(requestOptions?.queryParams) + .build(), timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, abortSignal: requestOptions?.abortSignal, @@ -270,7 +272,7 @@ export class BalanceClient { method: "POST", headers: _headers, contentType: "application/json", - queryParameters: requestOptions?.queryParams, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), requestType: "json", body: _body, timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, @@ -363,7 +365,11 @@ export class BalanceClient { ), method: "GET", headers: _headers, - queryParameters: { ..._queryParams, ...requestOptions?.queryParams }, + queryString: core.url + .queryBuilder() + .addMany(_queryParams) + .mergeAdditional(requestOptions?.queryParams) + .build(), timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, abortSignal: requestOptions?.abortSignal, @@ -455,7 +461,7 @@ export class BalanceClient { method: "PUT", headers: _headers, contentType: "application/json", - queryParameters: requestOptions?.queryParams, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), requestType: "json", body: _body, timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, @@ -547,7 +553,7 @@ export class BalanceClient { ), method: "DELETE", headers: _headers, - queryParameters: requestOptions?.queryParams, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, abortSignal: requestOptions?.abortSignal, @@ -641,7 +647,7 @@ export class BalanceClient { method: "POST", headers: _headers, contentType: "application/json", - queryParameters: requestOptions?.queryParams, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), requestType: "json", body: _body, timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, @@ -735,7 +741,11 @@ export class BalanceClient { ), method: "GET", headers: _headers, - queryParameters: { ..._queryParams, ...requestOptions?.queryParams }, + queryString: core.url + .queryBuilder() + .addMany(_queryParams) + .mergeAdditional(requestOptions?.queryParams) + .build(), timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, abortSignal: requestOptions?.abortSignal, @@ -830,7 +840,7 @@ export class BalanceClient { method: "PUT", headers: _headers, contentType: "application/json", - queryParameters: requestOptions?.queryParams, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), requestType: "json", body: _body, timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, @@ -921,7 +931,7 @@ export class BalanceClient { ), method: "DELETE", headers: _headers, - queryParameters: requestOptions?.queryParams, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, abortSignal: requestOptions?.abortSignal, @@ -965,7 +975,7 @@ export class BalanceClient { } /** - * Returns balance list + * Returns contact balances for a given balance definition across all subscriptions. * * @param {Brevo.GetContactBalancesRequest} request * @param {BalanceClient.RequestOptions} requestOptions - Request-specific configuration. @@ -978,7 +988,8 @@ export class BalanceClient { * * @example * await client.balance.getContactBalances({ - * pid: "pid" + * pid: "pid", + * balanceDefinitionId: "balanceDefinitionId" * }) */ public getContactBalances( @@ -992,9 +1003,14 @@ export class BalanceClient { request: Brevo.GetContactBalancesRequest, requestOptions?: BalanceClient.RequestOptions, ): Promise> { - const { pid, includeInternal } = request; + const { pid, includeInternal, limit, offset, sort, sortField, balanceDefinitionId } = request; const _queryParams: Record = { includeInternal, + limit, + offset, + sort: sort != null ? sort : undefined, + sortField: sortField != null ? sortField : undefined, + balanceDefinitionId, }; const _authRequest: core.AuthRequest = await this._options.authProvider.getAuthRequest(); const _headers: core.Fetcher.Args["headers"] = mergeHeaders( @@ -1011,7 +1027,11 @@ export class BalanceClient { ), method: "GET", headers: _headers, - queryParameters: { ..._queryParams, ...requestOptions?.queryParams }, + queryString: core.url + .queryBuilder() + .addMany(_queryParams) + .mergeAdditional(requestOptions?.queryParams) + .build(), timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, abortSignal: requestOptions?.abortSignal, @@ -1072,7 +1092,7 @@ export class BalanceClient { * balanceDefinitionId: "balanceDefinitionId", * contactId: 1, * dueAt: "dueAt", - * source: "source" + * source: "engine" * }) */ public createBalanceOrder( @@ -1103,7 +1123,7 @@ export class BalanceClient { method: "POST", headers: _headers, contentType: "application/json", - queryParameters: requestOptions?.queryParams, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), requestType: "json", body: _body, timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, @@ -1194,7 +1214,11 @@ export class BalanceClient { ), method: "GET", headers: _headers, - queryParameters: { ..._queryParams, ...requestOptions?.queryParams }, + queryString: core.url + .queryBuilder() + .addMany(_queryParams) + .mergeAdditional(requestOptions?.queryParams) + .build(), timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, abortSignal: requestOptions?.abortSignal, @@ -1287,7 +1311,7 @@ export class BalanceClient { method: "POST", headers: _headers, contentType: "application/json", - queryParameters: requestOptions?.queryParams, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), requestType: "json", body: _body, timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, @@ -1350,7 +1374,7 @@ export class BalanceClient { * @example * await client.balance.getTransactionHistoryApi({ * pid: "pid", - * contactId: 1, + * contactId: 1000000, * balanceDefinitionId: "balanceDefinitionId" * }) */ @@ -1373,9 +1397,9 @@ export class BalanceClient { sort, contactId, balanceDefinitionId, - filters, status, transactionType, + loyaltySubscriptionId, } = request; const _queryParams: Record = { limit, @@ -1384,9 +1408,9 @@ export class BalanceClient { sort: sort != null ? sort : undefined, contactId, balanceDefinitionId, - filters, status: status != null ? status : undefined, transactionType: transactionType != null ? transactionType : undefined, + loyaltySubscriptionId, }; const _authRequest: core.AuthRequest = await this._options.authProvider.getAuthRequest(); const _headers: core.Fetcher.Args["headers"] = mergeHeaders( @@ -1403,7 +1427,11 @@ export class BalanceClient { ), method: "GET", headers: _headers, - queryParameters: { ..._queryParams, ...requestOptions?.queryParams }, + queryString: core.url + .queryBuilder() + .addMany(_queryParams) + .mergeAdditional(requestOptions?.queryParams) + .build(), timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, abortSignal: requestOptions?.abortSignal, @@ -1496,7 +1524,7 @@ export class BalanceClient { method: "POST", headers: _headers, contentType: "application/json", - queryParameters: requestOptions?.queryParams, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), requestType: "json", body: _body, timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, @@ -1586,7 +1614,7 @@ export class BalanceClient { ), method: "POST", headers: _headers, - queryParameters: requestOptions?.queryParams, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, abortSignal: requestOptions?.abortSignal, @@ -1674,7 +1702,7 @@ export class BalanceClient { ), method: "POST", headers: _headers, - queryParameters: requestOptions?.queryParams, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, abortSignal: requestOptions?.abortSignal, diff --git a/src/api/resources/balance/client/requests/BeginTransactionRequest.ts b/src/api/resources/balance/client/requests/BeginTransactionRequest.ts index 7ecd06e..88defe7 100644 --- a/src/api/resources/balance/client/requests/BeginTransactionRequest.ts +++ b/src/api/resources/balance/client/requests/BeginTransactionRequest.ts @@ -11,22 +11,33 @@ export interface BeginTransactionRequest { /** Loyalty Program Id */ pid: string; - /** Unique identifier for the loyalty subscription (required unless `contactId` is provided). */ - LoyaltySubscriptionId?: string; - /** Transaction amount (must be provided). */ + /** Transaction amount. A positive value creates a credit transaction and a negative value creates a debit transaction (unless transactionType is explicitly provided). */ amount: number; - /** Whether the transaction should be automatically completed. */ - autoComplete?: boolean; + /** Explicit transaction type. If not provided, the type is inferred from the sign of the amount (positive = credit, negative = debit). */ + transactionType?: BeginTransactionRequest.TransactionType; /** Unique identifier (UUID) of the associated balance definition. */ balanceDefinitionId: string; - /** Optional expiry time for the balance in minutes (must be greater than 0 if provided). */ - balanceExpiryInMinutes?: number; - /** Unique identifier of the contact involved in the transaction (required unless `LoyaltySubscriptionId` is provided). */ + /** Unique identifier of the contact involved in the transaction. Required unless `LoyaltySubscriptionId` is provided. */ contactId?: number; - /** Optional timestamp specifying when the transaction occurred. */ - eventTime?: string; + /** Unique identifier for the loyalty subscription. Required unless `contactId` is provided. */ + LoyaltySubscriptionId?: string; /** Optional metadata associated with the transaction. */ meta?: Record; - /** Optional time-to-live for the transaction (must be greater than 0 if provided). */ + /** Time-to-live for the transaction in seconds. Must be at least 10 seconds if provided. */ ttl?: number; + /** Timestamp specifying when the transaction event occurred (ISO 8601 / RFC 3339 format). */ + eventTime?: string; + /** Whether the transaction should be automatically completed. */ + autoComplete?: boolean; + /** Expiry time for the balance in minutes. Must be greater than 0 if provided. Only applicable when autoComplete is true. */ + balanceExpiryInMinutes?: number; +} + +export namespace BeginTransactionRequest { + /** Explicit transaction type. If not provided, the type is inferred from the sign of the amount (positive = credit, negative = debit). */ + export const TransactionType = { + Credit: "credit", + Debit: "debit", + } as const; + export type TransactionType = (typeof TransactionType)[keyof typeof TransactionType]; } diff --git a/src/api/resources/balance/client/requests/CreateBalanceOrderRequest.ts b/src/api/resources/balance/client/requests/CreateBalanceOrderRequest.ts index 126012a..a895748 100644 --- a/src/api/resources/balance/client/requests/CreateBalanceOrderRequest.ts +++ b/src/api/resources/balance/client/requests/CreateBalanceOrderRequest.ts @@ -8,7 +8,7 @@ * balanceDefinitionId: "balanceDefinitionId", * contactId: 1, * dueAt: "dueAt", - * source: "source" + * source: "engine" * } */ export interface CreateBalanceOrderRequest { @@ -26,6 +26,15 @@ export interface CreateBalanceOrderRequest { expiresAt?: string; /** Optional metadata associated with the order. */ meta?: Record; - /** Specifies the origin of the order (`engine` or `user`). */ - source: string; + /** Specifies the origin of the order. */ + source: CreateBalanceOrderRequest.Source; +} + +export namespace CreateBalanceOrderRequest { + /** Specifies the origin of the order. */ + export const Source = { + Engine: "engine", + User: "user", + } as const; + export type Source = (typeof Source)[keyof typeof Source]; } diff --git a/src/api/resources/balance/client/requests/GetContactBalancesRequest.ts b/src/api/resources/balance/client/requests/GetContactBalancesRequest.ts index 676e240..4f1b5ab 100644 --- a/src/api/resources/balance/client/requests/GetContactBalancesRequest.ts +++ b/src/api/resources/balance/client/requests/GetContactBalancesRequest.ts @@ -1,9 +1,12 @@ // This file was auto-generated by Fern from our API Definition. +import type * as Brevo from "../../../../index.js"; + /** * @example * { - * pid: "pid" + * pid: "pid", + * balanceDefinitionId: "balanceDefinitionId" * } */ export interface GetContactBalancesRequest { @@ -11,4 +14,14 @@ export interface GetContactBalancesRequest { pid: string; /** Include balances tied to internal definitions. */ includeInternal?: boolean; + /** Limit the number of records returned */ + limit?: number; + /** Skip a number of records */ + offset?: number; + /** Sort order */ + sort?: Brevo.GetContactBalancesRequestSort; + /** Field to sort by */ + sortField?: Brevo.GetContactBalancesRequestSortField; + /** Balance Definition ID (required) */ + balanceDefinitionId: string; } diff --git a/src/api/resources/balance/client/requests/GetLoyaltyBalanceProgramsPidActiveBalanceRequest.ts b/src/api/resources/balance/client/requests/GetLoyaltyBalanceProgramsPidActiveBalanceRequest.ts index cdced4d..5f11f9f 100644 --- a/src/api/resources/balance/client/requests/GetLoyaltyBalanceProgramsPidActiveBalanceRequest.ts +++ b/src/api/resources/balance/client/requests/GetLoyaltyBalanceProgramsPidActiveBalanceRequest.ts @@ -1,11 +1,13 @@ // This file was auto-generated by Fern from our API Definition. +import type * as Brevo from "../../../../index.js"; + /** * @example * { * pid: "pid", - * contact_id: 1, - * balance_definition_id: "balance_definition_id" + * contactId: 1000000, + * balanceDefinitionId: "balanceDefinitionId" * } */ export interface GetLoyaltyBalanceProgramsPidActiveBalanceRequest { @@ -16,13 +18,13 @@ export interface GetLoyaltyBalanceProgramsPidActiveBalanceRequest { /** Offset */ offset?: number; /** Sort Field */ - sort_field?: string; + sortField?: "createdAt"; /** Sort Order */ - sort?: string; + sort?: Brevo.GetLoyaltyBalanceProgramsPidActiveBalanceRequestSort; /** Contact ID */ - contact_id: number; + contactId: number; /** Balance Definition ID */ - balance_definition_id: string; + balanceDefinitionId: string; /** Include balances tied to internal definitions. */ includeInternal?: boolean; } diff --git a/src/api/resources/balance/client/requests/GetLoyaltyBalanceProgramsPidTransactionHistoryRequest.ts b/src/api/resources/balance/client/requests/GetLoyaltyBalanceProgramsPidTransactionHistoryRequest.ts index 915f95e..aa39b6a 100644 --- a/src/api/resources/balance/client/requests/GetLoyaltyBalanceProgramsPidTransactionHistoryRequest.ts +++ b/src/api/resources/balance/client/requests/GetLoyaltyBalanceProgramsPidTransactionHistoryRequest.ts @@ -6,7 +6,7 @@ import type * as Brevo from "../../../../index.js"; * @example * { * pid: "pid", - * contactId: 1, + * contactId: 1000000, * balanceDefinitionId: "balanceDefinitionId" * } */ @@ -19,16 +19,16 @@ export interface GetLoyaltyBalanceProgramsPidTransactionHistoryRequest { offset?: number; /** Field to sort by */ sortField?: "createdAt"; - /** Sort order, either asc or desc */ + /** Sort order */ sort?: Brevo.GetLoyaltyBalanceProgramsPidTransactionHistoryRequestSort; /** Contact ID */ contactId: number; /** Balance Definition ID */ balanceDefinitionId: string; - /** Filters to apply */ - filters?: string | string[]; - /** Transaction status filter. Allowed values: draft, completed, rejected, cancelled, expired */ + /** Transaction status filter */ status?: Brevo.GetLoyaltyBalanceProgramsPidTransactionHistoryRequestStatus; - /** Transaction type filter. Allowed values: credit, debit */ + /** Transaction type filter */ transactionType?: Brevo.GetLoyaltyBalanceProgramsPidTransactionHistoryRequestTransactionType; + /** Loyalty Subscription ID filter */ + loyaltySubscriptionId?: string; } diff --git a/src/api/resources/balance/client/requests/index.ts b/src/api/resources/balance/client/requests/index.ts index a782eb4..600d81b 100644 --- a/src/api/resources/balance/client/requests/index.ts +++ b/src/api/resources/balance/client/requests/index.ts @@ -1,8 +1,8 @@ -export type { BeginTransactionRequest } from "./BeginTransactionRequest.js"; +export { BeginTransactionRequest } from "./BeginTransactionRequest.js"; export type { CancelTransactionRequest } from "./CancelTransactionRequest.js"; export type { CompleteTransactionRequest } from "./CompleteTransactionRequest.js"; export { CreateBalanceLimitRequest } from "./CreateBalanceLimitRequest.js"; -export type { CreateBalanceOrderRequest } from "./CreateBalanceOrderRequest.js"; +export { CreateBalanceOrderRequest } from "./CreateBalanceOrderRequest.js"; export type { DeleteBalanceDefinitionRequest } from "./DeleteBalanceDefinitionRequest.js"; export type { DeleteBalanceLimitRequest } from "./DeleteBalanceLimitRequest.js"; export type { GetBalanceDefinitionListRequest } from "./GetBalanceDefinitionListRequest.js"; diff --git a/src/api/resources/balance/types/GetContactBalancesRequestSort.ts b/src/api/resources/balance/types/GetContactBalancesRequestSort.ts new file mode 100644 index 0000000..5111e7d --- /dev/null +++ b/src/api/resources/balance/types/GetContactBalancesRequestSort.ts @@ -0,0 +1,8 @@ +// This file was auto-generated by Fern from our API Definition. + +export const GetContactBalancesRequestSort = { + Asc: "asc", + Desc: "desc", +} as const; +export type GetContactBalancesRequestSort = + (typeof GetContactBalancesRequestSort)[keyof typeof GetContactBalancesRequestSort]; diff --git a/src/api/resources/balance/types/GetContactBalancesRequestSortField.ts b/src/api/resources/balance/types/GetContactBalancesRequestSortField.ts new file mode 100644 index 0000000..d3b7135 --- /dev/null +++ b/src/api/resources/balance/types/GetContactBalancesRequestSortField.ts @@ -0,0 +1,8 @@ +// This file was auto-generated by Fern from our API Definition. + +export const GetContactBalancesRequestSortField = { + UpdatedAt: "updatedAt", + Value: "value", +} as const; +export type GetContactBalancesRequestSortField = + (typeof GetContactBalancesRequestSortField)[keyof typeof GetContactBalancesRequestSortField]; diff --git a/src/api/resources/balance/types/GetLoyaltyBalanceProgramsPidActiveBalanceRequestSort.ts b/src/api/resources/balance/types/GetLoyaltyBalanceProgramsPidActiveBalanceRequestSort.ts new file mode 100644 index 0000000..bb0ebad --- /dev/null +++ b/src/api/resources/balance/types/GetLoyaltyBalanceProgramsPidActiveBalanceRequestSort.ts @@ -0,0 +1,8 @@ +// This file was auto-generated by Fern from our API Definition. + +export const GetLoyaltyBalanceProgramsPidActiveBalanceRequestSort = { + Asc: "asc", + Desc: "desc", +} as const; +export type GetLoyaltyBalanceProgramsPidActiveBalanceRequestSort = + (typeof GetLoyaltyBalanceProgramsPidActiveBalanceRequestSort)[keyof typeof GetLoyaltyBalanceProgramsPidActiveBalanceRequestSort]; diff --git a/src/api/resources/balance/types/GetLoyaltyBalanceProgramsPidActiveBalanceResponse.ts b/src/api/resources/balance/types/GetLoyaltyBalanceProgramsPidActiveBalanceResponse.ts new file mode 100644 index 0000000..8b83e48 --- /dev/null +++ b/src/api/resources/balance/types/GetLoyaltyBalanceProgramsPidActiveBalanceResponse.ts @@ -0,0 +1,34 @@ +// This file was auto-generated by Fern from our API Definition. + +/** + * Active balance response for a specific contact and balance definition. + */ +export interface GetLoyaltyBalanceProgramsPidActiveBalanceResponse { + /** Total number of active balances. */ + count?: number | undefined; + /** Unique identifier of the loyalty program. */ + loyaltyProgramId?: string | undefined; + /** Unique identifier of the contact. */ + contactId?: number | undefined; + /** Unique identifier of the balance definition. */ + balanceDefinitionId?: string | undefined; + /** List of active balances. */ + activeBalances?: GetLoyaltyBalanceProgramsPidActiveBalanceResponse.ActiveBalances.Item[] | undefined; +} + +export namespace GetLoyaltyBalanceProgramsPidActiveBalanceResponse { + export type ActiveBalances = ActiveBalances.Item[]; + + export namespace ActiveBalances { + export interface Item { + /** Unique identifier of the balance entry. */ + id?: string | undefined; + /** Current balance amount. */ + amount?: number | undefined; + /** Timestamp when the balance was created. */ + createdAt?: string | undefined; + /** Timestamp when the balance expires (if applicable). */ + expiresAt?: string | undefined; + } + } +} diff --git a/src/api/resources/balance/types/GetLoyaltyBalanceProgramsPidTransactionHistoryResponse.ts b/src/api/resources/balance/types/GetLoyaltyBalanceProgramsPidTransactionHistoryResponse.ts index 741d358..b0e1102 100644 --- a/src/api/resources/balance/types/GetLoyaltyBalanceProgramsPidTransactionHistoryResponse.ts +++ b/src/api/resources/balance/types/GetLoyaltyBalanceProgramsPidTransactionHistoryResponse.ts @@ -26,6 +26,8 @@ export namespace GetLoyaltyBalanceProgramsPidTransactionHistoryResponse { export interface Item { /** The transaction amount. */ amount?: number | undefined; + /** The type of the transaction. */ + transactionType?: Item.TransactionType | undefined; /** Expiration date of the balance associated with this transaction. */ balanceExpirationDate?: string | undefined; /** Timestamp when the transaction was canceled, if applicable. */ @@ -45,5 +47,14 @@ export namespace GetLoyaltyBalanceProgramsPidTransactionHistoryResponse { /** Current status of the transaction (e.g., pending, completed, rejected). */ status?: string | undefined; } + + export namespace Item { + /** The type of the transaction. */ + export const TransactionType = { + Credit: "credit", + Debit: "debit", + } as const; + export type TransactionType = (typeof TransactionType)[keyof typeof TransactionType]; + } } } diff --git a/src/api/resources/balance/types/GetSubscriptionBalancesResponse.ts b/src/api/resources/balance/types/GetSubscriptionBalancesResponse.ts index 01c0686..467238f 100644 --- a/src/api/resources/balance/types/GetSubscriptionBalancesResponse.ts +++ b/src/api/resources/balance/types/GetSubscriptionBalancesResponse.ts @@ -1,6 +1,11 @@ // This file was auto-generated by Fern from our API Definition. export interface GetSubscriptionBalancesResponse { + /** Unique identifier of the loyalty program. */ + loyaltyProgramId?: string | undefined; + /** Unique identifier of the contact. */ + contactId?: number | undefined; + /** Aggregate balance per balance definition. */ balance?: GetSubscriptionBalancesResponse.Balance.Item[] | undefined; } @@ -9,9 +14,9 @@ export namespace GetSubscriptionBalancesResponse { export namespace Balance { export interface Item { - /** balance definition ID */ + /** Balance definition ID. */ balanceDefinitionId?: string | undefined; - /** Unique identifier for the balance definition associated with this aggregate balance */ + /** Aggregate balance value for this definition. */ value?: number | undefined; } } diff --git a/src/api/resources/balance/types/PostLoyaltyBalanceProgramsPidSubscriptionsCidBalancesResponse.ts b/src/api/resources/balance/types/PostLoyaltyBalanceProgramsPidSubscriptionsCidBalancesResponse.ts index 97d48f7..7971a16 100644 --- a/src/api/resources/balance/types/PostLoyaltyBalanceProgramsPidSubscriptionsCidBalancesResponse.ts +++ b/src/api/resources/balance/types/PostLoyaltyBalanceProgramsPidSubscriptionsCidBalancesResponse.ts @@ -1,22 +1,22 @@ // This file was auto-generated by Fern from our API Definition. export interface PostLoyaltyBalanceProgramsPidSubscriptionsCidBalancesResponse { - /** The current amount available in the balance */ + /** Unique identifier for the balance. */ + id?: string | undefined; + /** The current amount available in the balance. */ amount?: number | undefined; - /** balance definition ID */ - balanceDefinitionId?: string | undefined; - /** Timestamp of when the balance was last consumed */ - consumedAt?: string | undefined; - /** contact ID */ + /** Loyalty program ID. */ + loyaltyProgramId?: string | undefined; + /** Organization ID. */ + organizationId?: number | undefined; + /** Contact ID. */ contactId?: number | undefined; - /** Timestamp of when the balance was created */ + /** Balance definition ID. */ + balanceDefinitionId?: string | undefined; + /** Timestamp of when the balance was created. */ createdAt?: string | undefined; - /** Expiration timestamp of the balance */ + /** Expiration timestamp of the balance. */ expiresAt?: string | undefined; - /** Unique identifier for the balance */ - id?: string | undefined; - /** loyalty program ID */ - loyaltyProgramId?: string | undefined; - /** organization ID */ - organizationId?: number | undefined; + /** Timestamp of when the balance was last consumed. */ + consumedAt?: string | undefined; } diff --git a/src/api/resources/balance/types/index.ts b/src/api/resources/balance/types/index.ts index 5714e84..54867f8 100644 --- a/src/api/resources/balance/types/index.ts +++ b/src/api/resources/balance/types/index.ts @@ -5,7 +5,11 @@ export * from "./GetBalanceDefinitionListRequestVersion.js"; export * from "./GetBalanceDefinitionListResponse.js"; export * from "./GetBalanceDefinitionRequestVersion.js"; export * from "./GetBalanceLimitRequestVersion.js"; +export * from "./GetContactBalancesRequestSort.js"; +export * from "./GetContactBalancesRequestSortField.js"; export * from "./GetContactBalancesResponse.js"; +export * from "./GetLoyaltyBalanceProgramsPidActiveBalanceRequestSort.js"; +export * from "./GetLoyaltyBalanceProgramsPidActiveBalanceResponse.js"; export * from "./GetLoyaltyBalanceProgramsPidTransactionHistoryRequestSort.js"; export * from "./GetLoyaltyBalanceProgramsPidTransactionHistoryRequestStatus.js"; export * from "./GetLoyaltyBalanceProgramsPidTransactionHistoryRequestTransactionType.js"; diff --git a/src/api/resources/companies/client/Client.ts b/src/api/resources/companies/client/Client.ts index 025cc1c..e2866b6 100644 --- a/src/api/resources/companies/client/Client.ts +++ b/src/api/resources/companies/client/Client.ts @@ -24,6 +24,8 @@ export class CompaniesClient { } /** + * Retrieve a paginated list of companies with optional filtering, sorting, and search capabilities. Results are sorted by creation date in descending order by default, and can be filtered by attributes, linked contacts, linked deals, or modification/creation timestamps. + * * @param {Brevo.GetCompaniesRequest} request * @param {CompaniesClient.RequestOptions} requestOptions - Request-specific configuration. * @@ -43,10 +45,19 @@ export class CompaniesClient { request: Brevo.GetCompaniesRequest = {}, requestOptions?: CompaniesClient.RequestOptions, ): Promise> { - const { filters, linkedContactsIds, linkedDealsIds, modifiedSince, createdSince, page, limit, sort, sortBy } = - request; + const { + "filters[attributes.name]": filtersAttributesName, + linkedContactsIds, + linkedDealsIds, + modifiedSince, + createdSince, + page, + limit, + sort, + sortBy, + } = request; const _queryParams: Record = { - filters, + "filters[attributes.name]": filtersAttributesName, linkedContactsIds, linkedDealsIds, modifiedSince, @@ -71,7 +82,11 @@ export class CompaniesClient { ), method: "GET", headers: _headers, - queryParameters: { ..._queryParams, ...requestOptions?.queryParams }, + queryString: core.url + .queryBuilder() + .addMany(_queryParams) + .mergeAdditional(requestOptions?.queryParams) + .build(), timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, abortSignal: requestOptions?.abortSignal, @@ -99,6 +114,8 @@ export class CompaniesClient { } /** + * Create a new CRM company with the specified name, attributes, and optional associations to contacts and deals. The company name is required, and you can optionally provide a country code when a phone number attribute is included. + * * @param {Brevo.PostCompaniesRequest} request * @param {CompaniesClient.RequestOptions} requestOptions - Request-specific configuration. * @@ -136,7 +153,7 @@ export class CompaniesClient { method: "POST", headers: _headers, contentType: "application/json", - queryParameters: requestOptions?.queryParams, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), requestType: "json", body: request, timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, @@ -214,7 +231,7 @@ export class CompaniesClient { ), method: "POST", headers: _headers, - queryParameters: requestOptions?.queryParams, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), requestType: "file", duplex: _maybeEncodedRequest.duplex, body: _maybeEncodedRequest.body, @@ -245,6 +262,8 @@ export class CompaniesClient { } /** + * Link or unlink contacts and deals with a specific company in a single request. You can simultaneously link new contacts/deals and unlink existing ones by providing the respective ID arrays in the request body. + * * @param {Brevo.PatchCompaniesLinkUnlinkIdRequest} request * @param {CompaniesClient.RequestOptions} requestOptions - Request-specific configuration. * @@ -285,7 +304,7 @@ export class CompaniesClient { method: "PATCH", headers: _headers, contentType: "application/json", - queryParameters: requestOptions?.queryParams, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), requestType: "json", body: _body, timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, @@ -315,6 +334,8 @@ export class CompaniesClient { } /** + * Retrieve the full details of a single company by its identifier, including its attributes, linked contacts, and linked deals. Returns a 404 error if the company does not exist, or a 403 error if the user lacks permission to view the company. + * * @param {Brevo.GetCompaniesIdRequest} request * @param {CompaniesClient.RequestOptions} requestOptions - Request-specific configuration. * @@ -353,7 +374,7 @@ export class CompaniesClient { ), method: "GET", headers: _headers, - queryParameters: requestOptions?.queryParams, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, abortSignal: requestOptions?.abortSignal, @@ -383,6 +404,8 @@ export class CompaniesClient { } /** + * Permanently delete a company by its identifier. The requesting user must be the company owner or have manage permission on companies; otherwise, a 403 Forbidden error is returned. + * * @param {Brevo.DeleteCompaniesIdRequest} request * @param {CompaniesClient.RequestOptions} requestOptions - Request-specific configuration. * @@ -421,7 +444,7 @@ export class CompaniesClient { ), method: "DELETE", headers: _headers, - queryParameters: requestOptions?.queryParams, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, abortSignal: requestOptions?.abortSignal, @@ -451,6 +474,8 @@ export class CompaniesClient { } /** + * Update an existing company''s attributes, name, linked contacts, or linked deals. Note that passing `linkedContactsIds` or `linkedDealsIds` replaces the entire list of associations, so omitted IDs will be removed. The company name cannot be set to an empty string. + * * @param {Brevo.PatchCompaniesIdRequest} request * @param {CompaniesClient.RequestOptions} requestOptions - Request-specific configuration. * @@ -490,7 +515,7 @@ export class CompaniesClient { method: "PATCH", headers: _headers, contentType: "application/json", - queryParameters: requestOptions?.queryParams, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), requestType: "json", body: _body, timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, @@ -522,6 +547,8 @@ export class CompaniesClient { } /** + * Create a new custom attribute for companies or deals. The attribute label must be unique within the object type, cannot exceed 50 characters, and cannot use reserved names. For `single-select` or `multi-choice` attribute types, you must also provide the `optionsLabels` array. + * * @param {Brevo.PostCrmAttributesRequest} request * @param {CompaniesClient.RequestOptions} requestOptions - Request-specific configuration. * @@ -561,7 +588,7 @@ export class CompaniesClient { method: "POST", headers: _headers, contentType: "application/json", - queryParameters: requestOptions?.queryParams, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), requestType: "json", body: request, timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, @@ -591,6 +618,8 @@ export class CompaniesClient { } /** + * Delete an existing custom attribute by its identifier. This permanently removes the attribute definition and cleans up all references to it across companies or deals. System-default and non-editable attributes cannot be deleted. + * * @param {Brevo.DeleteCrmAttributesIdRequest} request * @param {CompaniesClient.RequestOptions} requestOptions - Request-specific configuration. * @@ -629,7 +658,7 @@ export class CompaniesClient { ), method: "DELETE", headers: _headers, - queryParameters: requestOptions?.queryParams, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, abortSignal: requestOptions?.abortSignal, @@ -659,6 +688,8 @@ export class CompaniesClient { } /** + * Update an existing custom attribute''s label or options. You can rename the attribute label or modify the available options for `single-select` and `multi-choice` attribute types. System-default attributes cannot be modified except for specific editable fields. + * * @param {Brevo.PatchCrmAttributesIdRequest} request * @param {CompaniesClient.RequestOptions} requestOptions - Request-specific configuration. * @@ -698,7 +729,7 @@ export class CompaniesClient { method: "PATCH", headers: _headers, contentType: "application/json", - queryParameters: requestOptions?.queryParams, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), requestType: "json", body: _body, timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, @@ -730,8 +761,12 @@ export class CompaniesClient { } /** + * Retrieve the list of all attributes defined for companies, including both system-default and custom attributes. Each attribute includes its label, internal name, type, required status, and available options for select-type attributes. + * * @param {CompaniesClient.RequestOptions} requestOptions - Request-specific configuration. * + * @throws {@link Brevo.BadRequestError} + * * @example * await client.companies.getCompanyAttributes() */ @@ -759,7 +794,7 @@ export class CompaniesClient { ), method: "GET", headers: _headers, - queryParameters: requestOptions?.queryParams, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, abortSignal: requestOptions?.abortSignal, @@ -774,11 +809,16 @@ export class CompaniesClient { } if (_response.error.reason === "status-code") { - throw new errors.BrevoError({ - statusCode: _response.error.statusCode, - body: _response.error.body, - rawResponse: _response.rawResponse, - }); + switch (_response.error.statusCode) { + case 400: + throw new Brevo.BadRequestError(_response.error.body as unknown, _response.rawResponse); + default: + throw new errors.BrevoError({ + statusCode: _response.error.statusCode, + body: _response.error.body, + rawResponse: _response.rawResponse, + }); + } } return handleNonStatusCodeError(_response.error, _response.rawResponse, "GET", "/crm/attributes/companies"); diff --git a/src/api/resources/companies/client/requests/GetCompaniesRequest.ts b/src/api/resources/companies/client/requests/GetCompaniesRequest.ts index 3e9bb7a..0c8bcc0 100644 --- a/src/api/resources/companies/client/requests/GetCompaniesRequest.ts +++ b/src/api/resources/companies/client/requests/GetCompaniesRequest.ts @@ -7,15 +7,15 @@ import type * as Brevo from "../../../../index.js"; * {} */ export interface GetCompaniesRequest { - /** Filter by attrbutes. If you have filter for owner on your side please send it as {"attributes.owner":"6299dcf3874a14eacbc65c46"} */ - filters?: string; + /** Filter by attributes. If you have a filter for the owner on your side please send it as filters[attributes.owner] and utilize the account email for the filtering. */ + "filters[attributes.name]"?: string; /** Filter by linked contacts ids */ linkedContactsIds?: number; /** Filter by linked Deals ids */ linkedDealsIds?: string; - /** Filter (urlencoded) the contacts modified after a given UTC date-time (YYYY-MM-DDTHH:mm:ss.SSSZ). Prefer to pass your timezone in date-time format for accurate result. */ + /** Filter (urlencoded) the companies modified after a given UTC date-time (YYYY-MM-DDTHH:mm:ss.SSSZ). Prefer to pass your timezone in date-time format for accurate result. */ modifiedSince?: string; - /** Filter (urlencoded) the contacts created after a given UTC date-time (YYYY-MM-DDTHH:mm:ss.SSSZ). Prefer to pass your timezone in date-time format for accurate result. */ + /** Filter (urlencoded) the companies created after a given UTC date-time (YYYY-MM-DDTHH:mm:ss.SSSZ). Prefer to pass your timezone in date-time format for accurate result. */ createdSince?: string; /** Index of the first document of the page */ page?: number; diff --git a/src/api/resources/companies/client/requests/PatchCompaniesIdRequest.ts b/src/api/resources/companies/client/requests/PatchCompaniesIdRequest.ts index c4cc485..b5212a1 100644 --- a/src/api/resources/companies/client/requests/PatchCompaniesIdRequest.ts +++ b/src/api/resources/companies/client/requests/PatchCompaniesIdRequest.ts @@ -14,7 +14,7 @@ export interface PatchCompaniesIdRequest { countryCode?: number; /** Warning - Using PATCH on linkedContactIds replaces the list of linked contacts. Omitted IDs will be removed. */ linkedContactsIds?: number[]; - /** Warning - Using PATCH on linkedDealsIds replaces the list of linked contacts. Omitted IDs will be removed. */ + /** Warning - Using PATCH on linkedDealsIds replaces the list of linked deals. Omitted IDs will be removed. */ linkedDealsIds?: string[]; /** Name of company */ name?: string; diff --git a/src/api/resources/companies/client/requests/PostCompaniesImportRequest.ts b/src/api/resources/companies/client/requests/PostCompaniesImportRequest.ts index 212b9d3..4470149 100644 --- a/src/api/resources/companies/client/requests/PostCompaniesImportRequest.ts +++ b/src/api/resources/companies/client/requests/PostCompaniesImportRequest.ts @@ -7,7 +7,7 @@ import type * as core from "../../../../../core/index.js"; * {} */ export interface PostCompaniesImportRequest { - /** The CSV file to upload.The file should have the first row as the mapping attribute. Some default attribute names are (a) company_id [brevo mongoID to update deals] (b) associated_contact (c) associated_deal (f) any other attribute with internal name */ + /** The CSV file to upload.The file should have the first row as the mapping attribute. Some default attribute names are (a) company_id [brevo mongoID to update companies] (b) associated_contact (c) associated_deal (f) any other attribute with internal name */ file?: core.file.Uploadable | undefined; /** * The mapping options in JSON format. Here is an example of the JSON structure: ```json { diff --git a/src/api/resources/companies/client/requests/PostCrmAttributesRequest.ts b/src/api/resources/companies/client/requests/PostCrmAttributesRequest.ts index 8a617eb..4de1e5a 100644 --- a/src/api/resources/companies/client/requests/PostCrmAttributesRequest.ts +++ b/src/api/resources/companies/client/requests/PostCrmAttributesRequest.ts @@ -15,7 +15,7 @@ export interface PostCrmAttributesRequest { description?: string; /** The label for the attribute (max 50 characters, cannot be empty) */ label: string; - /** The type of object the attribute belongs to (prefilled with `companies`, mandatory) */ + /** The type of object the attribute belongs to. Must be either `companies` or `deals`. */ objectType: PostCrmAttributesRequest.ObjectType; /** Options for multi-choice or single-select attributes */ optionsLabels?: string[]; @@ -33,7 +33,7 @@ export namespace PostCrmAttributesRequest { MultiChoice: "multi-choice", } as const; export type AttributeType = (typeof AttributeType)[keyof typeof AttributeType]; - /** The type of object the attribute belongs to (prefilled with `companies`, mandatory) */ + /** The type of object the attribute belongs to. Must be either `companies` or `deals`. */ export const ObjectType = { Companies: "companies", Deals: "deals", diff --git a/src/api/resources/companies/types/GetCrmAttributesCompaniesResponseItem.ts b/src/api/resources/companies/types/GetCrmAttributesCompaniesResponseItem.ts index 7ddbd7d..5947558 100644 --- a/src/api/resources/companies/types/GetCrmAttributesCompaniesResponseItem.ts +++ b/src/api/resources/companies/types/GetCrmAttributesCompaniesResponseItem.ts @@ -1,12 +1,30 @@ // This file was auto-generated by Fern from our API Definition. /** - * List of attributes + * Company attribute details */ export interface GetCrmAttributesCompaniesResponseItem { - attributeOptions?: Record[] | undefined; - attributeTypeName?: string | undefined; + /** Internal name of the attribute */ internalName?: string | undefined; - isRequired?: boolean | undefined; + /** Type of the attribute */ + attributeTypeName?: string | undefined; + /** Display label of the attribute */ label?: string | undefined; + /** Options for single-select or multi-choice attributes */ + attributeOptions?: GetCrmAttributesCompaniesResponseItem.AttributeOptions.Item[] | undefined; + /** Whether this attribute is required */ + isRequired?: boolean | undefined; + /** Whether this attribute value is read-only */ + isValueReadonly?: boolean | undefined; +} + +export namespace GetCrmAttributesCompaniesResponseItem { + export type AttributeOptions = AttributeOptions.Item[]; + + export namespace AttributeOptions { + export interface Item { + key?: string | undefined; + value?: string | undefined; + } + } } diff --git a/src/api/resources/contacts/client/Client.ts b/src/api/resources/contacts/client/Client.ts index df3e57e..9d3ddb8 100644 --- a/src/api/resources/contacts/client/Client.ts +++ b/src/api/resources/contacts/client/Client.ts @@ -23,6 +23,8 @@ export class ContactsClient { } /** + * Retrieve all contacts from your Brevo account with support for pagination, filtering, and sorting. Results default to 50 contacts per page (maximum 1000) sorted in descending order of creation, and can be filtered by modification date, creation date, contact IDs (up to 20), list IDs, segment ID, or contact attributes using the equals operator. Note that either listIds or segmentId can be passed but not both simultaneously. + * * @param {Brevo.GetContactsRequest} request * @param {ContactsClient.RequestOptions} requestOptions - Request-specific configuration. * @@ -43,13 +45,14 @@ export class ContactsClient { request: Brevo.GetContactsRequest = {}, requestOptions?: ContactsClient.RequestOptions, ): Promise> { - const { limit, offset, modifiedSince, createdSince, sort, segmentId, listIds, filter } = request; + const { limit, offset, modifiedSince, createdSince, sort, ids, segmentId, listIds, filter } = request; const _queryParams: Record = { limit, offset, modifiedSince, createdSince, sort: sort != null ? sort : undefined, + ids, segmentId, listIds, filter, @@ -69,7 +72,11 @@ export class ContactsClient { ), method: "GET", headers: _headers, - queryParameters: { ..._queryParams, ...requestOptions?.queryParams }, + queryString: core.url + .queryBuilder() + .addMany(_queryParams) + .mergeAdditional(requestOptions?.queryParams) + .build(), timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, abortSignal: requestOptions?.abortSignal, @@ -142,7 +149,7 @@ export class ContactsClient { method: "POST", headers: _headers, contentType: "application/json", - queryParameters: requestOptions?.queryParams, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), requestType: "json", body: request, timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, @@ -180,8 +187,12 @@ export class ContactsClient { } /** + * Retrieve all contact attributes defined in your Brevo account, grouped by category (normal, transactional, category, calculated, global). Each attribute includes its name, type, and category, along with enumeration values for category-type attributes and options for multiple-choice-type attributes. + * * @param {ContactsClient.RequestOptions} requestOptions - Request-specific configuration. * + * @throws {@link Brevo.BadRequestError} + * * @example * await client.contacts.getAttributes() */ @@ -209,7 +220,7 @@ export class ContactsClient { ), method: "GET", headers: _headers, - queryParameters: requestOptions?.queryParams, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, abortSignal: requestOptions?.abortSignal, @@ -221,17 +232,24 @@ export class ContactsClient { } if (_response.error.reason === "status-code") { - throw new errors.BrevoError({ - statusCode: _response.error.statusCode, - body: _response.error.body, - rawResponse: _response.rawResponse, - }); + switch (_response.error.statusCode) { + case 400: + throw new Brevo.BadRequestError(_response.error.body as unknown, _response.rawResponse); + default: + throw new errors.BrevoError({ + statusCode: _response.error.statusCode, + body: _response.error.body, + rawResponse: _response.rawResponse, + }); + } } return handleNonStatusCodeError(_response.error, _response.rawResponse, "GET", "/contacts/attributes"); } /** + * Create a new contact attribute under the specified category and name. The required body properties depend on the category: use "type" for normal, transactional, or category attributes; use "value" for calculated or global attributes; use "enumeration" for category attributes; and use "multiCategoryOptions" for normal multiple-choice attributes. None of the category or multicategory option values can exceed 200 characters. + * * @param {Brevo.CreateAttributeRequest} request * @param {ContactsClient.RequestOptions} requestOptions - Request-specific configuration. * @@ -271,7 +289,7 @@ export class ContactsClient { method: "POST", headers: _headers, contentType: "application/json", - queryParameters: requestOptions?.queryParams, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), requestType: "json", body: _body, timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, @@ -306,6 +324,8 @@ export class ContactsClient { } /** + * Update an existing contact attribute identified by its category and name. For category-type attributes, you can update the enumeration values; for calculated or global attributes, update the computed value formula; and for normal multiple-choice attributes, update the multicategory options. None of the category or multicategory option values can exceed 200 characters. + * * @param {Brevo.UpdateAttributeRequest} request * @param {ContactsClient.RequestOptions} requestOptions - Request-specific configuration. * @@ -346,7 +366,7 @@ export class ContactsClient { method: "PUT", headers: _headers, contentType: "application/json", - queryParameters: requestOptions?.queryParams, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), requestType: "json", body: _body, timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, @@ -383,6 +403,8 @@ export class ContactsClient { } /** + * Permanently delete an existing contact attribute by its category and name. The attribute must exist in the specified category (normal, transactional, category, calculated, or global), otherwise a 404 error is returned. + * * @param {Brevo.DeleteAttributeRequest} request * @param {ContactsClient.RequestOptions} requestOptions - Request-specific configuration. * @@ -422,7 +444,7 @@ export class ContactsClient { ), method: "DELETE", headers: _headers, - queryParameters: requestOptions?.queryParams, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, abortSignal: requestOptions?.abortSignal, @@ -457,6 +479,8 @@ export class ContactsClient { } /** + * Delete a specific option from an existing multiple-choice contact attribute. The attribute type must be "multiple-choice", and both the attribute name and the option to delete must already exist in your account. + * * @param {Brevo.DeleteMultiAttributeOptionsRequest} request * @param {ContactsClient.RequestOptions} requestOptions - Request-specific configuration. * @@ -497,7 +521,7 @@ export class ContactsClient { ), method: "DELETE", headers: _headers, - queryParameters: requestOptions?.queryParams, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, abortSignal: requestOptions?.abortSignal, @@ -532,6 +556,8 @@ export class ContactsClient { } /** + * Update multiple contacts in a single API call by passing an array of contact objects. Each contact in the array must be identified by one of: email, id, or sms (only one identifier per contact). You can update attributes, blacklist status, list memberships, ext_id, and transactional email forbidden senders for each contact in the batch. + * * @param {Brevo.UpdateBatchContactsRequest} request * @param {ContactsClient.RequestOptions} requestOptions - Request-specific configuration. * @@ -567,7 +593,7 @@ export class ContactsClient { method: "POST", headers: _headers, contentType: "application/json", - queryParameters: requestOptions?.queryParams, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), requestType: "json", body: request, timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, @@ -639,7 +665,7 @@ export class ContactsClient { method: "POST", headers: _headers, contentType: "application/json", - queryParameters: requestOptions?.queryParams, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), requestType: "json", body: request, timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, @@ -714,7 +740,7 @@ export class ContactsClient { method: "POST", headers: _headers, contentType: "application/json", - queryParameters: requestOptions?.queryParams, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), requestType: "json", body: request, timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, @@ -795,7 +821,11 @@ export class ContactsClient { ), method: "GET", headers: _headers, - queryParameters: { ..._queryParams, ...requestOptions?.queryParams }, + queryString: core.url + .queryBuilder() + .addMany(_queryParams) + .mergeAdditional(requestOptions?.queryParams) + .build(), timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, abortSignal: requestOptions?.abortSignal, @@ -823,6 +853,8 @@ export class ContactsClient { } /** + * Create a new folder to organize your contact lists. Folders serve as containers for grouping related lists together. The folder name is required and must be provided in the request body. + * * @param {Brevo.CreateUpdateFolder} request * @param {ContactsClient.RequestOptions} requestOptions - Request-specific configuration. * @@ -858,7 +890,7 @@ export class ContactsClient { method: "POST", headers: _headers, contentType: "application/json", - queryParameters: requestOptions?.queryParams, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), requestType: "json", body: request, timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, @@ -930,7 +962,7 @@ export class ContactsClient { ), method: "GET", headers: _headers, - queryParameters: requestOptions?.queryParams, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, abortSignal: requestOptions?.abortSignal, @@ -960,6 +992,8 @@ export class ContactsClient { } /** + * Update the name of an existing folder identified by its ID. The new folder name must be provided in the request body. Returns a 404 error if the folder ID does not exist. + * * @param {Brevo.UpdateFolderRequest} request * @param {ContactsClient.RequestOptions} requestOptions - Request-specific configuration. * @@ -1000,7 +1034,7 @@ export class ContactsClient { method: "PUT", headers: _headers, contentType: "application/json", - queryParameters: requestOptions?.queryParams, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), requestType: "json", body: _body, timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, @@ -1032,6 +1066,8 @@ export class ContactsClient { } /** + * Permanently delete a folder identified by its ID. Deleting a folder will also delete all the contact lists contained within it. This action cannot be undone. + * * @param {Brevo.DeleteFolderRequest} request * @param {ContactsClient.RequestOptions} requestOptions - Request-specific configuration. * @@ -1070,7 +1106,7 @@ export class ContactsClient { ), method: "DELETE", headers: _headers, - queryParameters: requestOptions?.queryParams, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, abortSignal: requestOptions?.abortSignal, @@ -1152,7 +1188,11 @@ export class ContactsClient { ), method: "GET", headers: _headers, - queryParameters: { ..._queryParams, ...requestOptions?.queryParams }, + queryString: core.url + .queryBuilder() + .addMany(_queryParams) + .mergeAdditional(requestOptions?.queryParams) + .build(), timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, abortSignal: requestOptions?.abortSignal, @@ -1224,7 +1264,7 @@ export class ContactsClient { method: "POST", headers: _headers, contentType: "application/json", - queryParameters: requestOptions?.queryParams, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), requestType: "json", body: request, timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, @@ -1298,7 +1338,11 @@ export class ContactsClient { ), method: "GET", headers: _headers, - queryParameters: { ..._queryParams, ...requestOptions?.queryParams }, + queryString: core.url + .queryBuilder() + .addMany(_queryParams) + .mergeAdditional(requestOptions?.queryParams) + .build(), timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, abortSignal: requestOptions?.abortSignal, @@ -1326,6 +1370,8 @@ export class ContactsClient { } /** + * Create a new contact list inside a specified folder. Both the list name and the parent folder ID are required. The newly created list will be empty and ready to receive contacts via the add contacts endpoint. + * * @param {Brevo.CreateListRequest} request * @param {ContactsClient.RequestOptions} requestOptions - Request-specific configuration. * @@ -1364,7 +1410,7 @@ export class ContactsClient { method: "POST", headers: _headers, contentType: "application/json", - queryParameters: requestOptions?.queryParams, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), requestType: "json", body: request, timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, @@ -1394,6 +1440,8 @@ export class ContactsClient { } /** + * Retrieve the details of a specific contact list by its ID, including its name, folder ID, creation date, subscriber counts, and campaign statistics. You can optionally filter campaign statistics by providing startDate and endDate parameters (both must be used together in YYYY-MM-DD format). + * * @param {Brevo.GetListRequest} request * @param {ContactsClient.RequestOptions} requestOptions - Request-specific configuration. * @@ -1436,7 +1484,11 @@ export class ContactsClient { ), method: "GET", headers: _headers, - queryParameters: { ..._queryParams, ...requestOptions?.queryParams }, + queryString: core.url + .queryBuilder() + .addMany(_queryParams) + .mergeAdditional(requestOptions?.queryParams) + .build(), timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, abortSignal: requestOptions?.abortSignal, @@ -1466,6 +1518,8 @@ export class ContactsClient { } /** + * Update an existing contact list identified by its ID. You can update the list name, move it to a different folder by providing a new folderId, or both. Only one of the two parameters (name, folderId) needs to be provided per request. + * * @param {Brevo.UpdateListRequest} request * @param {ContactsClient.RequestOptions} requestOptions - Request-specific configuration. * @@ -1505,7 +1559,7 @@ export class ContactsClient { method: "PUT", headers: _headers, contentType: "application/json", - queryParameters: requestOptions?.queryParams, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), requestType: "json", body: _body, timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, @@ -1537,6 +1591,8 @@ export class ContactsClient { } /** + * Permanently delete a contact list identified by its ID. The contacts in the list are not deleted; they are only removed from this list. Returns a 404 error if the list ID does not exist. + * * @param {Brevo.DeleteListRequest} request * @param {ContactsClient.RequestOptions} requestOptions - Request-specific configuration. * @@ -1575,7 +1631,7 @@ export class ContactsClient { ), method: "DELETE", headers: _headers, - queryParameters: requestOptions?.queryParams, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, abortSignal: requestOptions?.abortSignal, @@ -1605,11 +1661,14 @@ export class ContactsClient { } /** + * Retrieve all contacts belonging to a specific list, identified by its list ID. Results are paginated with a default of 50 contacts per page (maximum 500) and sorted in descending order of creation. You can optionally filter contacts by their modification date using the modifiedSince parameter. + * * @param {Brevo.GetContactsFromListRequest} request * @param {ContactsClient.RequestOptions} requestOptions - Request-specific configuration. * * @throws {@link Brevo.BadRequestError} * @throws {@link Brevo.NotFoundError} + * @throws {@link Brevo.TooManyRequestsError} * * @example * await client.contacts.getContactsFromList({ @@ -1649,7 +1708,11 @@ export class ContactsClient { ), method: "GET", headers: _headers, - queryParameters: { ..._queryParams, ...requestOptions?.queryParams }, + queryString: core.url + .queryBuilder() + .addMany(_queryParams) + .mergeAdditional(requestOptions?.queryParams) + .build(), timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, abortSignal: requestOptions?.abortSignal, @@ -1666,6 +1729,11 @@ export class ContactsClient { throw new Brevo.BadRequestError(_response.error.body as unknown, _response.rawResponse); case 404: throw new Brevo.NotFoundError(_response.error.body as unknown, _response.rawResponse); + case 429: + throw new Brevo.TooManyRequestsError( + _response.error.body as Brevo.ErrorModel, + _response.rawResponse, + ); default: throw new errors.BrevoError({ statusCode: _response.error.statusCode, @@ -1742,7 +1810,7 @@ export class ContactsClient { method: "POST", headers: _headers, contentType: "application/json", - queryParameters: requestOptions?.queryParams, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), requestType: "json", body: _body, timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, @@ -1845,7 +1913,7 @@ export class ContactsClient { method: "POST", headers: _headers, contentType: "application/json", - queryParameters: requestOptions?.queryParams, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), requestType: "json", body: _body, timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, @@ -1882,6 +1950,8 @@ export class ContactsClient { } /** + * Retrieve all contact segments defined in your Brevo account with support for pagination and sorting. Results default to 10 segments per page (maximum 50) sorted in descending order of creation. Each segment includes its ID, name, category name, and last update timestamp. + * * @param {Brevo.GetSegmentsRequest} request * @param {ContactsClient.RequestOptions} requestOptions - Request-specific configuration. * @@ -1922,7 +1992,11 @@ export class ContactsClient { ), method: "GET", headers: _headers, - queryParameters: { ..._queryParams, ...requestOptions?.queryParams }, + queryString: core.url + .queryBuilder() + .addMany(_queryParams) + .mergeAdditional(requestOptions?.queryParams) + .build(), timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, abortSignal: requestOptions?.abortSignal, @@ -1997,7 +2071,11 @@ export class ContactsClient { ), method: "GET", headers: _headers, - queryParameters: { ..._queryParams, ...requestOptions?.queryParams }, + queryString: core.url + .queryBuilder() + .addMany(_queryParams) + .mergeAdditional(requestOptions?.queryParams) + .build(), timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, abortSignal: requestOptions?.abortSignal, @@ -2074,7 +2152,11 @@ export class ContactsClient { method: "PUT", headers: _headers, contentType: "application/json", - queryParameters: { ..._queryParams, ...requestOptions?.queryParams }, + queryString: core.url + .queryBuilder() + .addMany(_queryParams) + .mergeAdditional(requestOptions?.queryParams) + .build(), requestType: "json", body: _body, timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, @@ -2155,7 +2237,11 @@ export class ContactsClient { ), method: "DELETE", headers: _headers, - queryParameters: { ..._queryParams, ...requestOptions?.queryParams }, + queryString: core.url + .queryBuilder() + .addMany(_queryParams) + .mergeAdditional(requestOptions?.queryParams) + .build(), timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, abortSignal: requestOptions?.abortSignal, @@ -2190,6 +2276,8 @@ export class ContactsClient { } /** + * Retrieve email campaign statistics for a specific contact identified by email address or numeric ID. Statistics include messages sent, opens, clicks, hard/soft bounces, deliveries, unsubscriptions, complaints, and transactional attributes. By default, data covers the last 90 days; use startDate and endDate parameters (YYYY-MM-DD) to specify a custom range with a maximum span of 90 days. + * * @param {Brevo.GetContactStatsRequest} request * @param {ContactsClient.RequestOptions} requestOptions - Request-specific configuration. * @@ -2232,7 +2320,11 @@ export class ContactsClient { ), method: "GET", headers: _headers, - queryParameters: { ..._queryParams, ...requestOptions?.queryParams }, + queryString: core.url + .queryBuilder() + .addMany(_queryParams) + .mergeAdditional(requestOptions?.queryParams) + .build(), timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, abortSignal: requestOptions?.abortSignal, diff --git a/src/api/resources/contacts/client/requests/CreateContactRequest.ts b/src/api/resources/contacts/client/requests/CreateContactRequest.ts index 85077ff..70a63f5 100644 --- a/src/api/resources/contacts/client/requests/CreateContactRequest.ts +++ b/src/api/resources/contacts/client/requests/CreateContactRequest.ts @@ -21,6 +21,10 @@ export interface CreateContactRequest { smtpBlacklistSender?: string[]; /** Facilitate to update the existing contact in the same request (updateEnabled = true) */ updateEnabled?: boolean; + /** When true, if the contact being created shares an identifier (email, SMS, ext_id, whatsapp, landline) with an existing contact, the two contacts are force-merged. The contact with the most recent `last_modified` timestamp is retained; the other is deleted. When false (default), a 4xx error is returned on identifier conflict. */ + forceMerge?: boolean; + /** When true, the response returns the `id` of the surviving contact after merge. */ + getId?: boolean; } export namespace CreateContactRequest { diff --git a/src/api/resources/contacts/client/requests/GetContactInfoRequest.ts b/src/api/resources/contacts/client/requests/GetContactInfoRequest.ts index 0df5b8e..5f2ee5a 100644 --- a/src/api/resources/contacts/client/requests/GetContactInfoRequest.ts +++ b/src/api/resources/contacts/client/requests/GetContactInfoRequest.ts @@ -13,8 +13,8 @@ export interface GetContactInfoRequest { identifier: Brevo.GetContactInfoRequestIdentifier; /** email_id for Email, phone_id for SMS attribute, contact_id for ID of the contact, ext_id for EXT_ID attribute, whatsapp_id for WHATSAPP attribute, landline_number_id for LANDLINE_NUMBER attribute */ identifierType?: Brevo.GetContactInfoRequestIdentifierType; - /** **Mandatory if endDate is used.** Starting date (YYYY-MM-DD) of the statistic events specific to campaigns. Must be lower than equal to endDate */ + /** **Mandatory if endDate is used.** Starting date (YYYY-MM-DD) of the statistic events specific to campaigns. Must be lower than equal to endDate. Must not be greater than the current date. */ startDate?: string; - /** **Mandatory if startDate is used.** Ending date (YYYY-MM-DD) of the statistic events specific to campaigns. Must be greater than equal to startDate. */ + /** **Mandatory if startDate is used.** Ending date (YYYY-MM-DD) of the statistic events specific to campaigns. Must be greater than equal to startDate. Must not be greater than the current date. */ endDate?: string; } diff --git a/src/api/resources/contacts/client/requests/GetContactStatsRequest.ts b/src/api/resources/contacts/client/requests/GetContactStatsRequest.ts index 0324ab0..ee47c0a 100644 --- a/src/api/resources/contacts/client/requests/GetContactStatsRequest.ts +++ b/src/api/resources/contacts/client/requests/GetContactStatsRequest.ts @@ -11,8 +11,8 @@ import type * as Brevo from "../../../../index.js"; export interface GetContactStatsRequest { /** Email (urlencoded) OR ID of the contact */ identifier: Brevo.GetContactStatsRequestIdentifier; - /** **Mandatory if endDate is used.** Starting date (YYYY-MM-DD) of the statistic events specific to campaigns. Must be lower than equal to endDate */ + /** **Mandatory if endDate is used.** Starting date (YYYY-MM-DD) of the statistic events specific to campaigns. Must be lower than equal to endDate. Must not be greater than the current date. */ startDate?: string; - /** **Mandatory if startDate is used.** Ending date (YYYY-MM-DD) of the statistic events specific to campaigns. Must be greater than equal to startDate. Maximum difference between startDate and endDate should not be greater than 90 days */ + /** **Mandatory if startDate is used.** Ending date (YYYY-MM-DD) of the statistic events specific to campaigns. Must be greater than equal to startDate. Must not be greater than the current date. Maximum difference between startDate and endDate should not be greater than 90 days. */ endDate?: string; } diff --git a/src/api/resources/contacts/client/requests/GetContactsRequest.ts b/src/api/resources/contacts/client/requests/GetContactsRequest.ts index fad0d39..44a5801 100644 --- a/src/api/resources/contacts/client/requests/GetContactsRequest.ts +++ b/src/api/resources/contacts/client/requests/GetContactsRequest.ts @@ -17,7 +17,9 @@ export interface GetContactsRequest { createdSince?: string; /** Sort the results in the ascending/descending order of record creation. Default order is **descending** if `sort` is not passed */ sort?: Brevo.GetContactsRequestSort; - /** Id of the segment. **Either listIds or segmentId can be passed.** */ + /** Filter by a list of contact IDs. You can pass a **maximum of 20 IDs**. All elements must be integers. */ + ids?: number | number[]; + /** Id of the segment. **Either listIds or segmentId can be passed.** Must be a positive integer (minimum value of 1). */ segmentId?: number; /** Ids of the list. **Either listIds or segmentId can be passed.** */ listIds?: number | number[]; diff --git a/src/api/resources/contacts/client/requests/GetListRequest.ts b/src/api/resources/contacts/client/requests/GetListRequest.ts index 8a5f023..5ce31af 100644 --- a/src/api/resources/contacts/client/requests/GetListRequest.ts +++ b/src/api/resources/contacts/client/requests/GetListRequest.ts @@ -9,7 +9,7 @@ export interface GetListRequest { /** Id of the list */ listId: number; - /** **Mandatory if endDate is used**. Ending (urlencoded) UTC date-time (YYYY-MM-DDTHH:mm:ss.SSSZ) to aggregate the sent email campaigns for a specific list id. **Prefer to pass your timezone in date-time format for accurate result** */ + /** **Mandatory if endDate is used**. Starting (urlencoded) UTC date-time (YYYY-MM-DDTHH:mm:ss.SSSZ) to aggregate the sent email campaigns for a specific list id. **Prefer to pass your timezone in date-time format for accurate result** */ startDate?: string; /** **Mandatory if startDate is used**. Ending (urlencoded) UTC date-time (YYYY-MM-DDTHH:mm:ss.SSSZ) to aggregate the sent email campaigns for a specific list id. **Prefer to pass your timezone in date-time format for accurate result** */ endDate?: string; diff --git a/src/api/resources/contacts/client/requests/UpdateContactRequest.ts b/src/api/resources/contacts/client/requests/UpdateContactRequest.ts index c67887b..1503193 100644 --- a/src/api/resources/contacts/client/requests/UpdateContactRequest.ts +++ b/src/api/resources/contacts/client/requests/UpdateContactRequest.ts @@ -9,9 +9,9 @@ import type * as Brevo from "../../../../index.js"; * } */ export interface UpdateContactRequest { - /** Email (urlencoded) OR ID of the contact OR EXT_ID attribute (urlencoded) OR its SMS attribute value OR its WHATSAPP attribute value OR its LANDLINE attribute value */ + /** Email (urlencoded) OR ID of the contact OR EXT_ID attribute (urlencoded) OR its SMS attribute value OR its WHATSAPP attribute value OR its LANDLINE_NUMBER attribute value */ identifier: Brevo.UpdateContactRequestIdentifier; - /** email_id for Email, contact_id for ID of the contact, ext_id for EXT_ID attribute, phone_id for SMS attribute, whatsapp_id for WHATSAPP attribute, landline_number_id for LANDLINE attribute */ + /** email_id for Email, contact_id for ID of the contact, ext_id for EXT_ID attribute, phone_id for SMS attribute, whatsapp_id for WHATSAPP attribute, landline_number_id for LANDLINE_NUMBER attribute */ identifierType?: Brevo.UpdateContactRequestIdentifierType; /** Pass the set of attributes to be updated. **These attributes must be present in your account**. To update existing email address of a contact with the new one please pass EMAIL in attributes. For example, **{ "EMAIL":"newemail@domain.com", "FNAME":"Ellie", "LNAME":"Roger", "COUNTRIES":["India","China"]}**. The attribute's parameter should be passed in capital letter while updating a contact. Values that don't match the attribute type (e.g. text or string in a date attribute) will be ignored .Keep in mind transactional attributes can be updated the same way as normal attributes. Mobile Number in **SMS** field should be passed with proper country code. For example: **{"SMS":"+91xxxxxxxxxx"} or {"SMS":"0091xxxxxxxxxx"}** */ attributes?: Record; @@ -27,6 +27,8 @@ export interface UpdateContactRequest { smtpBlacklistSender?: string[]; /** Ids of the lists to remove the contact from */ unlinkListIds?: number[]; + /** When true, if the contact being updated shares an identifier (email, SMS, ext_id, whatsapp, landline) with an existing contact, the two contacts are force-merged. The contact with the most recent `last_modified` timestamp is retained; the other is deleted. When false (default), a 4xx error is returned on identifier conflict. */ + forceMerge?: boolean; } export namespace UpdateContactRequest { diff --git a/src/api/resources/contacts/types/GetAttributesResponse.ts b/src/api/resources/contacts/types/GetAttributesResponse.ts index 3480d56..7d3de20 100644 --- a/src/api/resources/contacts/types/GetAttributesResponse.ts +++ b/src/api/resources/contacts/types/GetAttributesResponse.ts @@ -40,8 +40,10 @@ export namespace GetAttributesResponse { export interface Item { /** Label of the "category" type attribute */ label: string; - /** ID of Value of the "category" type attribute */ + /** Numeric ID of the "category" type attribute value. Set to 0 when the raw value cannot be converted to an integer (for example non-numeric values such as "en" or "fr"). Refer to `valueStr` for the original string representation. */ value: number; + /** String representation of the "category" type attribute value. Always contains the original value as stored. Use this field when the attribute value is non-numeric (e.g. "en", "fr") or when you need the exact string form alongside the numeric `value`. */ + valueStr: string; } } diff --git a/src/api/resources/contacts/types/GetContactInfoResponse.ts b/src/api/resources/contacts/types/GetContactInfoResponse.ts index 3123d63..9c0da83 100644 --- a/src/api/resources/contacts/types/GetContactInfoResponse.ts +++ b/src/api/resources/contacts/types/GetContactInfoResponse.ts @@ -17,6 +17,8 @@ export interface GetContactInfoResponse { modifiedAt: string; /** Blacklist status for SMS campaigns (true=blacklisted, false=not blacklisted) */ smsBlacklisted: boolean; + /** Blacklist status for WhatsApp campaigns (true=blacklisted, false=not blacklisted) */ + whatsappBlacklisted: boolean; /** Campaign statistics of the contact */ statistics: GetContactInfoResponse.Statistics; } @@ -37,13 +39,13 @@ export namespace GetContactInfoResponse { complaints?: Statistics.Complaints.Item[] | undefined; /** Listing of the delivered campaign for the contact */ delivered?: Statistics.Delivered.Item[] | undefined; - /** Listing of the hardbounes generated by the contact */ + /** Listing of the hard bounces generated by the contact */ hardBounces?: Statistics.HardBounces.Item[] | undefined; /** Listing of the sent campaign for the contact */ messagesSent?: Statistics.MessagesSent.Item[] | undefined; /** Listing of the openings generated by the contact */ opened?: Statistics.Opened.Item[] | undefined; - /** Listing of the softbounes generated by the contact */ + /** Listing of the soft bounces generated by the contact */ softBounces?: Statistics.SoftBounces.Item[] | undefined; /** Listing of the transactional attributes for the contact */ transacAttributes?: Statistics.TransacAttributes.Item[] | undefined; diff --git a/src/api/resources/contacts/types/GetSegmentsResponse.ts b/src/api/resources/contacts/types/GetSegmentsResponse.ts index 0171aea..2ef1902 100644 --- a/src/api/resources/contacts/types/GetSegmentsResponse.ts +++ b/src/api/resources/contacts/types/GetSegmentsResponse.ts @@ -14,11 +14,11 @@ export namespace GetSegmentsResponse { export interface Item { /** Name of the Segment Category */ categoryName: string; - /** ID of the list */ + /** ID of the segment */ id: number; /** Name of the Segment */ segmentName: string; - /** Updation UTC date-time of the segment (YYYY-MM-DDTHH:mm:ss.SSSZ) */ + /** Last update UTC date-time of the segment (YYYY-MM-DDTHH:mm:ss.SSSZ) */ updatedAt?: string | undefined; } } diff --git a/src/api/resources/conversations/client/Client.ts b/src/api/resources/conversations/client/Client.ts index 72a8a7c..8934d33 100644 --- a/src/api/resources/conversations/client/Client.ts +++ b/src/api/resources/conversations/client/Client.ts @@ -23,7 +23,7 @@ export class ConversationsClient { } /** - * We recommend pinging this endpoint every minute for as long as the agent has to be considered online. + * Sets the agent's status to online for 2-3 minutes. We recommend pinging this endpoint every minute for as long as the agent has to be considered online. You must provide either `agentId` alone, or all three of `agentEmail` + `agentName` + `receivedFrom`. * * @param {Brevo.PostConversationsAgentOnlinePingRequest} request * @param {ConversationsClient.RequestOptions} requestOptions - Request-specific configuration. @@ -71,7 +71,7 @@ export class ConversationsClient { method: "POST", headers: _headers, contentType: "application/json", - queryParameters: requestOptions?.queryParams, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), requestType: "json", body: request, timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, @@ -106,6 +106,8 @@ export class ConversationsClient { } /** + * Send a message as an agent to an existing visitor's conversation. You must provide either `agentId` alone, or all three of `agentEmail` + `agentName` + `receivedFrom` to identify the agent. + * * @param {Brevo.PostConversationsMessagesRequest} request * @param {ConversationsClient.RequestOptions} requestOptions - Request-specific configuration. * @@ -162,7 +164,7 @@ export class ConversationsClient { method: "POST", headers: _headers, contentType: "application/json", - queryParameters: requestOptions?.queryParams, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), requestType: "json", body: request, timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, @@ -192,6 +194,8 @@ export class ConversationsClient { } /** + * Retrieve a single message by its ID. + * * @param {Brevo.GetConversationsMessagesIdRequest} request * @param {ConversationsClient.RequestOptions} requestOptions - Request-specific configuration. * @@ -230,7 +234,7 @@ export class ConversationsClient { ), method: "GET", headers: _headers, - queryParameters: requestOptions?.queryParams, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, abortSignal: requestOptions?.abortSignal, @@ -260,7 +264,7 @@ export class ConversationsClient { } /** - * Only agents’ messages can be edited. + * Update the text of a message sent by an agent. Only messages of type `agent` can be edited. The `text` and `html` fields of the message will be updated. * * @param {Brevo.PutConversationsMessagesIdRequest} request * @param {ConversationsClient.RequestOptions} requestOptions - Request-specific configuration. @@ -302,7 +306,7 @@ export class ConversationsClient { method: "PUT", headers: _headers, contentType: "application/json", - queryParameters: requestOptions?.queryParams, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), requestType: "json", body: _body, timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, @@ -334,7 +338,7 @@ export class ConversationsClient { } /** - * Only agents’ messages can be deleted. + * Delete a message sent by an agent. Only messages of type `agent` can be deleted. * * @param {Brevo.DeleteConversationsMessagesIdRequest} request * @param {ConversationsClient.RequestOptions} requestOptions - Request-specific configuration. @@ -374,7 +378,7 @@ export class ConversationsClient { ), method: "DELETE", headers: _headers, - queryParameters: requestOptions?.queryParams, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, abortSignal: requestOptions?.abortSignal, @@ -409,7 +413,7 @@ export class ConversationsClient { } /** - * Example of automated messages: order status, announce new features in your web app, etc. + * Send an automated (pushed) message to a visitor on behalf of an agent. Example use cases: order status updates, announcing new features in your web app, etc. * * @param {Brevo.PostConversationsPushedMessagesRequest} request * @param {ConversationsClient.RequestOptions} requestOptions - Request-specific configuration. @@ -419,20 +423,20 @@ export class ConversationsClient { * @example * await client.conversations.sendAnAutomatedMessageToAVisitor({ * groupId: "PjRBMhWGen6aRHjif", - * text: "Your order has shipped! Here\u2019s your tracking number: 9114 5847 3325 9667 4328 88", + * text: "Your order has shipped! Here's your tracking number: 9114 5847 3325 9667 4328 88", * visitorId: "kZMvWhf8npAu3H6qd57w2Hv6nh6rnxvg" * }) * * @example * await client.conversations.sendAnAutomatedMessageToAVisitor({ - * text: "Your order has shipped! Here\u2019s your tracking number: 9114 5847 3325 9667 4328 88", + * text: "Your order has shipped! Here's your tracking number: 9114 5847 3325 9667 4328 88", * visitorId: "kZMvWhf8npAu3H6qd57w2Hv6nh6rnxvg" * }) * * @example * await client.conversations.sendAnAutomatedMessageToAVisitor({ * agentId: "d9nKoegKSjmCtyK78", - * text: "Your order has shipped! Here\u2019s your tracking number: 9114 5847 3325 9667 4328 88", + * text: "Your order has shipped! Here's your tracking number: 9114 5847 3325 9667 4328 88", * visitorId: "kZMvWhf8npAu3H6qd57w2Hv6nh6rnxvg" * }) */ @@ -463,7 +467,7 @@ export class ConversationsClient { method: "POST", headers: _headers, contentType: "application/json", - queryParameters: requestOptions?.queryParams, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), requestType: "json", body: request, timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, @@ -498,6 +502,8 @@ export class ConversationsClient { } /** + * Retrieve a single automated (pushed) message by its ID. + * * @param {Brevo.GetConversationsPushedMessagesIdRequest} request * @param {ConversationsClient.RequestOptions} requestOptions - Request-specific configuration. * @@ -536,7 +542,7 @@ export class ConversationsClient { ), method: "GET", headers: _headers, - queryParameters: requestOptions?.queryParams, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, abortSignal: requestOptions?.abortSignal, @@ -571,6 +577,8 @@ export class ConversationsClient { } /** + * Update the text of an automated (pushed) message. The `text` and `html` fields of the message will be updated. + * * @param {Brevo.PutConversationsPushedMessagesIdRequest} request * @param {ConversationsClient.RequestOptions} requestOptions - Request-specific configuration. * @@ -580,7 +588,7 @@ export class ConversationsClient { * @example * await client.conversations.updateAnAutomatedMessage({ * id: "id", - * text: "Your order has shipped! Here\u2019s your tracking number: 9114 5847 4668 7775 9233 54" + * text: "Your order has shipped! Here's your tracking number: 9114 5847 4668 7775 9233 54" * }) */ public updateAnAutomatedMessage( @@ -611,7 +619,7 @@ export class ConversationsClient { method: "PUT", headers: _headers, contentType: "application/json", - queryParameters: requestOptions?.queryParams, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), requestType: "json", body: _body, timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, @@ -648,6 +656,8 @@ export class ConversationsClient { } /** + * Delete an automated (pushed) message by its ID. + * * @param {Brevo.DeleteConversationsPushedMessagesIdRequest} request * @param {ConversationsClient.RequestOptions} requestOptions - Request-specific configuration. * @@ -686,7 +696,7 @@ export class ConversationsClient { ), method: "DELETE", headers: _headers, - queryParameters: requestOptions?.queryParams, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, abortSignal: requestOptions?.abortSignal, @@ -761,7 +771,7 @@ export class ConversationsClient { method: "PUT", headers: _headers, contentType: "application/json", - queryParameters: requestOptions?.queryParams, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), requestType: "json", body: request, timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, diff --git a/src/api/resources/conversations/client/requests/PostConversationsAgentOnlinePingRequest.ts b/src/api/resources/conversations/client/requests/PostConversationsAgentOnlinePingRequest.ts index 83ed09b..7dcabda 100644 --- a/src/api/resources/conversations/client/requests/PostConversationsAgentOnlinePingRequest.ts +++ b/src/api/resources/conversations/client/requests/PostConversationsAgentOnlinePingRequest.ts @@ -14,12 +14,12 @@ * } */ export interface PostConversationsAgentOnlinePingRequest { - /** agent email. When sending online pings from a standalone system, it’s hard to maintain a 1-to-1 relationship between the users of both systems. In this case, an agent can be specified by their email address. If there’s no agent with the specified email address in your Brevo organization, a dummy agent will be created automatically. */ - agentEmail?: unknown; - /** agent ID. It can be found on agent’s page or received from a webhook. Alternatively, you can use `agentEmail` + `agentName` + `receivedFrom` instead (all 3 fields required). */ - agentId?: unknown; - /** agent name */ - agentName?: unknown; - /** mark your messages to distinguish messages created by you from the others. */ - receivedFrom?: unknown; + /** Agent's email address. When sending online pings from a standalone system, it's hard to maintain a 1-to-1 relationship between the users of both systems. In this case, an agent can be specified by their email address. If there's no agent with the specified email address in your Brevo organization, a dummy agent will be created automatically. */ + agentEmail?: string; + /** Agent ID. It can be found on the agent's page or received from a webhook. Alternatively, you can use `agentEmail` + `agentName` + `receivedFrom` instead (all 3 fields required). */ + agentId?: string; + /** Agent's name. */ + agentName?: string; + /** Mark your messages to distinguish messages created by you from the others. */ + receivedFrom?: string; } diff --git a/src/api/resources/conversations/client/requests/PostConversationsMessagesRequest.ts b/src/api/resources/conversations/client/requests/PostConversationsMessagesRequest.ts index a42ca62..be0eae1 100644 --- a/src/api/resources/conversations/client/requests/PostConversationsMessagesRequest.ts +++ b/src/api/resources/conversations/client/requests/PostConversationsMessagesRequest.ts @@ -26,14 +26,16 @@ * } */ export interface PostConversationsMessagesRequest { - /** agent email. When sending messages from a standalone system, it’s hard to maintain a 1-to-1 relationship between the users of both systems. In this case, an agent can be specified by their email address. */ - agentEmail?: unknown; - /** agent ID. It can be found on agent’s page or received from a webhook. Alternatively, you can use `agentEmail` + `agentName` + `receivedFrom` instead (all 3 fields required). */ - agentId?: unknown; - /** agent name */ - agentName?: unknown; - /** mark your messages to distinguish messages created by you from the others. */ - receivedFrom?: unknown; - text?: unknown; - visitorId?: unknown; + /** Agent's email address. When sending messages from a standalone system, it's hard to maintain a 1-to-1 relationship between the users of both systems. In this case, an agent can be specified by their email address. */ + agentEmail?: string; + /** Agent ID. It can be found on the agent's page or received from a webhook. Alternatively, you can use `agentEmail` + `agentName` + `receivedFrom` instead (all 3 fields required). */ + agentId?: string; + /** Agent's name. */ + agentName?: string; + /** Mark your messages to distinguish messages created by you from the others. */ + receivedFrom?: string; + /** Message text. */ + text: string; + /** Visitor's ID received from a webhook or generated by you to bind an existing user account to Conversations. */ + visitorId: string; } diff --git a/src/api/resources/conversations/client/requests/PostConversationsPushedMessagesRequest.ts b/src/api/resources/conversations/client/requests/PostConversationsPushedMessagesRequest.ts index fb466bf..ede5f2b 100644 --- a/src/api/resources/conversations/client/requests/PostConversationsPushedMessagesRequest.ts +++ b/src/api/resources/conversations/client/requests/PostConversationsPushedMessagesRequest.ts @@ -4,28 +4,30 @@ * @example * { * groupId: "PjRBMhWGen6aRHjif", - * text: "Your order has shipped! Here\u2019s your tracking number: 9114 5847 3325 9667 4328 88", + * text: "Your order has shipped! Here's your tracking number: 9114 5847 3325 9667 4328 88", * visitorId: "kZMvWhf8npAu3H6qd57w2Hv6nh6rnxvg" * } * * @example * { - * text: "Your order has shipped! Here\u2019s your tracking number: 9114 5847 3325 9667 4328 88", + * text: "Your order has shipped! Here's your tracking number: 9114 5847 3325 9667 4328 88", * visitorId: "kZMvWhf8npAu3H6qd57w2Hv6nh6rnxvg" * } * * @example * { * agentId: "d9nKoegKSjmCtyK78", - * text: "Your order has shipped! Here\u2019s your tracking number: 9114 5847 3325 9667 4328 88", + * text: "Your order has shipped! Here's your tracking number: 9114 5847 3325 9667 4328 88", * visitorId: "kZMvWhf8npAu3H6qd57w2Hv6nh6rnxvg" * } */ export interface PostConversationsPushedMessagesRequest { - /** agent ID. It can be found on agent’s page or received from a webhook. */ - agentId?: unknown; - /** group ID. It can be found on group’s page. */ - groupId?: unknown; - text?: unknown; - visitorId?: unknown; + /** Agent ID. It can be found on the agent's page or received from a webhook. */ + agentId?: string; + /** Group ID. It can be found on the group's page. */ + groupId?: string; + /** Message text. */ + text: string; + /** Visitor's ID received from a webhook or generated by you to bind an existing user account to Conversations. */ + visitorId: string; } diff --git a/src/api/resources/conversations/client/requests/PutConversationsMessagesIdRequest.ts b/src/api/resources/conversations/client/requests/PutConversationsMessagesIdRequest.ts index 881c908..fb2747d 100644 --- a/src/api/resources/conversations/client/requests/PutConversationsMessagesIdRequest.ts +++ b/src/api/resources/conversations/client/requests/PutConversationsMessagesIdRequest.ts @@ -10,6 +10,6 @@ export interface PutConversationsMessagesIdRequest { /** ID of the message */ id: string; - /** edited message text */ + /** The new message text. */ text: string; } diff --git a/src/api/resources/conversations/client/requests/PutConversationsPushedMessagesIdRequest.ts b/src/api/resources/conversations/client/requests/PutConversationsPushedMessagesIdRequest.ts index a66209a..9e476f4 100644 --- a/src/api/resources/conversations/client/requests/PutConversationsPushedMessagesIdRequest.ts +++ b/src/api/resources/conversations/client/requests/PutConversationsPushedMessagesIdRequest.ts @@ -4,12 +4,12 @@ * @example * { * id: "id", - * text: "Your order has shipped! Here\u2019s your tracking number: 9114 5847 4668 7775 9233 54" + * text: "Your order has shipped! Here's your tracking number: 9114 5847 4668 7775 9233 54" * } */ export interface PutConversationsPushedMessagesIdRequest { /** ID of the message */ id: string; - /** edited message text */ + /** The new message text. */ text: string; } diff --git a/src/api/resources/coupons/client/Client.ts b/src/api/resources/coupons/client/Client.ts index 64331ff..93e6e79 100644 --- a/src/api/resources/coupons/client/Client.ts +++ b/src/api/resources/coupons/client/Client.ts @@ -23,6 +23,8 @@ export class CouponsClient { } /** + * Retrieve a paginated list of all coupon collections in your Brevo account. Results can be sorted by creation date, remaining coupons count, or expiration date, in ascending or descending order. Pagination defaults to 50 collections per page (maximum 100). + * * @param {Brevo.GetCouponCollectionsRequest} request * @param {CouponsClient.RequestOptions} requestOptions - Request-specific configuration. * @@ -65,7 +67,11 @@ export class CouponsClient { ), method: "GET", headers: _headers, - queryParameters: { ..._queryParams, ...requestOptions?.queryParams }, + queryString: core.url + .queryBuilder() + .addMany(_queryParams) + .mergeAdditional(requestOptions?.queryParams) + .build(), timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, abortSignal: requestOptions?.abortSignal, @@ -95,6 +101,8 @@ export class CouponsClient { } /** + * Create a new coupon collection with a name and a default coupon value. You can optionally set an expiration date in RFC3339 format and configure alert thresholds to receive email notifications when remaining coupons or remaining days before expiration fall below a specified number. The collection ID is auto-generated as a UUID and returned in the response. + * * @param {Brevo.CreateCouponCollectionRequest} request * @param {CouponsClient.RequestOptions} requestOptions - Request-specific configuration. * @@ -134,7 +142,7 @@ export class CouponsClient { method: "POST", headers: _headers, contentType: "application/json", - queryParameters: requestOptions?.queryParams, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), requestType: "json", body: request, timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, @@ -166,6 +174,8 @@ export class CouponsClient { } /** + * Retrieve the details of a single coupon collection by its UUID. The response includes the collection name, default coupon value, total and remaining coupon counts, and creation timestamp. Returns a `404` error if no collection matches the provided ID. + * * @param {Brevo.GetCouponCollectionRequest} request * @param {CouponsClient.RequestOptions} requestOptions - Request-specific configuration. * @@ -205,7 +215,7 @@ export class CouponsClient { ), method: "GET", headers: _headers, - queryParameters: requestOptions?.queryParams, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, abortSignal: requestOptions?.abortSignal, @@ -237,6 +247,8 @@ export class CouponsClient { } /** + * Update an existing coupon collection by its UUID. You can modify the default coupon value, set or remove the expiration date (pass `null` to remove), and configure or disable alert thresholds for remaining coupons or remaining days. Only the fields included in the request body are updated; omitted fields remain unchanged. + * * @param {Brevo.UpdateCouponCollectionRequest} request * @param {CouponsClient.RequestOptions} requestOptions - Request-specific configuration. * @@ -276,7 +288,7 @@ export class CouponsClient { method: "PATCH", headers: _headers, contentType: "application/json", - queryParameters: requestOptions?.queryParams, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), requestType: "json", body: _body, timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, @@ -308,6 +320,8 @@ export class CouponsClient { } /** + * Add coupons to an existing coupon collection. The `coupons` array must contain between 1 and 10,000 unique coupon code strings, all associated with the specified `collectionId`. Coupon creation is processed asynchronously and a `204` status is returned immediately upon acceptance. Returns a `404` error if the specified coupon collection does not exist. + * * @param {Brevo.CreateCouponsRequest} request * @param {CouponsClient.RequestOptions} requestOptions - Request-specific configuration. * @@ -348,7 +362,7 @@ export class CouponsClient { method: "POST", headers: _headers, contentType: "application/json", - queryParameters: requestOptions?.queryParams, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), requestType: "json", body: request, timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, diff --git a/src/api/resources/customObjects/client/Client.ts b/src/api/resources/customObjects/client/Client.ts index 012c9ad..7d44f9b 100644 --- a/src/api/resources/customObjects/client/Client.ts +++ b/src/api/resources/customObjects/client/Client.ts @@ -25,24 +25,51 @@ export class CustomObjectsClient { /** * Custom objects are only available to Enterprise plans. * This feature is in beta. These are subject to change. - * This API allows bulk upsert of object records in a single request. Each object record may include - * - Attributes - * - Identifiers - * - Associations - * **Response:** - * The API processes the request asynchronously and returns a processId that you can use to track the background process status. - * **API and Schema Limitation:** - * - Size: - * - Max 1000 objects records per request - * - Max request body size: 1 MB - * - Max 500 attributes defined per object record upsert request - * - This is coherent with schema limitation: an object cannot have more than 500 attributes. - * - Worth noting: Nothing happens If an attribute is mentioned in the request, but was not previously defined for the object schema (no error, no attribute creation) - * - Max 10 associations defined per associated object type, in each record of the request - * - This is not a schema limitation. You can associate an object record to an unlimited number of other object records by running multiple requests. + * Performs bulk create or update (upsert) operations for object records in a single asynchronous request. This endpoint is optimized for high-volume data imports and synchronization scenarios. + * + * **How Upsert Works:** + * - **Create**: Omit `identifiers`, or provide only `ext_id` (if it doesn't already exist). A new record is created with a Brevo-generated `id`. + * - **Update**: Provide `id` (Brevo internal ID) or an `ext_id` that already exists. The matching record is updated with the new attribute values. + * - **Important:** `id` is for **updates only**. Providing an `id` that does not belong to an existing record will fail during async processing (the HTTP response will still be 202, but the record will be rejected in the background). To create a new record with a stable external reference, use `ext_id` instead. + * + * **Request Structure:** + * Each object record in the `records` array can include: + * - `identifiers`: Either `id` (internal Brevo ID) or `ext_id` (your external system ID) — required for updates. **Note:** use `id` (singular), not `ids`. + * - `attributes`: Key-value pairs where each key is the attribute **key** (e.g., `company_name`), not the attribute label (e.g., "Company Name"). + * - `associations`: Controls linking and unlinking of associated records (optional). Each entry specifies: + * - `object_type`: The type of the associated object + * - `action`: `link` (default) to create the association, or `unlink` to remove it + * - `records`: The associated records to link or unlink (each identified by `ext_id` or `id`) + * - **Unlink is idempotent** — unlinking a non-existing association is a no-op (no error returned) + * - `link` and `unlink` actions can be submitted for the same `object_type` in a single record entry + * - Both associated records must already exist before a link can be created + * + * > **Common mistake:** Passing the attribute **label** (the display name you see in the UI) instead of the attribute **key** will cause the attribute to be silently ignored and the record may not be created as expected. + * + * **Asynchronous Processing:** + * - Returns immediately with a `processId` (HTTP 202 Accepted) + * - Use the processId to track status via the Get process API + * + * **API and Schema Limitations:** + * - Max 1000 object records per request + * - Max request body size: 1 MB + * - Max 500 attributes per object record (matches the schema limit of 500 attributes per object) + * - Unknown attribute keys are silently ignored (no error, no attribute creation) + * - Max 10 association records per associated object-type in each record of the request. If you need more, send multiple requests. + * + * **Important Behaviors:** + * - The object schema must be created before upserting records + * - Unknown attribute keys are silently ignored (no error, no creation) + * - Both associated object records must already exist before creating a link association + * - Unlink operations are idempotent: attempting to unlink a non-existing association returns success + * - `link` and `unlink` actions can be submitted for the same `object_type` in a single record entry + * - Contact objects cannot be created via this endpoint + * - For `category` and `multiple_category` attributes, pass the option **key** as the value (not the option label or option ID). + * - The `id` identifier (internal Brevo ID) can only be used for **updating** existing records. To create new records, either omit identifiers (Brevo auto-generates an ID) or provide an `ext_id`. + * * **Errors:** - * - Make sure both object records exist before associating them, else the API will return an error. - * - This route does not create objects. The object where the object records are upserted by this API must be created already else the API will return an error "invalid object type". + * - Make sure both object records exist before associating them, else the API will return an error. + * - This route does not create objects. The object where the object records are upserted by this API must be created already else the API will return an error "invalid object type". * * @param {Brevo.UpsertrecordsRequest} request * @param {CustomObjectsClient.RequestOptions} requestOptions - Request-specific configuration. @@ -55,7 +82,61 @@ export class CustomObjectsClient { * @example * await client.customObjects.upsertrecords({ * object_type: "vehicle", - * records: [{}] + * records: [{ + * associations: [{ + * object_type: "garage", + * action: "link", + * records: [{ + * identifiers: { + * id: 435435 + * } + * }] + * }, { + * object_type: "garage", + * action: "unlink", + * records: [{ + * identifiers: { + * ext_id: "old-garage-001" + * } + * }] + * }], + * attributes: { + * "make": "Toyota", + * "model": "Camry", + * "year": 2020, + * "engine_type": "hybrid" + * }, + * identifiers: { + * ext_id: "VIN123" + * } + * }] + * }) + * + * @example + * await client.customObjects.upsertrecords({ + * object_type: "vehicle", + * records: [{ + * attributes: { + * "make": "Honda", + * "model": "Civic", + * "year": 2023, + * "engine_type": "petrol" + * } + * }] + * }) + * + * @example + * await client.customObjects.upsertrecords({ + * object_type: "vehicle", + * records: [{ + * attributes: { + * "color": "red", + * "engine_type": "diesel" + * }, + * identifiers: { + * id: 42 + * } + * }] * }) */ public upsertrecords( @@ -86,7 +167,7 @@ export class CustomObjectsClient { method: "POST", headers: _headers, contentType: "application/json", - queryParameters: requestOptions?.queryParams, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), requestType: "json", body: _body, timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, @@ -179,7 +260,11 @@ export class CustomObjectsClient { ), method: "GET", headers: _headers, - queryParameters: { ..._queryParams, ...requestOptions?.queryParams }, + queryString: core.url + .queryBuilder() + .addMany(_queryParams) + .mergeAdditional(requestOptions?.queryParams) + .build(), timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, abortSignal: requestOptions?.abortSignal, @@ -219,15 +304,14 @@ export class CustomObjectsClient { /** * Use this endpoint to delete multiple object records of the same object-type in one request. - * The request is accepted and processed asynchronously. You can track the status of the deletion process using the returned **processId**. - * **API and Schema Limitations:** - Each request can contain up to **1000** object record identifiers - If more records must be deleted → send multiple batch requests + * The request is accepted and processed asynchronously. You can track the status of the deletion process using the returned **processId**. + * **Limitations:** - Each request can contain up to **1000** object record identifiers - Either `ids` or `ext_ids` must be provided, but **not both** in the same request - Deletion of Brevo standard object records is not supported via this endpoint - If more records must be deleted, send multiple batch requests * * @param {Brevo.BatchDeleteObjectRecordsRequest} request * @param {CustomObjectsClient.RequestOptions} requestOptions - Request-specific configuration. * * @throws {@link Brevo.BadRequestError} * @throws {@link Brevo.ForbiddenError} - * @throws {@link Brevo.NotFoundError} * @throws {@link Brevo.InternalServerError} * * @example @@ -266,7 +350,7 @@ export class CustomObjectsClient { method: "POST", headers: _headers, contentType: "application/json", - queryParameters: requestOptions?.queryParams, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), requestType: "json", body: _body, timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, @@ -288,8 +372,6 @@ export class CustomObjectsClient { throw new Brevo.BadRequestError(_response.error.body as unknown, _response.rawResponse); case 403: throw new Brevo.ForbiddenError(_response.error.body as unknown, _response.rawResponse); - case 404: - throw new Brevo.NotFoundError(_response.error.body as unknown, _response.rawResponse); case 500: throw new Brevo.InternalServerError(_response.error.body as unknown, _response.rawResponse); default: diff --git a/src/api/resources/customObjects/client/requests/BatchDeleteObjectRecordsRequest.ts b/src/api/resources/customObjects/client/requests/BatchDeleteObjectRecordsRequest.ts index cb95008..98ddbb3 100644 --- a/src/api/resources/customObjects/client/requests/BatchDeleteObjectRecordsRequest.ts +++ b/src/api/resources/customObjects/client/requests/BatchDeleteObjectRecordsRequest.ts @@ -12,13 +12,13 @@ export interface BatchDeleteObjectRecordsRequest { /** Object type for the records to delete */ object_type: string; - /** One of the below must be provided */ + /** Either `ids` or `ext_ids` must be provided, but not both in the same request. */ identifiers?: BatchDeleteObjectRecordsRequest.Identifiers; } export namespace BatchDeleteObjectRecordsRequest { /** - * One of the below must be provided + * Either `ids` or `ext_ids` must be provided, but not both in the same request. */ export type Identifiers = | { diff --git a/src/api/resources/customObjects/client/requests/GetrecordsRequest.ts b/src/api/resources/customObjects/client/requests/GetrecordsRequest.ts index 029f0c8..a1bf354 100644 --- a/src/api/resources/customObjects/client/requests/GetrecordsRequest.ts +++ b/src/api/resources/customObjects/client/requests/GetrecordsRequest.ts @@ -11,7 +11,7 @@ import type * as Brevo from "../../../../index.js"; * } */ export interface GetrecordsRequest { - /** object type for the attribute */ + /** Object type for the records to retrieve. Must be a previously created custom object type. Contact as object type is not supported in this endpoint. */ object_type: string; /** Number of records returned per page */ limit: number; diff --git a/src/api/resources/customObjects/client/requests/UpsertrecordsRequest.ts b/src/api/resources/customObjects/client/requests/UpsertrecordsRequest.ts index 36e0ce2..cfb90c7 100644 --- a/src/api/resources/customObjects/client/requests/UpsertrecordsRequest.ts +++ b/src/api/resources/customObjects/client/requests/UpsertrecordsRequest.ts @@ -4,11 +4,65 @@ * @example * { * object_type: "vehicle", - * records: [{}] + * records: [{ + * associations: [{ + * object_type: "garage", + * action: "link", + * records: [{ + * identifiers: { + * id: 435435 + * } + * }] + * }, { + * object_type: "garage", + * action: "unlink", + * records: [{ + * identifiers: { + * ext_id: "old-garage-001" + * } + * }] + * }], + * attributes: { + * "make": "Toyota", + * "model": "Camry", + * "year": 2020, + * "engine_type": "hybrid" + * }, + * identifiers: { + * ext_id: "VIN123" + * } + * }] + * } + * + * @example + * { + * object_type: "vehicle", + * records: [{ + * attributes: { + * "make": "Honda", + * "model": "Civic", + * "year": 2023, + * "engine_type": "petrol" + * } + * }] + * } + * + * @example + * { + * object_type: "vehicle", + * records: [{ + * attributes: { + * "color": "red", + * "engine_type": "diesel" + * }, + * identifiers: { + * id: 42 + * } + * }] * } */ export interface UpsertrecordsRequest { - /** object type for the attribute */ + /** Object type for the records to upsert. Must be a previously created custom object type. Only lowercase alphanumeric characters and underscores are allowed (max 32 characters). */ object_type: string; /** List of object records to be upsert. Each record can have attributes, identifiers, and associations. */ records: UpsertrecordsRequest.Records.Item[]; @@ -19,10 +73,26 @@ export namespace UpsertrecordsRequest { export namespace Records { export interface Item { + /** List of associations for the object record. Maximum 20 total entries allowed, with a maximum of 10 link actions and 10 unlink actions. Each entry specifies an object_type and an action (link or unlink). Unlink is idempotent — removing a non-existing association does not return an error. Both associated records must already exist before creating a link. */ associations?: Item.Associations.Item[] | undefined; - /** Attributes attached with the object record. Only the already created attributes will be used with records. Pass the value with the attributes key you want to set or update for the object record. Minimum 1 attribute is required. */ + /** + * Key-value pairs of attribute data for the object record. Each key must be the attribute **key** (e.g., `company_name`, `engine_type`), not the attribute label (e.g., "Company Name", "Engine Type"). Only attributes that already exist in the object schema will be accepted — unknown keys are silently ignored. Minimum 1 attribute is required. + * + * For `category` or `multiple_category` attributes, set the value to the option **key** (not the option label or option ID). You can find available option keys in the `options` array returned by the GET attributes endpoint, or in the frontend under each attribute's settings. + * + * For example, use the option key "hybrid" not the label "Hybrid" — using the label will be silently ignored. + * + * For `multiple_choice` type, pass an **array of option keys** (not display labels). For example, if options have keys `"sunroof"` and `"leather_seats"`, pass `["sunroof", "leather_seats"]`. + */ attributes?: Record | undefined; - /** Identifiers attached with the object record. It can have id or ext_id. ext_id is ID of record in the external system that client want to store in the object system, id is an internal ID of object record generated by Brevo system. NOTE: - Its an optional field, if identifier is not provided, then id of object records will be generated by Brevo. This id can be used for further operation with the object record. - Both ext_id and id cannot be provided in the same request. */ + /** + * Identifiers for the object record. Supports `id` (singular, not `ids`) or `ext_id`. + * - `ext_id`: Your external system's identifier for this record. + * - `id`: Internal Brevo record ID — can only be used for **updating** existing records, not for creation. + * NOTE: + * - This is an optional field. If no identifier is provided, Brevo auto-generates an internal ID that you can use for future operations. + * - If both `ext_id` and `id` are provided, `id` takes precedence and the operation is treated as an update. It is recommended to provide only one identifier per record. + */ identifiers?: Item.Identifiers | undefined; } @@ -30,45 +100,54 @@ export namespace UpsertrecordsRequest { export type Associations = Associations.Item[]; export namespace Associations { - export type Item = - | { - object_type?: string | undefined; - records?: - | { - identifiers?: - | { - ext_id?: string | undefined; - id?: number | undefined; - } - | undefined; - }[] - | undefined; - } - | { - object_type?: string | undefined; - records?: - | ( - | { - identifiers?: - | { - ext_id?: string | undefined; - id?: number | undefined; - } - | undefined; - } - | { - identifiers?: Record | undefined; - } - )[] - | undefined; - }; + export interface Item { + /** Type of the associated object */ + object_type: string; + /** Action to perform on the association. - `link`: Create association between records (default if not provided) - `unlink`: Remove association between records. Idempotent — unlinking a non-existing association is a no-op success. */ + action?: Item.Action | undefined; + records: Item.Records.Item[]; + } + + export namespace Item { + /** Action to perform on the association. - `link`: Create association between records (default if not provided) - `unlink`: Remove association between records. Idempotent — unlinking a non-existing association is a no-op success. */ + export const Action = { + Link: "link", + Unlink: "unlink", + } as const; + export type Action = (typeof Action)[keyof typeof Action]; + export type Records = Records.Item[]; + + export namespace Records { + export interface Item { + /** Identifiers for the associated object record. Provide either `ext_id` or `id`. */ + identifiers?: Item.Identifiers | undefined; + } + + export namespace Item { + /** + * Identifiers for the associated object record. Provide either `ext_id` or `id`. + */ + export interface Identifiers { + /** External ID of the associated record in your system. */ + ext_id?: string | undefined; + /** Internal ID of the associated object record generated by Brevo. */ + id?: number | undefined; + } + } + } + } } /** - * Identifiers attached with the object record. It can have id or ext_id. ext_id is ID of record in the external system that client want to store in the object system, id is an internal ID of object record generated by Brevo system. NOTE: - Its an optional field, if identifier is not provided, then id of object records will be generated by Brevo. This id can be used for further operation with the object record. - Both ext_id and id cannot be provided in the same request. + * Identifiers for the object record. Supports `id` (singular, not `ids`) or `ext_id`. + * - `ext_id`: Your external system's identifier for this record. + * - `id`: Internal Brevo record ID — can only be used for **updating** existing records, not for creation. + * NOTE: + * - This is an optional field. If no identifier is provided, Brevo auto-generates an internal ID that you can use for future operations. + * - If both `ext_id` and `id` are provided, `id` takes precedence and the operation is treated as an update. It is recommended to provide only one identifier per record. */ export interface Identifiers { - /** ext_id is ID of record in the external system that client_dev want to store in the object system. */ + /** ext_id is ID of record in the external system that client wants to store in the object system. */ ext_id?: string | undefined; /** Internal ID of the object record generated by Brevo */ id?: number | undefined; diff --git a/src/api/resources/customObjects/client/requests/index.ts b/src/api/resources/customObjects/client/requests/index.ts index ba83d4f..1d1be1c 100644 --- a/src/api/resources/customObjects/client/requests/index.ts +++ b/src/api/resources/customObjects/client/requests/index.ts @@ -1,3 +1,3 @@ export type { BatchDeleteObjectRecordsRequest } from "./BatchDeleteObjectRecordsRequest.js"; export type { GetrecordsRequest } from "./GetrecordsRequest.js"; -export type { UpsertrecordsRequest } from "./UpsertrecordsRequest.js"; +export { UpsertrecordsRequest } from "./UpsertrecordsRequest.js"; diff --git a/src/api/resources/customObjects/types/GetrecordsResponse.ts b/src/api/resources/customObjects/types/GetrecordsResponse.ts index 0b688dc..eb81c18 100644 --- a/src/api/resources/customObjects/types/GetrecordsResponse.ts +++ b/src/api/resources/customObjects/types/GetrecordsResponse.ts @@ -13,11 +13,18 @@ export namespace GetrecordsResponse { export interface Item { /** List of associations for the object record. If association query param is true it will return 5 associated records per association. */ associations?: Item.Associations.Item[] | undefined; - /** Attributes attached with the object record. Only the already created attributes will be used with records. Minimum 1 attribute is required. */ + /** + * Key-value pairs of attribute data for the object record. Each key is the attribute **key** (e.g., `company_name`, `engine_type`), not the attribute label (e.g., "Company Name", "Engine Type"). Only attributes that already exist in the object schema will be present. + * For `category` or `multiple_category` attributes, the value is the option **key** (not the option label or option ID). + */ attributes?: Record | undefined; /** Timestamp when the object record was created */ createdAt?: string | undefined; - /** Identifiers attached with the object record. It can have id or ext_id. ext_id is ID of record in the external system that client want to store in the object system, id is an internal ID of object record generated by Brevo system. */ + /** + * Identifiers for the object record. Supports `id` (singular, not `ids`) or `ext_id`. + * - `ext_id`: Your external system's identifier for this record. + * - `id`: Internal Brevo record ID. + */ identifiers?: Item.Identifiers | undefined; /** Timestamp when the object record was last updated */ updatedAt?: string | undefined; @@ -73,12 +80,14 @@ export namespace GetrecordsResponse { } /** - * Identifiers attached with the object record. It can have id or ext_id. ext_id is ID of record in the external system that client want to store in the object system, id is an internal ID of object record generated by Brevo system. + * Identifiers for the object record. Supports `id` (singular, not `ids`) or `ext_id`. + * - `ext_id`: Your external system's identifier for this record. + * - `id`: Internal Brevo record ID. */ export interface Identifiers { - /** ext_id is ID of record in the external system that client_dev want to store in the object system. */ + /** External ID of the record in your system. */ ext_id?: string | undefined; - /** Internal ID of the object record generated by Brevo */ + /** Internal ID of the object record generated by Brevo. */ id?: number | undefined; } } diff --git a/src/api/resources/deals/client/Client.ts b/src/api/resources/deals/client/Client.ts index d0e428b..439e15c 100644 --- a/src/api/resources/deals/client/Client.ts +++ b/src/api/resources/deals/client/Client.ts @@ -24,8 +24,12 @@ export class DealsClient { } /** + * Retrieve the list of all attributes defined for deals, including both system-default and custom attributes. Each attribute includes its label, internal name, type, required status, and available options for select-type attributes. + * * @param {DealsClient.RequestOptions} requestOptions - Request-specific configuration. * + * @throws {@link Brevo.BadRequestError} + * * @example * await client.deals.getDealAttributes() */ @@ -53,7 +57,7 @@ export class DealsClient { ), method: "GET", headers: _headers, - queryParameters: requestOptions?.queryParams, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, abortSignal: requestOptions?.abortSignal, @@ -68,17 +72,24 @@ export class DealsClient { } if (_response.error.reason === "status-code") { - throw new errors.BrevoError({ - statusCode: _response.error.statusCode, - body: _response.error.body, - rawResponse: _response.rawResponse, - }); + switch (_response.error.statusCode) { + case 400: + throw new Brevo.BadRequestError(_response.error.body as unknown, _response.rawResponse); + default: + throw new errors.BrevoError({ + statusCode: _response.error.statusCode, + body: _response.error.body, + rawResponse: _response.rawResponse, + }); + } } return handleNonStatusCodeError(_response.error, _response.rawResponse, "GET", "/crm/attributes/deals"); } /** + * Retrieve a paginated list of deals with optional filtering, sorting, and search capabilities. Results can be filtered by attributes such as deal name or owner, linked companies, linked contacts, or modification/creation timestamps. Default sort order is descending by creation date. + * * @param {Brevo.GetCrmDealsRequest} request * @param {DealsClient.RequestOptions} requestOptions - Request-specific configuration. * @@ -107,6 +118,7 @@ export class DealsClient { offset, limit, sort, + sortBy, } = request; const _queryParams: Record = { "filters[attributes.deal_name]": filtersAttributesDealName, @@ -117,6 +129,7 @@ export class DealsClient { offset, limit, sort: sort != null ? sort : undefined, + sortBy, }; const _authRequest: core.AuthRequest = await this._options.authProvider.getAuthRequest(); const _headers: core.Fetcher.Args["headers"] = mergeHeaders( @@ -133,7 +146,11 @@ export class DealsClient { ), method: "GET", headers: _headers, - queryParameters: { ..._queryParams, ...requestOptions?.queryParams }, + queryString: core.url + .queryBuilder() + .addMany(_queryParams) + .mergeAdditional(requestOptions?.queryParams) + .build(), timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, abortSignal: requestOptions?.abortSignal, @@ -161,6 +178,8 @@ export class DealsClient { } /** + * Create a new deal in the CRM with the specified name, attributes, and optional associations to contacts and companies. You can assign the deal to a specific pipeline and stage by providing `pipeline` and `deal_stage` attribute IDs, which can be retrieved from the pipeline details endpoint. + * * @param {Brevo.PostCrmDealsRequest} request * @param {DealsClient.RequestOptions} requestOptions - Request-specific configuration. * @@ -198,7 +217,7 @@ export class DealsClient { method: "POST", headers: _headers, contentType: "application/json", - queryParameters: requestOptions?.queryParams, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), requestType: "json", body: request, timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, @@ -276,7 +295,7 @@ export class DealsClient { ), method: "POST", headers: _headers, - queryParameters: requestOptions?.queryParams, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), requestType: "file", duplex: _maybeEncodedRequest.duplex, body: _maybeEncodedRequest.body, @@ -307,6 +326,8 @@ export class DealsClient { } /** + * Link or unlink contacts and companies with a specific deal in a single request. You can simultaneously link new contacts/companies and unlink existing ones by providing the respective ID arrays in the request body. + * * @param {Brevo.PatchCrmDealsLinkUnlinkIdRequest} request * @param {DealsClient.RequestOptions} requestOptions - Request-specific configuration. * @@ -347,7 +368,7 @@ export class DealsClient { method: "PATCH", headers: _headers, contentType: "application/json", - queryParameters: requestOptions?.queryParams, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), requestType: "json", body: _body, timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, @@ -377,6 +398,8 @@ export class DealsClient { } /** + * Retrieve the full details of a single deal by its identifier, including its attributes, pipeline stage, linked contacts, and linked companies. Returns a 404 error if the deal does not exist. + * * @param {Brevo.GetCrmDealsIdRequest} request * @param {DealsClient.RequestOptions} requestOptions - Request-specific configuration. * @@ -415,7 +438,7 @@ export class DealsClient { ), method: "GET", headers: _headers, - queryParameters: requestOptions?.queryParams, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, abortSignal: requestOptions?.abortSignal, @@ -445,6 +468,8 @@ export class DealsClient { } /** + * Permanently delete a deal by its identifier. The requesting user must be the deal owner or have manage permission on deals; otherwise, a 403 Forbidden error is returned. + * * @param {Brevo.DeleteCrmDealsIdRequest} request * @param {DealsClient.RequestOptions} requestOptions - Request-specific configuration. * @@ -483,7 +508,7 @@ export class DealsClient { ), method: "DELETE", headers: _headers, - queryParameters: requestOptions?.queryParams, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, abortSignal: requestOptions?.abortSignal, @@ -513,6 +538,8 @@ export class DealsClient { } /** + * Update an existing deal''s attributes, name, linked contacts, or linked companies. Note that passing `linkedContactsIds` or `linkedCompaniesIds` replaces the entire list of associations, so omitted IDs will be removed. To move a deal to a different pipeline or stage, provide both the `pipeline` and `deal_stage` attribute IDs. + * * @param {Brevo.PatchCrmDealsIdRequest} request * @param {DealsClient.RequestOptions} requestOptions - Request-specific configuration. * @@ -552,7 +579,7 @@ export class DealsClient { method: "PATCH", headers: _headers, contentType: "application/json", - queryParameters: requestOptions?.queryParams, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), requestType: "json", body: _body, timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, @@ -590,6 +617,8 @@ export class DealsClient { * * @param {DealsClient.RequestOptions} requestOptions - Request-specific configuration. * + * @throws {@link Brevo.BadRequestError} + * * @example * await client.deals.getPipelineStages() */ @@ -615,7 +644,7 @@ export class DealsClient { ), method: "GET", headers: _headers, - queryParameters: requestOptions?.queryParams, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, abortSignal: requestOptions?.abortSignal, @@ -627,17 +656,24 @@ export class DealsClient { } if (_response.error.reason === "status-code") { - throw new errors.BrevoError({ - statusCode: _response.error.statusCode, - body: _response.error.body, - rawResponse: _response.rawResponse, - }); + switch (_response.error.statusCode) { + case 400: + throw new Brevo.BadRequestError(_response.error.body as unknown, _response.rawResponse); + default: + throw new errors.BrevoError({ + statusCode: _response.error.statusCode, + body: _response.error.body, + rawResponse: _response.rawResponse, + }); + } } return handleNonStatusCodeError(_response.error, _response.rawResponse, "GET", "/crm/pipeline/details"); } /** + * Retrieve the list of all deal pipelines configured for your account, including each pipeline''s stages and settings. If no pipelines have been configured yet, a default pipeline is automatically created and returned. + * * @param {DealsClient.RequestOptions} requestOptions - Request-specific configuration. * * @throws {@link Brevo.BadRequestError} @@ -667,7 +703,7 @@ export class DealsClient { ), method: "GET", headers: _headers, - queryParameters: requestOptions?.queryParams, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, abortSignal: requestOptions?.abortSignal, @@ -695,6 +731,8 @@ export class DealsClient { } /** + * Retrieve the details of a specific deal pipeline by its identifier, including its stages, stage ordering, and configuration. Use this endpoint to obtain the pipeline and stage IDs needed when creating or updating deals. + * * @param {Brevo.GetCrmPipelineDetailsPipelineIdRequest} request * @param {DealsClient.RequestOptions} requestOptions - Request-specific configuration. * @@ -732,7 +770,7 @@ export class DealsClient { ), method: "GET", headers: _headers, - queryParameters: requestOptions?.queryParams, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, abortSignal: requestOptions?.abortSignal, diff --git a/src/api/resources/deals/client/requests/GetCrmDealsRequest.ts b/src/api/resources/deals/client/requests/GetCrmDealsRequest.ts index cfda0b9..3c68e3e 100644 --- a/src/api/resources/deals/client/requests/GetCrmDealsRequest.ts +++ b/src/api/resources/deals/client/requests/GetCrmDealsRequest.ts @@ -11,11 +11,11 @@ export interface GetCrmDealsRequest { "filters[attributes.deal_name]"?: string; /** Filter by linked companies ids */ "filters[linkedCompaniesIds]"?: string; - /** Filter by linked companies ids */ + /** Filter by linked contacts ids */ "filters[linkedContactsIds]"?: string; - /** Filter (urlencoded) the contacts modified after a given UTC date-time (YYYY-MM-DDTHH:mm:ss.SSSZ). Prefer to pass your timezone in date-time format for accurate result. */ + /** Filter (urlencoded) the deals modified after a given UTC date-time (YYYY-MM-DDTHH:mm:ss.SSSZ). Prefer to pass your timezone in date-time format for accurate result. */ modifiedSince?: string; - /** Filter (urlencoded) the contacts created after a given UTC date-time (YYYY-MM-DDTHH:mm:ss.SSSZ). Prefer to pass your timezone in date-time format for accurate result. */ + /** Filter (urlencoded) the deals created after a given UTC date-time (YYYY-MM-DDTHH:mm:ss.SSSZ). Prefer to pass your timezone in date-time format for accurate result. */ createdSince?: string; /** Index of the first document of the page */ offset?: number; @@ -23,4 +23,6 @@ export interface GetCrmDealsRequest { limit?: number; /** Sort the results in the ascending/descending order. Default order is **descending** by creation if `sort` is not passed */ sort?: Brevo.GetCrmDealsRequestSort; + /** The field used to sort field names. */ + sortBy?: string; } diff --git a/src/api/resources/deals/client/requests/PatchCrmDealsIdRequest.ts b/src/api/resources/deals/client/requests/PatchCrmDealsIdRequest.ts index b71c9cb..dafac2e 100644 --- a/src/api/resources/deals/client/requests/PatchCrmDealsIdRequest.ts +++ b/src/api/resources/deals/client/requests/PatchCrmDealsIdRequest.ts @@ -10,7 +10,7 @@ export interface PatchCrmDealsIdRequest { id: string; /** Attributes for deal update To assign owner of a Deal you can send attributes.deal_owner and utilize the account email or ID. If you wish to update the pipeline of a deal you need to provide the `pipeline` and the `deal_stage` Pipeline and deal_stage are ids you can fetch using this endpoint `/crm/pipeline/details/{pipelineID}` */ attributes?: Record; - /** Warning - Using PATCH on linkedCompaniesIds replaces the list of linked contacts. Omitted IDs will be removed. */ + /** Warning - Using PATCH on linkedCompaniesIds replaces the list of linked companies. Omitted IDs will be removed. */ linkedCompaniesIds?: string[]; /** Warning - Using PATCH on linkedContactIds replaces the list of linked contacts. Omitted IDs will be removed. */ linkedContactsIds?: number[]; diff --git a/src/api/resources/deals/client/requests/PostCrmDealsImportRequest.ts b/src/api/resources/deals/client/requests/PostCrmDealsImportRequest.ts index 5910b03..5641c1b 100644 --- a/src/api/resources/deals/client/requests/PostCrmDealsImportRequest.ts +++ b/src/api/resources/deals/client/requests/PostCrmDealsImportRequest.ts @@ -13,7 +13,7 @@ export interface PostCrmDealsImportRequest { * The mapping options in JSON format. Here is an example of the JSON structure: ```json { * "link_entities": true, // Determines whether to link related entities during the import process * "unlink_entities": false, // Determines whether to unlink related entities during the import process - * "update_existing_records": true, // Determines whether to update based on company ID or treat every row as create + * "update_existing_records": true, // Determines whether to update based on deal ID or treat every row as create * "unset_empty_attributes": false // Determines whether to unset a specific attribute during update if the values input is blank * } ``` */ diff --git a/src/api/resources/deals/types/GetCrmAttributesDealsResponseItem.ts b/src/api/resources/deals/types/GetCrmAttributesDealsResponseItem.ts index 3fadd07..08404c1 100644 --- a/src/api/resources/deals/types/GetCrmAttributesDealsResponseItem.ts +++ b/src/api/resources/deals/types/GetCrmAttributesDealsResponseItem.ts @@ -1,12 +1,30 @@ // This file was auto-generated by Fern from our API Definition. /** - * List of attributes + * Deal attribute details */ export interface GetCrmAttributesDealsResponseItem { - attributeOptions?: Record[] | undefined; - attributeTypeName?: string | undefined; + /** Internal name of the attribute */ internalName?: string | undefined; - isRequired?: boolean | undefined; + /** Type of the attribute */ + attributeTypeName?: string | undefined; + /** Display label of the attribute */ label?: string | undefined; + /** Options for single-select or multi-choice attributes */ + attributeOptions?: GetCrmAttributesDealsResponseItem.AttributeOptions.Item[] | undefined; + /** Whether this attribute is required */ + isRequired?: boolean | undefined; + /** Whether this attribute value is read-only */ + isValueReadonly?: boolean | undefined; +} + +export namespace GetCrmAttributesDealsResponseItem { + export type AttributeOptions = AttributeOptions.Item[]; + + export namespace AttributeOptions { + export interface Item { + key?: string | undefined; + value?: string | undefined; + } + } } diff --git a/src/api/resources/domains/client/Client.ts b/src/api/resources/domains/client/Client.ts index de247ae..36cabf7 100644 --- a/src/api/resources/domains/client/Client.ts +++ b/src/api/resources/domains/client/Client.ts @@ -70,7 +70,7 @@ export class DomainsClient { ), method: "GET", headers: _headers, - queryParameters: requestOptions?.queryParams, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, abortSignal: requestOptions?.abortSignal, @@ -159,7 +159,7 @@ export class DomainsClient { method: "POST", headers: _headers, contentType: "application/json", - queryParameters: requestOptions?.queryParams, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), requestType: "json", body: request, timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, @@ -240,7 +240,7 @@ export class DomainsClient { ), method: "GET", headers: _headers, - queryParameters: requestOptions?.queryParams, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, abortSignal: requestOptions?.abortSignal, @@ -318,7 +318,7 @@ export class DomainsClient { ), method: "DELETE", headers: _headers, - queryParameters: requestOptions?.queryParams, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, abortSignal: requestOptions?.abortSignal, @@ -403,7 +403,7 @@ export class DomainsClient { ), method: "PUT", headers: _headers, - queryParameters: requestOptions?.queryParams, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, abortSignal: requestOptions?.abortSignal, diff --git a/src/api/resources/ecommerce/client/Client.ts b/src/api/resources/ecommerce/client/Client.ts index 1a92a4c..80f904d 100644 --- a/src/api/resources/ecommerce/client/Client.ts +++ b/src/api/resources/ecommerce/client/Client.ts @@ -23,6 +23,8 @@ export class EcommerceClient { } /** + * Retrieve a paginated list of all ecommerce categories stored in your Brevo account. Results are sorted by creation date in descending order by default, and can be filtered by category IDs, name, modification date, creation date, or deletion status. The response includes a `count` field with the total number of matching categories, and pagination defaults to 50 categories per page (maximum 100). + * * @param {Brevo.GetCategoriesRequest} request * @param {EcommerceClient.RequestOptions} requestOptions - Request-specific configuration. * @@ -68,7 +70,11 @@ export class EcommerceClient { ), method: "GET", headers: _headers, - queryParameters: { ..._queryParams, ...requestOptions?.queryParams }, + queryString: core.url + .queryBuilder() + .addMany(_queryParams) + .mergeAdditional(requestOptions?.queryParams) + .build(), timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, abortSignal: requestOptions?.abortSignal, @@ -96,6 +102,8 @@ export class EcommerceClient { } /** + * Create a new ecommerce category or update an existing one, identified by the mandatory `id` field. When `updateEnabled` is set to `false` (the default), the endpoint performs an insert and returns `201`; if the category ID already exists, a `400` error is returned. When `updateEnabled` is `true`, the endpoint performs an upsert, returning `201` for a new category or `204` when an existing category is updated. The `name` field is mandatory for creation but optional for updates. + * * @param {Brevo.CreateUpdateCategoryRequest} request * @param {EcommerceClient.RequestOptions} requestOptions - Request-specific configuration. * @@ -133,7 +141,7 @@ export class EcommerceClient { method: "POST", headers: _headers, contentType: "application/json", - queryParameters: requestOptions?.queryParams, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), requestType: "json", body: request, timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, @@ -166,6 +174,8 @@ export class EcommerceClient { } /** + * Create or update multiple ecommerce categories in a single request. The `categories` array accepts up to 100 category objects, each requiring a unique `id`. When `updateEnabled` is `false` (the default), all categories are inserted as new; if any ID already exists, a `400` error is returned. When `updateEnabled` is `true`, existing categories are updated and new ones are created via upsert. Duplicate IDs within the same request payload are rejected. The response returns the count of created and updated categories. + * * @param {Brevo.CreateUpdateBatchCategoryRequest} request * @param {EcommerceClient.RequestOptions} requestOptions - Request-specific configuration. * @@ -205,7 +215,7 @@ export class EcommerceClient { method: "POST", headers: _headers, contentType: "application/json", - queryParameters: requestOptions?.queryParams, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), requestType: "json", body: request, timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, @@ -238,6 +248,8 @@ export class EcommerceClient { } /** + * Retrieve the full details of a single ecommerce category by its unique ID. The response includes the category name, URL, creation and modification timestamps, and deletion status. Returns a `404` error if no category matches the provided ID. + * * @param {Brevo.GetCategoryInfoRequest} request * @param {EcommerceClient.RequestOptions} requestOptions - Request-specific configuration. * @@ -276,7 +288,7 @@ export class EcommerceClient { ), method: "GET", headers: _headers, - queryParameters: requestOptions?.queryParams, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, abortSignal: requestOptions?.abortSignal, @@ -338,7 +350,7 @@ export class EcommerceClient { ), method: "POST", headers: _headers, - queryParameters: requestOptions?.queryParams, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, abortSignal: requestOptions?.abortSignal, @@ -368,6 +380,8 @@ export class EcommerceClient { } /** + * Retrieve aggregated ecommerce attribution metrics for one or more Brevo email campaigns, SMS campaigns, or automation workflows. You can optionally filter by a date range using `periodFrom` and `periodTo` in RFC3339 format. The response includes per-source metrics (orders count, revenue, and average basket) as well as aggregated totals across all requested sources. + * * @param {Brevo.GetEcommerceAttributionMetricsRequest} request * @param {EcommerceClient.RequestOptions} requestOptions - Request-specific configuration. * @@ -376,7 +390,8 @@ export class EcommerceClient { * @example * await client.ecommerce.getAttributionMetricsForOneOrMoreBrevoCampaignsOrWorkflows({ * periodFrom: "2022-01-02T00:00:00Z", - * periodTo: "2022-01-03T00:00:00Z" + * periodTo: "2022-01-03T00:00:00Z", + * "emailCampaignId[]": ["sale"] * }) */ public getAttributionMetricsForOneOrMoreBrevoCampaignsOrWorkflows( @@ -423,7 +438,11 @@ export class EcommerceClient { ), method: "GET", headers: _headers, - queryParameters: { ..._queryParams, ...requestOptions?.queryParams }, + queryString: core.url + .queryBuilder() + .addMany(_queryParams) + .mergeAdditional(requestOptions?.queryParams) + .build(), timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, abortSignal: requestOptions?.abortSignal, @@ -459,6 +478,8 @@ export class EcommerceClient { } /** + * Retrieve detailed attribution metrics for a single Brevo campaign or automation workflow, identified by its conversion source type and ID. The response includes orders count, revenue, average basket value, and the number of new customers attributed to that specific campaign or workflow. + * * @param {Brevo.GetEcommerceAttributionMetricsConversionSourceConversionSourceIdRequest} request * @param {EcommerceClient.RequestOptions} requestOptions - Request-specific configuration. * @@ -499,7 +520,7 @@ export class EcommerceClient { ), method: "GET", headers: _headers, - queryParameters: requestOptions?.queryParams, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, abortSignal: requestOptions?.abortSignal, @@ -535,6 +556,8 @@ export class EcommerceClient { } /** + * Retrieve the list of products whose sales have been attributed to a specific Brevo campaign or automation workflow. Each product entry includes its ID, name, SKU, image URL, product URL, price, revenue, and orders count. The conversion source type must be one of `email_campaign`, `sms_campaign`, `automation_workflow_email`, or `automation_workflow_sms`. + * * @param {Brevo.GetEcommerceAttributionProductsConversionSourceConversionSourceIdRequest} request * @param {EcommerceClient.RequestOptions} requestOptions - Request-specific configuration. * @@ -575,7 +598,7 @@ export class EcommerceClient { ), method: "GET", headers: _headers, - queryParameters: requestOptions?.queryParams, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, abortSignal: requestOptions?.abortSignal, @@ -611,6 +634,8 @@ export class EcommerceClient { } /** + * Retrieve the ISO 4217 display currency code currently configured for your Brevo ecommerce account. This currency is used to display monetary values across the ecommerce dashboard and reports. Returns a `403` error if ecommerce is not activated on the account. + * * @param {EcommerceClient.RequestOptions} requestOptions - Request-specific configuration. * * @throws {@link Brevo.BadRequestError} @@ -646,7 +671,7 @@ export class EcommerceClient { ), method: "GET", headers: _headers, - queryParameters: requestOptions?.queryParams, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, abortSignal: requestOptions?.abortSignal, @@ -686,6 +711,8 @@ export class EcommerceClient { } /** + * Set or update the ISO 4217 display currency code for your Brevo ecommerce account. This currency determines how monetary values are displayed in the ecommerce dashboard and reports. The provided currency code must be a valid ISO 4217 code; invalid codes result in a `422` error. Returns a `403` error if ecommerce is not activated on the account. + * * @param {Brevo.SetConfigDisplayCurrencyRequest} request * @param {EcommerceClient.RequestOptions} requestOptions - Request-specific configuration. * @@ -726,7 +753,7 @@ export class EcommerceClient { method: "POST", headers: _headers, contentType: "application/json", - queryParameters: requestOptions?.queryParams, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), requestType: "json", body: request, timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, @@ -817,7 +844,11 @@ export class EcommerceClient { ), method: "GET", headers: _headers, - queryParameters: { ..._queryParams, ...requestOptions?.queryParams }, + queryString: core.url + .queryBuilder() + .addMany(_queryParams) + .mergeAdditional(requestOptions?.queryParams) + .build(), timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, abortSignal: requestOptions?.abortSignal, @@ -892,7 +923,7 @@ export class EcommerceClient { method: "POST", headers: _headers, contentType: "application/json", - queryParameters: requestOptions?.queryParams, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), requestType: "json", body: request, timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, @@ -971,7 +1002,7 @@ export class EcommerceClient { method: "POST", headers: _headers, contentType: "application/json", - queryParameters: requestOptions?.queryParams, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), requestType: "json", body: request, timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, @@ -1001,6 +1032,8 @@ export class EcommerceClient { } /** + * Retrieve a paginated list of all ecommerce products stored in your Brevo account. Results are sorted by creation date in descending order by default, and can be filtered by product IDs, name (minimum 3 characters), price range, category IDs, modification date, creation date, or deletion status. Use the `search` parameter to query across SKU, name, and ID simultaneously — results are prioritized as exact SKU match > SKU prefix match > name match > ID match. Pagination defaults to 50 products per page (maximum 1000), and the response includes a `count` field with the total number of matching products. + * * @param {Brevo.GetProductsRequest} request * @param {EcommerceClient.RequestOptions} requestOptions - Request-specific configuration. * @@ -1025,6 +1058,7 @@ export class EcommerceClient { offset, sort, ids, + search, name, "price[lte]": priceLte, "price[gte]": priceGte, @@ -1032,9 +1066,16 @@ export class EcommerceClient { "price[gt]": priceGt, "price[eq]": priceEq, "price[ne]": priceNe, + "alternativePrice[lte]": alternativePriceLte, + "alternativePrice[gte]": alternativePriceGte, + "alternativePrice[lt]": alternativePriceLt, + "alternativePrice[gt]": alternativePriceGt, + "alternativePrice[eq]": alternativePriceEq, + "alternativePrice[ne]": alternativePriceNe, categories, modifiedSince, createdSince, + sortByField, isDeleted, } = request; const _queryParams: Record = { @@ -1042,6 +1083,7 @@ export class EcommerceClient { offset, sort: sort != null ? sort : undefined, ids, + search, name, "price[lte]": priceLte, "price[gte]": priceGte, @@ -1049,9 +1091,16 @@ export class EcommerceClient { "price[gt]": priceGt, "price[eq]": priceEq, "price[ne]": priceNe, + "alternativePrice[lte]": alternativePriceLte, + "alternativePrice[gte]": alternativePriceGte, + "alternativePrice[lt]": alternativePriceLt, + "alternativePrice[gt]": alternativePriceGt, + "alternativePrice[eq]": alternativePriceEq, + "alternativePrice[ne]": alternativePriceNe, categories, modifiedSince, createdSince, + sortByField: sortByField != null ? sortByField : undefined, isDeleted, }; const _authRequest: core.AuthRequest = await this._options.authProvider.getAuthRequest(); @@ -1069,7 +1118,11 @@ export class EcommerceClient { ), method: "GET", headers: _headers, - queryParameters: { ..._queryParams, ...requestOptions?.queryParams }, + queryString: core.url + .queryBuilder() + .addMany(_queryParams) + .mergeAdditional(requestOptions?.queryParams) + .build(), timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, abortSignal: requestOptions?.abortSignal, @@ -1097,6 +1150,8 @@ export class EcommerceClient { } /** + * Create a new ecommerce product or update an existing one, identified by the mandatory `id` field. When `updateEnabled` is `false` (the default), the endpoint inserts a new product and returns `201`; if the product ID already exists, a `400` error is returned. When `updateEnabled` is `true`, the endpoint performs an upsert, returning `201` for a new product or `204` for an update. The `name` field is mandatory for creation but optional for updates. Product images are downloaded, validated (max 5 MB, formats: jpeg, jpg, png, bmp, gif, webp), and re-hosted on S3. The `metaInfo` object supports up to 20 keys with a cumulative size limit of approximately 1000 KB. + * * @param {Brevo.CreateUpdateProductRequest} request * @param {EcommerceClient.RequestOptions} requestOptions - Request-specific configuration. * @@ -1135,7 +1190,7 @@ export class EcommerceClient { method: "POST", headers: _headers, contentType: "application/json", - queryParameters: requestOptions?.queryParams, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), requestType: "json", body: request, timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, @@ -1168,6 +1223,8 @@ export class EcommerceClient { } /** + * Create or update multiple ecommerce products in a single request. The `products` array accepts up to 100 product objects for creation (or up to 1000 when `updateEnabled` is `true` and the account has an increased limit). Each product requires a unique `id` and `name` (name is mandatory for creation only). When `updateEnabled` is `false`, all products are inserted as new; if any ID already exists, a `400` error is returned. When `updateEnabled` is `true`, existing products are updated and new ones are created via upsert. Duplicate IDs within the same request payload are rejected. The response returns the count of created and updated products. + * * @param {Brevo.CreateUpdateBatchProductsRequest} request * @param {EcommerceClient.RequestOptions} requestOptions - Request-specific configuration. * @@ -1208,7 +1265,7 @@ export class EcommerceClient { method: "POST", headers: _headers, contentType: "application/json", - queryParameters: requestOptions?.queryParams, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), requestType: "json", body: request, timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, @@ -1241,6 +1298,8 @@ export class EcommerceClient { } /** + * Retrieve the full details of a single ecommerce product by its unique ID. The response includes the product name, price, SKU, URL, image URLs (original and thumbnails), categories, stock level, meta information, creation and modification timestamps, and deletion status. Returns a `404` error if no product matches the provided ID. + * * @param {Brevo.GetProductInfoRequest} request * @param {EcommerceClient.RequestOptions} requestOptions - Request-specific configuration. * @@ -1279,7 +1338,7 @@ export class EcommerceClient { ), method: "GET", headers: _headers, - queryParameters: requestOptions?.queryParams, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, abortSignal: requestOptions?.abortSignal, @@ -1309,6 +1368,8 @@ export class EcommerceClient { } /** + * Register a contact to receive an alert for a specific product event, such as `back_in_stock`. At least one contact identifier (`ext_id`, `email`, or `sms`) must be provided; when multiple are given, priority is `ext_id` > `email` > `sms`. Returns a `404` error if the product ID does not exist, and a `403` error if product alerts are not enabled for the account. + * * @param {Brevo.CreateProductAlertRequest} request * @param {EcommerceClient.RequestOptions} requestOptions - Request-specific configuration. * @@ -1351,7 +1412,7 @@ export class EcommerceClient { method: "POST", headers: _headers, contentType: "application/json", - queryParameters: requestOptions?.queryParams, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), requestType: "json", body: _body, timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, diff --git a/src/api/resources/ecommerce/client/requests/CreateBatchOrderRequest.ts b/src/api/resources/ecommerce/client/requests/CreateBatchOrderRequest.ts index 62a9c47..504a9c8 100644 --- a/src/api/resources/ecommerce/client/requests/CreateBatchOrderRequest.ts +++ b/src/api/resources/ecommerce/client/requests/CreateBatchOrderRequest.ts @@ -19,9 +19,9 @@ import type * as Brevo from "../../../../index.js"; * } */ export interface CreateBatchOrderRequest { - /** Defines wether you want your orders to be considered as live data or as historical data (import of past data, synchronising data). True: orders will not trigger any automation workflows. False: orders will trigger workflows as usual. */ + /** Defines whether you want your orders to be considered as live data or as historical data (import of past data, synchronising data). True: orders will not trigger any automation workflows. False: orders will trigger workflows as usual. */ historical?: boolean; - /** Notify Url provided by client_dev to get the status of batch request */ + /** Webhook URL to receive the status of the batch request */ notifyUrl?: string; /** array of order objects */ orders: Brevo.Order[]; diff --git a/src/api/resources/ecommerce/client/requests/CreateUpdateBatchProductsRequest.ts b/src/api/resources/ecommerce/client/requests/CreateUpdateBatchProductsRequest.ts index b34e33b..daa9a29 100644 --- a/src/api/resources/ecommerce/client/requests/CreateUpdateBatchProductsRequest.ts +++ b/src/api/resources/ecommerce/client/requests/CreateUpdateBatchProductsRequest.ts @@ -12,7 +12,7 @@ export interface CreateUpdateBatchProductsRequest { /** array of products objects */ products: CreateUpdateBatchProductsRequest.Products.Item[]; - /** Facilitate to update the existing categories in the same request (updateEnabled = true) */ + /** Facilitate to update the existing products in the same request (updateEnabled = true) */ updateEnabled?: boolean; } @@ -37,12 +37,14 @@ export namespace CreateUpdateBatchProductsRequest { isDeleted?: boolean | undefined; /** Meta data of product such as description, vendor, producer, stock level. The total characters of cumulative metaInfo shall not exceed **20000 characters**. */ metaInfo?: Record | undefined; - /** Mandatory in case of creation**. Name of the product for which you requested the details */ + /** **Mandatory in case of creation**. Name of the product, as displayed in the shop */ name: string; /** Parent product id of the product */ parentId?: string | undefined; /** Price of the product */ price?: number | undefined; + /** Alternative price of the product */ + alternativePrice?: number | undefined; /** Product identifier from the shop */ sku?: string | undefined; /** Current stock value of the product from the shop's database */ diff --git a/src/api/resources/ecommerce/client/requests/CreateUpdateProductRequest.ts b/src/api/resources/ecommerce/client/requests/CreateUpdateProductRequest.ts index 68fe8d9..0d45390 100644 --- a/src/api/resources/ecommerce/client/requests/CreateUpdateProductRequest.ts +++ b/src/api/resources/ecommerce/client/requests/CreateUpdateProductRequest.ts @@ -24,17 +24,19 @@ export interface CreateUpdateProductRequest { isDeleted?: boolean; /** Meta data of product such as description, vendor, producer, stock level. The total characters of cumulative metaInfo shall not exceed **20000 characters**. */ metaInfo?: Record; - /** Mandatory in case of creation**. Name of the product for which you requested the details */ + /** **Mandatory in case of creation**. Name of the product, as displayed in the shop */ name: string; /** Parent product id of the product */ parentId?: string; /** Price of the product */ price?: number; + /** Alternative price of the product */ + alternativePrice?: number; /** Product identifier from the shop */ sku?: string; /** Current stock value of the product from the shop's database */ stock?: number; - /** Facilitate to update the existing category in the same request (updateEnabled = true) */ + /** Facilitate to update the existing product in the same request (updateEnabled = true) */ updateEnabled?: boolean; /** URL to the product */ url?: string; diff --git a/src/api/resources/ecommerce/client/requests/GetEcommerceAttributionMetricsRequest.ts b/src/api/resources/ecommerce/client/requests/GetEcommerceAttributionMetricsRequest.ts index a715215..2c1d8f9 100644 --- a/src/api/resources/ecommerce/client/requests/GetEcommerceAttributionMetricsRequest.ts +++ b/src/api/resources/ecommerce/client/requests/GetEcommerceAttributionMetricsRequest.ts @@ -4,7 +4,8 @@ * @example * { * periodFrom: "2022-01-02T00:00:00Z", - * periodTo: "2022-01-03T00:00:00Z" + * periodTo: "2022-01-03T00:00:00Z", + * "emailCampaignId[]": ["sale"] * } */ export interface GetEcommerceAttributionMetricsRequest { diff --git a/src/api/resources/ecommerce/client/requests/GetProductsRequest.ts b/src/api/resources/ecommerce/client/requests/GetProductsRequest.ts index c2b6aa0..9bacbf9 100644 --- a/src/api/resources/ecommerce/client/requests/GetProductsRequest.ts +++ b/src/api/resources/ecommerce/client/requests/GetProductsRequest.ts @@ -15,6 +15,8 @@ export interface GetProductsRequest { sort?: Brevo.GetProductsRequestSort; /** Filter by product ids */ ids?: string | string[]; + /** Search products simultaneously across SKU, name, and ID fields. Results are returned in the following priority order: **exact SKU match** > **SKU prefix match** > **name match** > **ID match**. For example, `?search=123` on products with `{sku: "123"}` and `{sku: "123456"}` returns the exact SKU match first. */ + search?: string; /** Filter by product name, minimum 3 characters should be present for search. */ name?: string; /** Price filter for products less than and equals to particular amount */ @@ -29,12 +31,26 @@ export interface GetProductsRequest { "price[eq]"?: number; /** Price filter for products not equals to particular amount */ "price[ne]"?: number; + /** Alternative price filter for products less than and equals to particular amount */ + "alternativePrice[lte]"?: number; + /** Alternative price filter for products greater than and equals to particular amount */ + "alternativePrice[gte]"?: number; + /** Alternative price filter for products less than particular amount */ + "alternativePrice[lt]"?: number; + /** Alternative price filter for products greater than particular amount */ + "alternativePrice[gt]"?: number; + /** Alternative price filter for products equals to particular amount */ + "alternativePrice[eq]"?: number; + /** Alternative price filter for products not equals to particular amount */ + "alternativePrice[ne]"?: number; /** Filter by categories ids */ categories?: string | string[]; - /** Filter (urlencoded) the orders modified after a given UTC date-time (YYYY-MM-DDTHH:mm:ss.SSSZ). **Prefer to pass your timezone in date-time format for accurate result.** */ + /** Filter (urlencoded) the products modified after a given UTC date-time (YYYY-MM-DDTHH:mm:ss.SSSZ). **Prefer to pass your timezone in date-time format for accurate result.** */ modifiedSince?: string; - /** Filter (urlencoded) the orders created after a given UTC date-time (YYYY-MM-DDTHH:mm:ss.SSSZ). **Prefer to pass your timezone in date-time format for accurate result.** */ + /** Filter (urlencoded) the products created after a given UTC date-time (YYYY-MM-DDTHH:mm:ss.SSSZ). **Prefer to pass your timezone in date-time format for accurate result.** */ createdSince?: string; + /** Sort the results by a specific field. Default sort field is `created_at` when not passed. */ + sortByField?: Brevo.GetProductsRequestSortByField; /** Filter products by their deletion status. If `false` is passed, only products that are not deleted will be returned. */ isDeleted?: string; } diff --git a/src/api/resources/ecommerce/types/CreateUpdateCategoryResponse.ts b/src/api/resources/ecommerce/types/CreateUpdateCategoryResponse.ts index 2901a3c..849f753 100644 --- a/src/api/resources/ecommerce/types/CreateUpdateCategoryResponse.ts +++ b/src/api/resources/ecommerce/types/CreateUpdateCategoryResponse.ts @@ -2,5 +2,5 @@ export interface CreateUpdateCategoryResponse { /** ID of the category when a new category is created */ - id?: number | undefined; + id?: string | undefined; } diff --git a/src/api/resources/ecommerce/types/CreateUpdateProductResponse.ts b/src/api/resources/ecommerce/types/CreateUpdateProductResponse.ts index edeab69..63572b5 100644 --- a/src/api/resources/ecommerce/types/CreateUpdateProductResponse.ts +++ b/src/api/resources/ecommerce/types/CreateUpdateProductResponse.ts @@ -1,6 +1,6 @@ // This file was auto-generated by Fern from our API Definition. export interface CreateUpdateProductResponse { - /** ID of the Product when a new product is created */ - id?: number | undefined; + /** ID of the product when a new product is created */ + id?: string | undefined; } diff --git a/src/api/resources/ecommerce/types/GetProductsRequestSortByField.ts b/src/api/resources/ecommerce/types/GetProductsRequestSortByField.ts new file mode 100644 index 0000000..2b4cfcd --- /dev/null +++ b/src/api/resources/ecommerce/types/GetProductsRequestSortByField.ts @@ -0,0 +1,10 @@ +// This file was auto-generated by Fern from our API Definition. + +export const GetProductsRequestSortByField = { + CreatedAt: "created_at", + Name: "name", + Price: "price", + Id: "id", +} as const; +export type GetProductsRequestSortByField = + (typeof GetProductsRequestSortByField)[keyof typeof GetProductsRequestSortByField]; diff --git a/src/api/resources/ecommerce/types/index.ts b/src/api/resources/ecommerce/types/index.ts index 45ea6ad..f4da27e 100644 --- a/src/api/resources/ecommerce/types/index.ts +++ b/src/api/resources/ecommerce/types/index.ts @@ -13,5 +13,6 @@ export * from "./GetEcommerceAttributionProductsConversionSourceConversionSource export * from "./GetEcommerceConfigDisplayCurrencyResponse.js"; export * from "./GetOrdersRequestSort.js"; export * from "./GetProductsRequestSort.js"; +export * from "./GetProductsRequestSortByField.js"; export * from "./GetProductsResponse.js"; export * from "./SetConfigDisplayCurrencyResponse.js"; diff --git a/src/api/resources/emailCampaigns/client/Client.ts b/src/api/resources/emailCampaigns/client/Client.ts index d9758c5..ff6cad8 100644 --- a/src/api/resources/emailCampaigns/client/Client.ts +++ b/src/api/resources/emailCampaigns/client/Client.ts @@ -24,7 +24,7 @@ export class EmailCampaignsClient { /** * The response payload for this endpoint has changed - * You now need to specify which type of statistics you would like to retrieve. For more information visit [this page](https://developers.brevo.com/changelog/get-all-marketing-campaigns). + * You now need to specify which type of statistics you would like to retrieve. For more information visit [this page](https://developers.brevo.com/changelog/2023/2/7). * * @param {Brevo.GetEmailCampaignsRequest} request * @param {EmailCampaignsClient.RequestOptions} requestOptions - Request-specific configuration. @@ -55,6 +55,7 @@ export class EmailCampaignsClient { offset, sort, excludeHtmlContent, + excludePdfAttachment, } = request; const _queryParams: Record = { type: type_ != null ? type_ : undefined, @@ -66,6 +67,7 @@ export class EmailCampaignsClient { offset, sort: sort != null ? sort : undefined, excludeHtmlContent, + excludePdfAttachment, }; const _authRequest: core.AuthRequest = await this._options.authProvider.getAuthRequest(); const _headers: core.Fetcher.Args["headers"] = mergeHeaders( @@ -82,7 +84,11 @@ export class EmailCampaignsClient { ), method: "GET", headers: _headers, - queryParameters: { ..._queryParams, ...requestOptions?.queryParams }, + queryString: core.url + .queryBuilder() + .addMany(_queryParams) + .mergeAdditional(requestOptions?.queryParams) + .build(), timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, abortSignal: requestOptions?.abortSignal, @@ -110,10 +116,13 @@ export class EmailCampaignsClient { } /** + * Create a new email campaign. The campaign requires at minimum a name and sender details, and is created in draft status by default. You must provide email content via one of three mutually exclusive options: htmlContent (inline HTML), htmlUrl (remote URL), or templateId (existing template); additionally, A/B testing can be enabled by setting abTesting to true with subjectA and subjectB, but this is incompatible with sendAtBestTime. + * * @param {Brevo.CreateEmailCampaignRequest} request * @param {EmailCampaignsClient.RequestOptions} requestOptions - Request-specific configuration. * * @throws {@link Brevo.BadRequestError} + * @throws {@link Brevo.MethodNotAllowedError} * * @example * await client.emailCampaigns.createEmailCampaign({ @@ -148,7 +157,7 @@ export class EmailCampaignsClient { method: "POST", headers: _headers, contentType: "application/json", - queryParameters: requestOptions?.queryParams, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), requestType: "json", body: request, timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, @@ -165,6 +174,11 @@ export class EmailCampaignsClient { switch (_response.error.statusCode) { case 400: throw new Brevo.BadRequestError(_response.error.body as unknown, _response.rawResponse); + case 405: + throw new Brevo.MethodNotAllowedError( + _response.error.body as Brevo.ErrorModel, + _response.rawResponse, + ); default: throw new errors.BrevoError({ statusCode: _response.error.statusCode, @@ -178,6 +192,8 @@ export class EmailCampaignsClient { } /** + * Upload an image to your account''s image gallery by providing an absolute URL to the image. The maximum allowed image size is 2MB and supported formats are jpeg, jpg, png, bmp, and gif; local file uploads are not supported. + * * @param {Brevo.UploadImageToGalleryRequest} request * @param {EmailCampaignsClient.RequestOptions} requestOptions - Request-specific configuration. * @@ -215,7 +231,7 @@ export class EmailCampaignsClient { method: "POST", headers: _headers, contentType: "application/json", - queryParameters: requestOptions?.queryParams, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), requestType: "json", body: request, timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, @@ -245,6 +261,8 @@ export class EmailCampaignsClient { } /** + * Retrieve detailed information about a specific email campaign by its ID, including recipients, statistics, and HTML content. Use the statistics query parameter to select which statistics to include (globalStats, linksStats, statsByDomain, statsByDevice, or statsByBrowser); statsByDevice and statsByBrowser are only available on this single-campaign endpoint. You can exclude HTML content from the response by setting excludeHtmlContent to true. + * * @param {Brevo.GetEmailCampaignRequest} request * @param {EmailCampaignsClient.RequestOptions} requestOptions - Request-specific configuration. * @@ -287,7 +305,11 @@ export class EmailCampaignsClient { ), method: "GET", headers: _headers, - queryParameters: { ..._queryParams, ...requestOptions?.queryParams }, + queryString: core.url + .queryBuilder() + .addMany(_queryParams) + .mergeAdditional(requestOptions?.queryParams) + .build(), timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, abortSignal: requestOptions?.abortSignal, @@ -317,11 +339,14 @@ export class EmailCampaignsClient { } /** + * Update an existing email campaign''s properties such as name, subject, content, sender, recipients, schedule, and A/B testing configuration. The campaign must exist and the request body must contain at least one valid field to update. Only draft or scheduled campaigns can be modified; if sendAtBestTime is enabled, IP warmup will be automatically disabled. + * * @param {Brevo.UpdateEmailCampaignRequest} request * @param {EmailCampaignsClient.RequestOptions} requestOptions - Request-specific configuration. * * @throws {@link Brevo.BadRequestError} * @throws {@link Brevo.NotFoundError} + * @throws {@link Brevo.MethodNotAllowedError} * * @example * await client.emailCampaigns.updateEmailCampaign({ @@ -356,7 +381,7 @@ export class EmailCampaignsClient { method: "PUT", headers: _headers, contentType: "application/json", - queryParameters: requestOptions?.queryParams, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), requestType: "json", body: _body, timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, @@ -375,6 +400,11 @@ export class EmailCampaignsClient { throw new Brevo.BadRequestError(_response.error.body as unknown, _response.rawResponse); case 404: throw new Brevo.NotFoundError(_response.error.body as unknown, _response.rawResponse); + case 405: + throw new Brevo.MethodNotAllowedError( + _response.error.body as Brevo.ErrorModel, + _response.rawResponse, + ); default: throw new errors.BrevoError({ statusCode: _response.error.statusCode, @@ -388,10 +418,13 @@ export class EmailCampaignsClient { } /** + * Delete an email campaign by its campaign ID. Only campaigns that have not been scheduled can be deleted; attempting to delete a campaign that has already been scheduled will return a 403 permission denied error. Related data in templates, newsletter builder, and schedule collections is also cleaned up. + * * @param {Brevo.DeleteEmailCampaignRequest} request * @param {EmailCampaignsClient.RequestOptions} requestOptions - Request-specific configuration. * * @throws {@link Brevo.BadRequestError} + * @throws {@link Brevo.ForbiddenError} * @throws {@link Brevo.NotFoundError} * * @example @@ -426,7 +459,7 @@ export class EmailCampaignsClient { ), method: "DELETE", headers: _headers, - queryParameters: requestOptions?.queryParams, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, abortSignal: requestOptions?.abortSignal, @@ -441,6 +474,8 @@ export class EmailCampaignsClient { switch (_response.error.statusCode) { case 400: throw new Brevo.BadRequestError(_response.error.body as unknown, _response.rawResponse); + case 403: + throw new Brevo.ForbiddenError(_response.error.body as unknown, _response.rawResponse); case 404: throw new Brevo.NotFoundError(_response.error.body as unknown, _response.rawResponse); default: @@ -501,7 +536,7 @@ export class EmailCampaignsClient { ), method: "GET", headers: _headers, - queryParameters: requestOptions?.queryParams, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, abortSignal: requestOptions?.abortSignal, @@ -539,6 +574,8 @@ export class EmailCampaignsClient { } /** + * Export the recipients of a sent email campaign as an asynchronous process, filtered by recipient type (e.g. openers, clickers, hardBounces). The recipientsType field is required and determines which subset of recipients to export. An optional notifyURL webhook will be called once the export is complete, and the response returns a processId to track the export status. + * * @param {Brevo.EmailExportRecipientsRequest} request * @param {EmailCampaignsClient.RequestOptions} requestOptions - Request-specific configuration. * @@ -579,7 +616,7 @@ export class EmailCampaignsClient { method: "POST", headers: _headers, contentType: "application/json", - queryParameters: requestOptions?.queryParams, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), requestType: "json", body: _body, timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, @@ -616,6 +653,8 @@ export class EmailCampaignsClient { } /** + * Send an existing email campaign immediately by scheduling it for the current time. The campaign must have valid recipients and content configured before sending. The system verifies your account''s send limit and credit balance before dispatching; if credits are insufficient, a 402 error is returned. + * * @param {Brevo.SendEmailCampaignNowRequest} request * @param {EmailCampaignsClient.RequestOptions} requestOptions - Request-specific configuration. * @@ -655,7 +694,7 @@ export class EmailCampaignsClient { ), method: "POST", headers: _headers, - queryParameters: requestOptions?.queryParams, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, abortSignal: requestOptions?.abortSignal, @@ -742,7 +781,7 @@ export class EmailCampaignsClient { method: "POST", headers: _headers, contentType: "application/json", - queryParameters: requestOptions?.queryParams, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), requestType: "json", body: _body, timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, @@ -779,6 +818,8 @@ export class EmailCampaignsClient { } /** + * Send a test version of an email campaign to specified email addresses or your entire test list. If the emailTo array is left empty, the test mail will be sent to all addresses in your test list. You can send a maximum of 50 test emails per day. + * * @param {Brevo.SendTestEmailRequest} request * @param {EmailCampaignsClient.RequestOptions} requestOptions - Request-specific configuration. * @@ -819,7 +860,7 @@ export class EmailCampaignsClient { method: "POST", headers: _headers, contentType: "application/json", - queryParameters: requestOptions?.queryParams, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), requestType: "json", body: _body, timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, @@ -897,7 +938,7 @@ export class EmailCampaignsClient { ), method: "GET", headers: _headers, - queryParameters: requestOptions?.queryParams, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, abortSignal: requestOptions?.abortSignal, @@ -937,6 +978,8 @@ export class EmailCampaignsClient { } /** + * Update the status of an email campaign, such as suspending, archiving, or replicating it. Available status values include suspended, archive, darchive, sent, queued, replicate, replicateTemplate, cancel, and draft. Note that the replicateTemplate status is only available for template type campaigns. + * * @param {Brevo.UpdateCampaignStatusRequest} request * @param {EmailCampaignsClient.RequestOptions} requestOptions - Request-specific configuration. * @@ -977,7 +1020,7 @@ export class EmailCampaignsClient { method: "PUT", headers: _headers, contentType: "application/json", - queryParameters: requestOptions?.queryParams, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), requestType: "json", body: _body, timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, diff --git a/src/api/resources/emailCampaigns/client/requests/CreateEmailCampaignRequest.ts b/src/api/resources/emailCampaigns/client/requests/CreateEmailCampaignRequest.ts index 883f201..aaf2dce 100644 --- a/src/api/resources/emailCampaigns/client/requests/CreateEmailCampaignRequest.ts +++ b/src/api/resources/emailCampaigns/client/requests/CreateEmailCampaignRequest.ts @@ -18,9 +18,9 @@ export interface CreateEmailCampaignRequest { footer?: string; /** Header of the email campaign */ header?: string; - /** Mandatory if htmlUrl and templateId are empty. Body of the message (HTML). */ + /** **Mandatory if htmlUrl and templateId are empty.** Body of the message (HTML). Must have more than 10 characters and be less than 1MB in size. Cannot be used together with `htmlUrl` or `templateId`. */ htmlContent?: string; - /** **Mandatory if htmlContent and templateId are empty**. Url to the message (HTML). For example: **https://html.domain.com** */ + /** **Mandatory if htmlContent and templateId are empty.** URL to the message (HTML). Cannot be used together with `htmlContent` or `templateId`. For example: **https://html.domain.com** */ htmlUrl?: string; /** **Mandatory if ipWarmupEnable is set to true**. Set a percentage increase rate for warming up your ip. We recommend you set the increase rate to 30% per day. If you want to send the same number of emails every day, set the daily increase value to 0%. */ increaseRate?: number; @@ -46,7 +46,7 @@ export interface CreateEmailCampaignRequest { scheduledAt?: string; /** Set this to true if you want to send your campaign at best time. */ sendAtBestTime?: boolean; - /** Sender details including id or email and name (_optional_). Only one of either Sender's email or Sender's ID shall be passed in one request at a time. For example: **{"name":"xyz", "email":"example@abc.com"}** **{"name":"xyz", "id":123}** */ + /** Sender details including id or email and name (optional). Only one of either Sender’s email or Sender’s ID shall be passed in one request at a time. Passing both `email` and `id` will result in an error. For example: **{"name":"xyz", "email":"example@abc.com"}** or **{"name":"xyz", "id":123}** */ sender: CreateEmailCampaignRequest.Sender; /** Add the size of your test groups. **Mandatory if abTesting = true & 'recipients' is passed**. We'll send version A and B to a random sample of recipients, and then the winning version to everyone else */ splitRule?: number; @@ -58,7 +58,7 @@ export interface CreateEmailCampaignRequest { subjectB?: string; /** Tag of the campaign */ tag?: string; - /** **Mandatory if htmlContent and htmlUrl are empty**. Id of the transactional email template with status _active_. Used to copy only its content fetched from htmlContent/htmlUrl to an email campaign for RSS feature. */ + /** **Mandatory if htmlContent and htmlUrl are empty.** Id of the transactional email template with status _active_. Used to copy only its content fetched from htmlContent/htmlUrl to an email campaign for RSS feature. Cannot be used together with `htmlContent` or `htmlUrl`. */ templateId?: number; /** To personalize the **To** Field. If you want to include the first name and last name of your recipient, add **{FNAME} {LNAME}**. These contact attributes must already exist in your Brevo account. If input parameter **params** used please use **{{contact.FNAME}} {{contact.LNAME}}** for personalization */ toField?: string; @@ -110,12 +110,12 @@ export namespace CreateEmailCampaignRequest { } /** - * Sender details including id or email and name (_optional_). Only one of either Sender's email or Sender's ID shall be passed in one request at a time. For example: **{"name":"xyz", "email":"example@abc.com"}** **{"name":"xyz", "id":123}** + * Sender details including id or email and name (optional). Only one of either Sender’s email or Sender’s ID shall be passed in one request at a time. Passing both `email` and `id` will result in an error. For example: **{"name":"xyz", "email":"example@abc.com"}** or **{"name":"xyz", "id":123}** */ export interface Sender { - /** Sender email */ + /** Sender email. Must be a valid email address. Cannot be used together with `id` in the same request. */ email?: string | undefined; - /** Select the sender for the campaign on the basis of sender id. _In order to select a sender with specific pool of IP’s, dedicated ip users shall pass id (instead of email)_. */ + /** Select the sender for the campaign on the basis of sender id. Cannot be used together with `email` in the same request. _In order to select a sender with a specific pool of IPs, dedicated IP users shall pass id (instead of email)._ */ id?: number | undefined; /** Sender Name */ name?: string | undefined; diff --git a/src/api/resources/emailCampaigns/client/requests/GetEmailCampaignRequest.ts b/src/api/resources/emailCampaigns/client/requests/GetEmailCampaignRequest.ts index d176a52..209aeae 100644 --- a/src/api/resources/emailCampaigns/client/requests/GetEmailCampaignRequest.ts +++ b/src/api/resources/emailCampaigns/client/requests/GetEmailCampaignRequest.ts @@ -11,7 +11,7 @@ import type * as Brevo from "../../../../index.js"; export interface GetEmailCampaignRequest { /** Id of the campaign */ campaignId: number; - /** Filter on type of the statistics required. Example **globalStats** value will only fetch globalStats info of the campaign in returned response. */ + /** Filter on the type of statistics required. Example: **globalStats** value will only fetch globalStats info of the campaign in the returned response. `statsByDevice` and `statsByBrowser` are only available when retrieving a single campaign (not in the list endpoint). */ statistics?: Brevo.GetEmailCampaignRequestStatistics; /** Use this flag to exclude htmlContent from the response body. If set to **true**, htmlContent field will be returned as empty string in the response body */ excludeHtmlContent?: boolean; diff --git a/src/api/resources/emailCampaigns/client/requests/GetEmailCampaignsRequest.ts b/src/api/resources/emailCampaigns/client/requests/GetEmailCampaignsRequest.ts index 9eb4bda..a4260e5 100644 --- a/src/api/resources/emailCampaigns/client/requests/GetEmailCampaignsRequest.ts +++ b/src/api/resources/emailCampaigns/client/requests/GetEmailCampaignsRequest.ts @@ -11,11 +11,11 @@ export interface GetEmailCampaignsRequest { type?: Brevo.GetEmailCampaignsRequestType; /** Filter on the status of the campaign */ status?: Brevo.GetEmailCampaignsRequestStatus; - /** Filter on type of the statistics required. Example **globalStats** value will only fetch globalStats info of the campaign in returned response.This option only returns data for events occurred in the last 6 months.For older campaigns, it’s advisable to use the **Get Campaign Report** endpoint. */ + /** Filter on the type of statistics required. Example: **globalStats** value will only fetch globalStats info of the campaign in the returned response. This option only returns data for events that occurred in the last 6 months. For older campaigns, it is advisable to use the **Get Campaign Report** endpoint. */ statistics?: Brevo.GetEmailCampaignsRequestStatistics; - /** **Mandatory if endDate is used**. Starting (urlencoded) UTC date-time (YYYY-MM-DDTHH:mm:ss.SSSZ) to filter the sent email campaigns. **Prefer to pass your timezone in date-time format for accurate result** ( only available if either 'status' not passed and if passed is set to 'sent' ) */ + /** **Mandatory if endDate is used.** Starting (urlencoded) UTC date-time (YYYY-MM-DDTHH:mm:ss.SSSZ) to filter the sent email campaigns. **Prefer to pass your timezone in date-time format for accurate result.** Only available if `status` is not passed or is set to `sent`. The date range between `startDate` and `endDate` must not exceed 2 years. `startDate` must not be in the future. */ startDate?: string; - /** **Mandatory if startDate is used**. Ending (urlencoded) UTC date-time (YYYY-MM-DDTHH:mm:ss.SSSZ) to filter the sent email campaigns. **Prefer to pass your timezone in date-time format for accurate result** ( only available if either 'status' not passed and if passed is set to 'sent' ) */ + /** **Mandatory if startDate is used.** Ending (urlencoded) UTC date-time (YYYY-MM-DDTHH:mm:ss.SSSZ) to filter the sent email campaigns. **Prefer to pass your timezone in date-time format for accurate result.** Only available if `status` is not passed or is set to `sent`. The date range between `startDate` and `endDate` must not exceed 2 years. `endDate` must not be in the future. */ endDate?: string; /** Number of documents per page */ limit?: number; @@ -23,6 +23,8 @@ export interface GetEmailCampaignsRequest { offset?: number; /** Sort the results in the ascending/descending order of record creation. Default order is **descending** if `sort` is not passed */ sort?: Brevo.GetEmailCampaignsRequestSort; - /** Use this flag to exclude htmlContent from the response body. If set to **true**, htmlContent field will be returned as empty string in the response body */ + /** Use this flag to exclude htmlContent from the response body. If set to **true**, the htmlContent field will be returned as an empty string in the response body. */ excludeHtmlContent?: boolean; + /** Use this flag to filter out campaigns that have a PDF attachment. If set to **true**, only campaigns without a PDF attachment (or with no attachment at all) will be returned. */ + excludePdfAttachment?: boolean; } diff --git a/src/api/resources/emailCampaigns/types/GetEmailCampaignResponse.ts b/src/api/resources/emailCampaigns/types/GetEmailCampaignResponse.ts index a6642f8..75310df 100644 --- a/src/api/resources/emailCampaigns/types/GetEmailCampaignResponse.ts +++ b/src/api/resources/emailCampaigns/types/GetEmailCampaignResponse.ts @@ -33,8 +33,12 @@ export interface GetEmailCampaignResponse { winnerCriteria?: string | undefined; /** The duration of the test in hours at the end of which the winning version will be sent. Only available if `abTesting` flag of the campaign is `true` */ winnerDelay?: number | undefined; + /** URL of the attachment file associated with the campaign. Empty string if no attachment is present. */ + attachmentUrl?: string | undefined; /** Creation UTC date-time of the campaign (YYYY-MM-DDTHH:mm:ss.SSSZ) */ createdAt: string; + /** Expiration date configuration for the email campaign, if set. Contains the duration and unit of the email expiry. */ + emailExpirationDate?: GetEmailCampaignResponse.EmailExpirationDate | undefined; /** Footer of the campaign */ footer: string; /** Header of the campaign */ @@ -56,7 +60,7 @@ export interface GetEmailCampaignResponse { sender: GetEmailCampaignResponse.Sender; /** Sent UTC date-time of the campaign (YYYY-MM-DDTHH:mm:ss.SSSZ). Only available if 'status' of the campaign is 'sent' */ sentDate?: string | undefined; - /** Link to share the campaign on social medias */ + /** Link to share the campaign on social media. For trigger campaigns, this returns a descriptive message instead of a URL. For classic campaigns that have not been sent, this also returns a descriptive message. */ shareLink?: string | undefined; /** Tag of the campaign */ tag?: string | undefined; @@ -66,12 +70,13 @@ export interface GetEmailCampaignResponse { testSent: boolean; /** Customisation of the "to" field of the campaign */ toField?: string | undefined; - /** utm parameter associated with campaign */ + /** The utm_campaign value associated with the campaign. Only present if a UTM campaign value was set. */ utmCampaignValue?: string | undefined; - /** utm id active */ - utmIDActive?: boolean | undefined; + /** The campaign ID used as utm_id parameter. Only present if UTM campaign tracking with ID is enabled. */ + utmID?: number | undefined; + /** The utm_medium value. Set to "EMAIL" when UTM campaign tracking is enabled. */ utmMedium?: string | undefined; - /** source of utm */ + /** The utm_source value. Set to "Brevo" when UTM campaign tracking is enabled. */ utmSource?: string | undefined; recipients: Brevo.GetCampaignRecipients; statistics: Brevo.GetExtendedCampaignStats; @@ -98,6 +103,26 @@ export namespace GetEmailCampaignResponse { } as const; export type Type = (typeof Type)[keyof typeof Type]; + /** + * Expiration date configuration for the email campaign, if set. Contains the duration and unit of the email expiry. + */ + export interface EmailExpirationDate { + /** Duration of the email expiry */ + duration?: number | undefined; + /** Unit of the duration */ + unit?: EmailExpirationDate.Unit | undefined; + } + + export namespace EmailExpirationDate { + /** Unit of the duration */ + export const Unit = { + Days: "days", + Weeks: "weeks", + Months: "months", + } as const; + export type Unit = (typeof Unit)[keyof typeof Unit]; + } + export interface Sender { /** Sender email of the campaign */ email?: string | undefined; diff --git a/src/api/resources/emailCampaigns/types/GetEmailCampaignsResponse.ts b/src/api/resources/emailCampaigns/types/GetEmailCampaignsResponse.ts index 71d563b..49f8ad9 100644 --- a/src/api/resources/emailCampaigns/types/GetEmailCampaignsResponse.ts +++ b/src/api/resources/emailCampaigns/types/GetEmailCampaignsResponse.ts @@ -43,8 +43,12 @@ export namespace GetEmailCampaignsResponse { winnerCriteria?: string | undefined; /** The duration of the test in hours at the end of which the winning version will be sent. Only available if `abTesting` flag of the campaign is `true` */ winnerDelay?: number | undefined; + /** URL of the attachment file associated with the campaign. Empty string if no attachment is present. */ + attachmentUrl?: string | undefined; /** Creation UTC date-time of the campaign (YYYY-MM-DDTHH:mm:ss.SSSZ) */ createdAt: string; + /** Expiration date configuration for the email campaign, if set. Contains the duration and unit of the email expiry. */ + emailExpirationDate?: Item.EmailExpirationDate | undefined; /** Footer of the campaign */ footer: string; /** Header of the campaign */ @@ -76,12 +80,13 @@ export namespace GetEmailCampaignsResponse { testSent: boolean; /** Customisation of the "to" field of the campaign */ toField?: string | undefined; - /** utm parameter associated with campaign */ + /** The utm_campaign value associated with the campaign. Only present if a UTM campaign value was set. */ utmCampaignValue?: string | undefined; - /** utm id active */ - utmIDActive?: boolean | undefined; + /** The campaign ID used as utm_id parameter. Only present if UTM campaign tracking with ID is enabled. */ + utmID?: number | undefined; + /** The utm_medium value. Set to "EMAIL" when UTM campaign tracking is enabled. */ utmMedium?: string | undefined; - /** source of utm */ + /** The utm_source value. Set to "Brevo" when UTM campaign tracking is enabled. */ utmSource?: string | undefined; recipients: Brevo.GetCampaignRecipients; statistics: Brevo.GetExtendedCampaignStats; @@ -108,6 +113,26 @@ export namespace GetEmailCampaignsResponse { } as const; export type Type = (typeof Type)[keyof typeof Type]; + /** + * Expiration date configuration for the email campaign, if set. Contains the duration and unit of the email expiry. + */ + export interface EmailExpirationDate { + /** Duration of the email expiry */ + duration?: number | undefined; + /** Unit of the duration */ + unit?: EmailExpirationDate.Unit | undefined; + } + + export namespace EmailExpirationDate { + /** Unit of the duration */ + export const Unit = { + Days: "days", + Weeks: "weeks", + Months: "months", + } as const; + export type Unit = (typeof Unit)[keyof typeof Unit]; + } + export interface Sender { /** Sender email of the campaign */ email?: string | undefined; diff --git a/src/api/resources/event/client/Client.ts b/src/api/resources/event/client/Client.ts index 0025fc4..7bc7d40 100644 --- a/src/api/resources/event/client/Client.ts +++ b/src/api/resources/event/client/Client.ts @@ -83,7 +83,11 @@ export class EventClient { ), method: "GET", headers: _headers, - queryParameters: { ..._queryParams, ...requestOptions?.queryParams }, + queryString: core.url + .queryBuilder() + .addMany(_queryParams) + .mergeAdditional(requestOptions?.queryParams) + .build(), timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, abortSignal: requestOptions?.abortSignal, @@ -156,7 +160,7 @@ export class EventClient { method: "POST", headers: _headers, contentType: "application/json", - queryParameters: requestOptions?.queryParams, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), requestType: "json", body: request, timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, @@ -190,27 +194,29 @@ export class EventClient { /** * Create multiple events to track contacts' interactions in a single request. * - * @param {Brevo.CreateBatchEventsRequestItem[]} request + * @param {Brevo.CreateBatchEventsRequest} request * @param {EventClient.RequestOptions} requestOptions - Request-specific configuration. * * @throws {@link Brevo.BadRequestError} * @throws {@link Brevo.UnauthorizedError} * * @example - * await client.event.createBatchEvents([{ - * event_name: "order_created", - * identifiers: {} - * }]) + * await client.event.createBatchEvents({ + * events: [{ + * event_name: "order_created", + * identifiers: {} + * }] + * }) */ public createBatchEvents( - request: Brevo.CreateBatchEventsRequestItem[], + request: Brevo.CreateBatchEventsRequest, requestOptions?: EventClient.RequestOptions, ): core.HttpResponsePromise { return core.HttpResponsePromise.fromPromise(this.__createBatchEvents(request, requestOptions)); } private async __createBatchEvents( - request: Brevo.CreateBatchEventsRequestItem[], + request: Brevo.CreateBatchEventsRequest, requestOptions?: EventClient.RequestOptions, ): Promise> { const _authRequest: core.AuthRequest = await this._options.authProvider.getAuthRequest(); @@ -229,7 +235,7 @@ export class EventClient { method: "POST", headers: _headers, contentType: "application/json", - queryParameters: requestOptions?.queryParams, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), requestType: "json", body: request, timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, diff --git a/src/api/resources/event/client/requests/CreateBatchEventsRequest.ts b/src/api/resources/event/client/requests/CreateBatchEventsRequest.ts new file mode 100644 index 0000000..93b8458 --- /dev/null +++ b/src/api/resources/event/client/requests/CreateBatchEventsRequest.ts @@ -0,0 +1,85 @@ +// This file was auto-generated by Fern from our API Definition. + +/** + * @example + * { + * events: [{ + * event_name: "order_created", + * identifiers: {} + * }] + * } + */ +export interface CreateBatchEventsRequest { + events: CreateBatchEventsRequest.Events.Item[]; +} + +export namespace CreateBatchEventsRequest { + export type Events = Events.Item[]; + + export namespace Events { + export interface Item { + /** Properties defining the state of the contact associated to this event. Useful to update contact attributes defined in your contacts database while passing the event. For example: **"FIRSTNAME": "Jane" , "AGE": 37** */ + contact_properties?: Record | undefined; + /** Timestamp of when the event occurred (e.g. "2024-01-24T17:39:57+01:00"). If no value is passed, the timestamp of the event creation is used. */ + event_date?: string | undefined; + /** The name of the event that occurred. This is how you will find your event in Brevo. Limited to 255 characters, alphanumerical characters and - _ only. */ + event_name: string; + /** Properties of the event. Top level properties and nested properties can be used to better segment contacts and personalise workflow conditions. The following field type are supported: string, number, boolean (true/false), date (Timestamp e.g. "2024-01-24T17:39:57+01:00"). Keys are limited to 255 characters, alphanumerical characters and - _ only. Size is limited to 50Kb. */ + event_properties?: Record | undefined; + /** Identifies the contact associated with the event. At least one identifier is required. */ + identifiers: Item.Identifiers; + /** Identifiers of the object record associated with this event. Ignored if the object type or identifier for this record does not exist on the account. */ + object?: Item.Object_ | undefined; + } + + export namespace Item { + export namespace ContactProperties { + export type Value = string | number; + } + + export namespace EventProperties { + export type Value = string | number | Record | unknown[]; + } + + /** + * Identifies the contact associated with the event. At least one identifier is required. + */ + export interface Identifiers { + /** Internal unique contact ID. When present, this takes priority over all other identifiers for event attribution and contact resolution. */ + contact_id?: number | undefined; + /** Email Id associated with the event */ + email_id?: string | undefined; + /** ext_id associated with the event */ + ext_id?: string | undefined; + /** landline_number associated with the event */ + landline_number_id?: string | undefined; + /** SMS associated with the event */ + phone_id?: string | undefined; + /** whatsapp associated with the event */ + whatsapp_id?: string | undefined; + } + + /** + * Identifiers of the object record associated with this event. Ignored if the object type or identifier for this record does not exist on the account. + */ + export interface Object_ { + /** Identifiers for the object. */ + identifiers?: Object_.Identifiers | undefined; + /** Type of object (e.g., subscription, vehicle, etc.) */ + type?: string | undefined; + } + + export namespace Object_ { + /** + * Identifiers for the object. + */ + export interface Identifiers { + /** External object ID */ + ext_id?: string | undefined; + /** Internal object ID */ + id?: string | undefined; + } + } + } + } +} diff --git a/src/api/resources/event/client/requests/CreateEventRequest.ts b/src/api/resources/event/client/requests/CreateEventRequest.ts index 5729e3e..52ffeac 100644 --- a/src/api/resources/event/client/requests/CreateEventRequest.ts +++ b/src/api/resources/event/client/requests/CreateEventRequest.ts @@ -10,11 +10,11 @@ export interface CreateEventRequest { /** Properties defining the state of the contact associated to this event. Useful to update contact attributes defined in your contacts database while passing the event. For example: **"FIRSTNAME": "Jane" , "AGE": 37** */ contact_properties?: Record; - /** Timestamp of when the event occurred (e.g. "2024-01-24T17:39:57+01:00"). If no value is passed, the timestamp of the event creation is used. */ + /** ISO 8601 timestamp of when the event occurred (e.g. "2024-01-24T17:39:57+01:00"). If no value is passed, the timestamp of the event creation is used. */ event_date?: string; - /** The name of the event that occurred. This is how you will find your event in Brevo. Limited to 255 characters, alphanumerical characters and - _ only. */ + /** The name of the event that occurred. This is how you will find your event in Brevo. Limited to 255 characters; only alphanumeric characters, hyphens (-), and underscores (_) are allowed. */ event_name: string; - /** Properties of the event. Top level properties and nested properties can be used to better segment contacts and personalise workflow conditions. The following field type are supported: string, number, boolean (true/false), date (Timestamp e.g. "2024-01-24T17:39:57+01:00"). Keys are limited to 255 characters, alphanumerical characters and - _ only. Size is limited to 50Kb. */ + /** Properties of the event. Top level properties and nested properties can be used to better segment contacts and personalise workflow conditions. The following field types are supported: string, number, boolean (true/false), date (Timestamp e.g. "2024-01-24T17:39:57+01:00"). Keys are limited to 255 characters, alphanumerical characters and - _ only. Size is limited to 50KB. */ event_properties?: Record; /** Identifies the contact associated with the event. At least one identifier is required. */ identifiers: CreateEventRequest.Identifiers; diff --git a/src/api/resources/event/client/requests/index.ts b/src/api/resources/event/client/requests/index.ts index 471011e..04cb32a 100644 --- a/src/api/resources/event/client/requests/index.ts +++ b/src/api/resources/event/client/requests/index.ts @@ -1,2 +1,3 @@ +export type { CreateBatchEventsRequest } from "./CreateBatchEventsRequest.js"; export type { CreateEventRequest } from "./CreateEventRequest.js"; export type { GetEventsRequest } from "./GetEventsRequest.js"; diff --git a/src/api/resources/event/index.ts b/src/api/resources/event/index.ts index d9adb1a..914b8c3 100644 --- a/src/api/resources/event/index.ts +++ b/src/api/resources/event/index.ts @@ -1,2 +1 @@ export * from "./client/index.js"; -export * from "./types/index.js"; diff --git a/src/api/resources/event/types/CreateBatchEventsRequestItem.ts b/src/api/resources/event/types/CreateBatchEventsRequestItem.ts deleted file mode 100644 index 88da2d1..0000000 --- a/src/api/resources/event/types/CreateBatchEventsRequestItem.ts +++ /dev/null @@ -1,66 +0,0 @@ -// This file was auto-generated by Fern from our API Definition. - -export interface CreateBatchEventsRequestItem { - /** Properties defining the state of the contact associated to this event. Useful to update contact attributes defined in your contacts database while passing the event. For example: **"FIRSTNAME": "Jane" , "AGE": 37** */ - contact_properties?: Record | undefined; - /** Timestamp of when the event occurred (e.g. "2024-01-24T17:39:57+01:00"). If no value is passed, the timestamp of the event creation is used. */ - event_date?: string | undefined; - /** The name of the event that occurred. This is how you will find your event in Brevo. Limited to 255 characters, alphanumerical characters and - _ only. */ - event_name: string; - /** Properties of the event. Top level properties and nested properties can be used to better segment contacts and personalise workflow conditions. The following field type are supported: string, number, boolean (true/false), date (Timestamp e.g. "2024-01-24T17:39:57+01:00"). Keys are limited to 255 characters, alphanumerical characters and - _ only. Size is limited to 50Kb. */ - event_properties?: Record | undefined; - /** Identifies the contact associated with the event. At least one identifier is required. */ - identifiers: CreateBatchEventsRequestItem.Identifiers; - /** Identifiers of the object record associated with this event. Ignored if the object type or identifier for this record does not exist on the account. */ - object?: CreateBatchEventsRequestItem.Object_ | undefined; -} - -export namespace CreateBatchEventsRequestItem { - export namespace ContactProperties { - export type Value = string | number | boolean; - } - - export namespace EventProperties { - export type Value = string | number | boolean | Record | unknown[]; - } - - /** - * Identifies the contact associated with the event. At least one identifier is required. - */ - export interface Identifiers { - /** Internal unique contact ID. When present, this takes priority over all other identifiers for event attribution and contact resolution. */ - contact_id?: number | undefined; - /** Email Id associated with the event */ - email_id?: string | undefined; - /** ext_id associated with the event */ - ext_id?: string | undefined; - /** landline_number associated with the event */ - landline_number_id?: string | undefined; - /** SMS associated with the event */ - phone_id?: string | undefined; - /** whatsapp associated with the event */ - whatsapp_id?: string | undefined; - } - - /** - * Identifiers of the object record associated with this event. Ignored if the object type or identifier for this record does not exist on the account. - */ - export interface Object_ { - /** Identifiers for the object. */ - identifiers?: Object_.Identifiers | undefined; - /** Type of object (e.g., subscription, vehicle, etc.) */ - type?: string | undefined; - } - - export namespace Object_ { - /** - * Identifiers for the object. - */ - export interface Identifiers { - /** External object ID */ - ext_id?: string | undefined; - /** Internal object ID */ - id?: string | undefined; - } - } -} diff --git a/src/api/resources/event/types/index.ts b/src/api/resources/event/types/index.ts deleted file mode 100644 index b2fea88..0000000 --- a/src/api/resources/event/types/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from "./CreateBatchEventsRequestItem.js"; diff --git a/src/api/resources/externalFeeds/client/Client.ts b/src/api/resources/externalFeeds/client/Client.ts index ad42ffd..04bee5f 100644 --- a/src/api/resources/externalFeeds/client/Client.ts +++ b/src/api/resources/externalFeeds/client/Client.ts @@ -98,7 +98,11 @@ export class ExternalFeedsClient { ), method: "GET", headers: _headers, - queryParameters: { ..._queryParams, ...requestOptions?.queryParams }, + queryString: core.url + .queryBuilder() + .addMany(_queryParams) + .mergeAdditional(requestOptions?.queryParams) + .build(), timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, abortSignal: requestOptions?.abortSignal, @@ -209,7 +213,7 @@ export class ExternalFeedsClient { method: "POST", headers: _headers, contentType: "application/json", - queryParameters: requestOptions?.queryParams, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), requestType: "json", body: request, timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, @@ -300,7 +304,7 @@ export class ExternalFeedsClient { ), method: "GET", headers: _headers, - queryParameters: requestOptions?.queryParams, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, abortSignal: requestOptions?.abortSignal, @@ -434,7 +438,7 @@ export class ExternalFeedsClient { method: "PUT", headers: _headers, contentType: "application/json", - queryParameters: requestOptions?.queryParams, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), requestType: "json", body: _body, timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, @@ -522,7 +526,7 @@ export class ExternalFeedsClient { ), method: "DELETE", headers: _headers, - queryParameters: requestOptions?.queryParams, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, abortSignal: requestOptions?.abortSignal, diff --git a/src/api/resources/externalFeeds/types/GetAllExternalFeedsResponse.ts b/src/api/resources/externalFeeds/types/GetAllExternalFeedsResponse.ts index 84a4a05..0751667 100644 --- a/src/api/resources/externalFeeds/types/GetAllExternalFeedsResponse.ts +++ b/src/api/resources/externalFeeds/types/GetAllExternalFeedsResponse.ts @@ -16,24 +16,20 @@ export namespace GetAllExternalFeedsResponse { id: string; /** Name of the feed */ name: string; - /** URL-friendly alias for the feed */ - alias: string; /** URL of the external data source */ url: string; /** Authentication type for accessing the feed */ authType: Item.AuthType; - /** Username for basic authentication */ + /** Username for basic authentication. Only returned when authType is 'basic'. Excluded when authType is 'token'. */ username?: string | undefined; - /** Password for basic authentication */ + /** Password for basic authentication. Only returned when authType is 'basic'. Excluded when authType is 'token'. */ password?: string | undefined; - /** Token for token-based authentication */ + /** Token for token-based authentication. Only returned when authType is 'token'. Excluded when authType is 'basic' or 'noAuth'. */ token?: string | undefined; /** Maximum number of retry attempts for failed requests */ maxRetries: number; /** Whether to cache the feed response */ cache: boolean; - /** Whether this is an internal Brevo system feed */ - isInternal: boolean; /** Custom HTTP headers for the feed request */ headers?: (Item.Headers.Item[] | null) | undefined; /** Feed creation timestamp */ diff --git a/src/api/resources/externalFeeds/types/GetExternalFeedByUuidResponse.ts b/src/api/resources/externalFeeds/types/GetExternalFeedByUuidResponse.ts index f685018..b2a5256 100644 --- a/src/api/resources/externalFeeds/types/GetExternalFeedByUuidResponse.ts +++ b/src/api/resources/externalFeeds/types/GetExternalFeedByUuidResponse.ts @@ -9,18 +9,12 @@ export interface GetExternalFeedByUuidResponse { url: string; /** Authentication type for accessing the feed */ authType: GetExternalFeedByUuidResponse.AuthType; - /** Username for basic authentication (null if not using basic auth) */ + /** Username for basic authentication. Only returned when authType is 'basic'. Excluded from response when authType is 'token'. */ username?: (string | null) | undefined; - /** Password for basic authentication (null if not using basic auth) */ + /** Password for basic authentication. Only returned when authType is 'basic'. Excluded from response when authType is 'token'. */ password?: (string | null) | undefined; - /** Token for token-based authentication (null if not using token auth) */ + /** Token for token-based authentication. Only returned when authType is 'token'. Excluded from response when authType is 'basic' or 'noAuth'. */ token?: (string | null) | undefined; - /** Whether personalization is enabled for this feed */ - personalization: boolean; - /** Default attribute name for personalization fallback (empty string if not set) */ - defaultAttr: string; - /** Default contact email for personalization fallback (empty string if not set) */ - defaultContact: string; /** Custom HTTP headers for the feed request */ headers?: (GetExternalFeedByUuidResponse.Headers.Item[] | null) | undefined; /** Maximum number of retry attempts for failed requests */ diff --git a/src/api/resources/files/client/Client.ts b/src/api/resources/files/client/Client.ts index 2eed388..c710e9d 100644 --- a/src/api/resources/files/client/Client.ts +++ b/src/api/resources/files/client/Client.ts @@ -23,6 +23,8 @@ export class FilesClient { } /** + * Retrieve a paginated list of CRM files with optional filtering by entity type, entity IDs, and date range. Results are sorted by creation date in descending order by default, with a default limit of 50 files per page. + * * @param {Brevo.GetCrmFilesRequest} request * @param {FilesClient.RequestOptions} requestOptions - Request-specific configuration. * @@ -67,7 +69,11 @@ export class FilesClient { ), method: "GET", headers: _headers, - queryParameters: { ..._queryParams, ...requestOptions?.queryParams }, + queryString: core.url + .queryBuilder() + .addMany(_queryParams) + .mergeAdditional(requestOptions?.queryParams) + .build(), timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, abortSignal: requestOptions?.abortSignal, @@ -95,6 +101,8 @@ export class FilesClient { } /** + * Upload a file and associate it with a contact, company, or deal. The file must be sent as multipart form data with a maximum size of 10 MB. You can optionally link the file to a specific entity by providing the corresponding entity ID. + * * @param {Brevo.PostCrmFilesRequest} request * @param {FilesClient.RequestOptions} requestOptions - Request-specific configuration. * @@ -148,7 +156,7 @@ export class FilesClient { ), method: "POST", headers: _headers, - queryParameters: requestOptions?.queryParams, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), requestType: "file", duplex: _maybeEncodedRequest.duplex, body: _maybeEncodedRequest.body, @@ -179,6 +187,8 @@ export class FilesClient { } /** + * Get a temporary download URL for a CRM file by its identifier. The returned URL is valid for 5 minutes only and provides direct access to the file content. + * * @param {Brevo.GetCrmFilesIdRequest} request * @param {FilesClient.RequestOptions} requestOptions - Request-specific configuration. * @@ -217,7 +227,7 @@ export class FilesClient { ), method: "GET", headers: _headers, - queryParameters: requestOptions?.queryParams, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, abortSignal: requestOptions?.abortSignal, @@ -247,6 +257,8 @@ export class FilesClient { } /** + * Permanently delete a CRM file by its identifier. This removes the file from storage and unlinks it from any associated contacts, companies, or deals. + * * @param {Brevo.DeleteCrmFilesIdRequest} request * @param {FilesClient.RequestOptions} requestOptions - Request-specific configuration. * @@ -285,7 +297,7 @@ export class FilesClient { ), method: "DELETE", headers: _headers, - queryParameters: requestOptions?.queryParams, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, abortSignal: requestOptions?.abortSignal, @@ -315,6 +327,8 @@ export class FilesClient { } /** + * Retrieve the metadata and details of a specific CRM file by its identifier. This returns information such as the file name, size, type, creation date, and associated entities, but does not include the file content itself. + * * @param {Brevo.GetCrmFilesIdDataRequest} request * @param {FilesClient.RequestOptions} requestOptions - Request-specific configuration. * @@ -353,7 +367,7 @@ export class FilesClient { ), method: "GET", headers: _headers, - queryParameters: requestOptions?.queryParams, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, abortSignal: requestOptions?.abortSignal, diff --git a/src/api/resources/inboundParsing/client/Client.ts b/src/api/resources/inboundParsing/client/Client.ts index 1691671..ba8846c 100644 --- a/src/api/resources/inboundParsing/client/Client.ts +++ b/src/api/resources/inboundParsing/client/Client.ts @@ -23,7 +23,7 @@ export class InboundParsingClient { } /** - * This endpoint will show the list of all the events for the received emails. + * This endpoint will show the list of all the events for the received emails. When no date range is provided, the last 30 days of events are returned by default. * * @param {Brevo.GetInboundEmailEventsRequest} request * @param {InboundParsingClient.RequestOptions} requestOptions - Request-specific configuration. @@ -68,7 +68,11 @@ export class InboundParsingClient { ), method: "GET", headers: _headers, - queryParameters: { ..._queryParams, ...requestOptions?.queryParams }, + queryString: core.url + .queryBuilder() + .addMany(_queryParams) + .mergeAdditional(requestOptions?.queryParams) + .build(), timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, abortSignal: requestOptions?.abortSignal, @@ -102,6 +106,7 @@ export class InboundParsingClient { * @param {InboundParsingClient.RequestOptions} requestOptions - Request-specific configuration. * * @throws {@link Brevo.BadRequestError} + * @throws {@link Brevo.NotFoundError} * * @example * await client.inboundParsing.getInboundEmailEventsByUuid({ @@ -135,7 +140,7 @@ export class InboundParsingClient { ), method: "GET", headers: _headers, - queryParameters: requestOptions?.queryParams, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, abortSignal: requestOptions?.abortSignal, @@ -153,6 +158,8 @@ export class InboundParsingClient { switch (_response.error.statusCode) { case 400: throw new Brevo.BadRequestError(_response.error.body as unknown, _response.rawResponse); + case 404: + throw new Brevo.NotFoundError(_response.error.body as unknown, _response.rawResponse); default: throw new errors.BrevoError({ statusCode: _response.error.statusCode, @@ -198,7 +205,7 @@ export class InboundParsingClient { ), method: "GET", headers: _headers, - queryParameters: requestOptions?.queryParams, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), responseType: "binary-response", timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, diff --git a/src/api/resources/inboundParsing/client/requests/GetInboundEmailEventsRequest.ts b/src/api/resources/inboundParsing/client/requests/GetInboundEmailEventsRequest.ts index 39f2441..bf07b77 100644 --- a/src/api/resources/inboundParsing/client/requests/GetInboundEmailEventsRequest.ts +++ b/src/api/resources/inboundParsing/client/requests/GetInboundEmailEventsRequest.ts @@ -9,9 +9,9 @@ import type * as Brevo from "../../../../index.js"; export interface GetInboundEmailEventsRequest { /** Email address of the sender. */ sender?: string; - /** Mandatory if endDate is used. Starting date (YYYY-MM-DD or YYYY-MM-DDTHH:mm:ss.SSSZ) from which you want to fetch the list. Maximum time period that can be selected is one month. */ + /** Mandatory if endDate is used. Starting date (YYYY-MM-DD or YYYY-MM-DDTHH:mm:ss.SSSZ) from which you want to fetch the list. Maximum time period that can be selected is 30 days. Must not be in the future. */ startDate?: string; - /** Mandatory if startDate is used. Ending date (YYYY-MM-DD or YYYY-MM-DDTHH:mm:ss.SSSZ) till which you want to fetch the list. Maximum time period that can be selected is one month. */ + /** Mandatory if startDate is used. Ending date (YYYY-MM-DD or YYYY-MM-DDTHH:mm:ss.SSSZ) till which you want to fetch the list. Maximum time period that can be selected is 30 days. Must not be in the future. */ endDate?: string; /** Number of documents returned per page */ limit?: number; diff --git a/src/api/resources/inboundParsing/types/GetInboundEmailEventsByUuidResponse.ts b/src/api/resources/inboundParsing/types/GetInboundEmailEventsByUuidResponse.ts index 29c4ef8..0368a97 100644 --- a/src/api/resources/inboundParsing/types/GetInboundEmailEventsByUuidResponse.ts +++ b/src/api/resources/inboundParsing/types/GetInboundEmailEventsByUuidResponse.ts @@ -3,9 +3,9 @@ export interface GetInboundEmailEventsByUuidResponse { /** List of attachments of the email. This will be present only after the processing is done. */ attachments?: GetInboundEmailEventsByUuidResponse.Attachments.Item[] | undefined; - /** Date when email was delivered successfully to client_dev’s webhook */ + /** Date when email was delivered successfully to the client’s webhook */ deliveredAt?: (string | null) | undefined; - /** List of events/logs that describe the lifecycle of the email on SIB platform */ + /** List of events/logs that describe the lifecycle of the email on the Brevo platform */ logs?: GetInboundEmailEventsByUuidResponse.Logs.Item[] | undefined; /** Value of the Message-ID header. This will be present only after the processing is done. */ messageId?: string | undefined; diff --git a/src/api/resources/index.ts b/src/api/resources/index.ts index 7252a47..b4c41cb 100644 --- a/src/api/resources/index.ts +++ b/src/api/resources/index.ts @@ -33,7 +33,6 @@ export * as emailCampaigns from "./emailCampaigns/index.js"; export * from "./emailCampaigns/types/index.js"; export * from "./event/client/requests/index.js"; export * as event from "./event/index.js"; -export * from "./event/types/index.js"; export * from "./externalFeeds/client/requests/index.js"; export * as externalFeeds from "./externalFeeds/index.js"; export * from "./externalFeeds/types/index.js"; diff --git a/src/api/resources/masterAccount/client/Client.ts b/src/api/resources/masterAccount/client/Client.ts index 790e33c..3b81f6d 100644 --- a/src/api/resources/masterAccount/client/Client.ts +++ b/src/api/resources/masterAccount/client/Client.ts @@ -62,7 +62,7 @@ export class MasterAccountClient { method: "POST", headers: _headers, contentType: "application/json", - queryParameters: requestOptions?.queryParams, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), requestType: "json", body: request, timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, @@ -133,7 +133,7 @@ export class MasterAccountClient { method: "PUT", headers: _headers, contentType: "application/json", - queryParameters: requestOptions?.queryParams, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), requestType: "json", body: _body, timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, @@ -174,6 +174,8 @@ export class MasterAccountClient { * @param {Brevo.GetCorporateGroupIdRequest} request * @param {MasterAccountClient.RequestOptions} requestOptions - Request-specific configuration. * + * @throws {@link Brevo.BadRequestError} + * * @example * await client.masterAccount.getAGroupDetails({ * id: "id" @@ -206,7 +208,7 @@ export class MasterAccountClient { ), method: "GET", headers: _headers, - queryParameters: requestOptions?.queryParams, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, abortSignal: requestOptions?.abortSignal, @@ -218,11 +220,16 @@ export class MasterAccountClient { } if (_response.error.reason === "status-code") { - throw new errors.BrevoError({ - statusCode: _response.error.statusCode, - body: _response.error.body, - rawResponse: _response.rawResponse, - }); + switch (_response.error.statusCode) { + case 400: + throw new Brevo.BadRequestError(_response.error.body as unknown, _response.rawResponse); + default: + throw new errors.BrevoError({ + statusCode: _response.error.statusCode, + body: _response.error.body, + rawResponse: _response.rawResponse, + }); + } } return handleNonStatusCodeError(_response.error, _response.rawResponse, "GET", "/corporate/group/{id}"); @@ -269,7 +276,7 @@ export class MasterAccountClient { method: "PUT", headers: _headers, contentType: "application/json", - queryParameters: requestOptions?.queryParams, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), requestType: "json", body: _body, timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, @@ -341,7 +348,7 @@ export class MasterAccountClient { ), method: "DELETE", headers: _headers, - queryParameters: requestOptions?.queryParams, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, abortSignal: requestOptions?.abortSignal, @@ -373,6 +380,8 @@ export class MasterAccountClient { * * @param {MasterAccountClient.RequestOptions} requestOptions - Request-specific configuration. * + * @throws {@link Brevo.BadRequestError} + * * @example * await client.masterAccount.getSubAccountGroups() */ @@ -400,7 +409,7 @@ export class MasterAccountClient { ), method: "GET", headers: _headers, - queryParameters: requestOptions?.queryParams, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, abortSignal: requestOptions?.abortSignal, @@ -415,11 +424,16 @@ export class MasterAccountClient { } if (_response.error.reason === "status-code") { - throw new errors.BrevoError({ - statusCode: _response.error.statusCode, - body: _response.error.body, - rawResponse: _response.rawResponse, - }); + switch (_response.error.statusCode) { + case 400: + throw new Brevo.BadRequestError(_response.error.body as unknown, _response.rawResponse); + default: + throw new errors.BrevoError({ + statusCode: _response.error.statusCode, + body: _response.error.body, + rawResponse: _response.rawResponse, + }); + } } return handleNonStatusCodeError(_response.error, _response.rawResponse, "GET", "/corporate/groups"); @@ -433,6 +447,8 @@ export class MasterAccountClient { * @param {Brevo.GetCorporateInvitedUsersListRequest} request * @param {MasterAccountClient.RequestOptions} requestOptions - Request-specific configuration. * + * @throws {@link Brevo.BadRequestError} + * * @example * await client.masterAccount.getCorporateInvitedUsersList() */ @@ -468,7 +484,11 @@ export class MasterAccountClient { ), method: "GET", headers: _headers, - queryParameters: { ..._queryParams, ...requestOptions?.queryParams }, + queryString: core.url + .queryBuilder() + .addMany(_queryParams) + .mergeAdditional(requestOptions?.queryParams) + .build(), timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, abortSignal: requestOptions?.abortSignal, @@ -483,11 +503,16 @@ export class MasterAccountClient { } if (_response.error.reason === "status-code") { - throw new errors.BrevoError({ - statusCode: _response.error.statusCode, - body: _response.error.body, - rawResponse: _response.rawResponse, - }); + switch (_response.error.statusCode) { + case 400: + throw new Brevo.BadRequestError(_response.error.body as unknown, _response.rawResponse); + default: + throw new errors.BrevoError({ + statusCode: _response.error.statusCode, + body: _response.error.body, + rawResponse: _response.rawResponse, + }); + } } return handleNonStatusCodeError(_response.error, _response.rawResponse, "GET", "/corporate/invited/users"); @@ -499,6 +524,8 @@ export class MasterAccountClient { * * @param {MasterAccountClient.RequestOptions} requestOptions - Request-specific configuration. * + * @throws {@link Brevo.BadRequestError} + * * @example * await client.masterAccount.listOfAllIPs() */ @@ -526,7 +553,7 @@ export class MasterAccountClient { ), method: "GET", headers: _headers, - queryParameters: requestOptions?.queryParams, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, abortSignal: requestOptions?.abortSignal, @@ -538,11 +565,16 @@ export class MasterAccountClient { } if (_response.error.reason === "status-code") { - throw new errors.BrevoError({ - statusCode: _response.error.statusCode, - body: _response.error.body, - rawResponse: _response.rawResponse, - }); + switch (_response.error.statusCode) { + case 400: + throw new Brevo.BadRequestError(_response.error.body as unknown, _response.rawResponse); + default: + throw new errors.BrevoError({ + statusCode: _response.error.statusCode, + body: _response.error.body, + rawResponse: _response.rawResponse, + }); + } } return handleNonStatusCodeError(_response.error, _response.rawResponse, "GET", "/corporate/ip"); @@ -582,7 +614,7 @@ export class MasterAccountClient { ), method: "GET", headers: _headers, - queryParameters: requestOptions?.queryParams, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, abortSignal: requestOptions?.abortSignal, @@ -658,7 +690,7 @@ export class MasterAccountClient { method: "POST", headers: _headers, contentType: "application/json", - queryParameters: requestOptions?.queryParams, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), requestType: "json", body: request, timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, @@ -737,7 +769,11 @@ export class MasterAccountClient { ), method: "GET", headers: _headers, - queryParameters: { ..._queryParams, ...requestOptions?.queryParams }, + queryString: core.url + .queryBuilder() + .addMany(_queryParams) + .mergeAdditional(requestOptions?.queryParams) + .build(), timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, abortSignal: requestOptions?.abortSignal, @@ -810,7 +846,7 @@ export class MasterAccountClient { method: "POST", headers: _headers, contentType: "application/json", - queryParameters: requestOptions?.queryParams, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), requestType: "json", body: request, timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, @@ -883,7 +919,7 @@ export class MasterAccountClient { method: "POST", headers: _headers, contentType: "application/json", - queryParameters: requestOptions?.queryParams, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), requestType: "json", body: request, timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, @@ -958,7 +994,7 @@ export class MasterAccountClient { method: "PUT", headers: _headers, contentType: "application/json", - queryParameters: requestOptions?.queryParams, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), requestType: "json", body: request, timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, @@ -1033,7 +1069,7 @@ export class MasterAccountClient { method: "POST", headers: _headers, contentType: "application/json", - queryParameters: requestOptions?.queryParams, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), requestType: "json", body: request, timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, @@ -1109,7 +1145,7 @@ export class MasterAccountClient { method: "POST", headers: _headers, contentType: "application/json", - queryParameters: requestOptions?.queryParams, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), requestType: "json", body: request, timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, @@ -1185,7 +1221,7 @@ export class MasterAccountClient { ), method: "GET", headers: _headers, - queryParameters: requestOptions?.queryParams, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, abortSignal: requestOptions?.abortSignal, @@ -1216,6 +1252,8 @@ export class MasterAccountClient { } /** + * Permanently deletes a sub-account from the corporate master account. Once deleted, all data associated with the sub-account organization is removed and cannot be recovered, so ensure the sub-account is no longer needed before proceeding. + * * @param {Brevo.DeleteCorporateSubAccountIdRequest} request * @param {MasterAccountClient.RequestOptions} requestOptions - Request-specific configuration. * @@ -1254,7 +1292,7 @@ export class MasterAccountClient { ), method: "DELETE", headers: _headers, - queryParameters: requestOptions?.queryParams, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, abortSignal: requestOptions?.abortSignal, @@ -1333,7 +1371,7 @@ export class MasterAccountClient { method: "PUT", headers: _headers, contentType: "application/json", - queryParameters: requestOptions?.queryParams, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), requestType: "json", body: _body, timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, @@ -1427,7 +1465,7 @@ export class MasterAccountClient { method: "PUT", headers: _headers, contentType: "application/json", - queryParameters: requestOptions?.queryParams, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), requestType: "json", body: _body, timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, @@ -1519,7 +1557,7 @@ export class MasterAccountClient { method: "PUT", headers: _headers, contentType: "application/json", - queryParameters: requestOptions?.queryParams, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), requestType: "json", body: request, timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, @@ -1617,7 +1655,7 @@ export class MasterAccountClient { method: "POST", headers: _headers, contentType: "application/json", - queryParameters: requestOptions?.queryParams, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), requestType: "json", body: request, timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, @@ -1694,7 +1732,7 @@ export class MasterAccountClient { ), method: "PUT", headers: _headers, - queryParameters: requestOptions?.queryParams, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, abortSignal: requestOptions?.abortSignal, @@ -1770,7 +1808,7 @@ export class MasterAccountClient { ), method: "DELETE", headers: _headers, - queryParameters: requestOptions?.queryParams, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, abortSignal: requestOptions?.abortSignal, @@ -1842,7 +1880,7 @@ export class MasterAccountClient { ), method: "GET", headers: _headers, - queryParameters: requestOptions?.queryParams, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, abortSignal: requestOptions?.abortSignal, @@ -1948,7 +1986,7 @@ export class MasterAccountClient { method: "PUT", headers: _headers, contentType: "application/json", - queryParameters: requestOptions?.queryParams, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), requestType: "json", body: _body, timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, diff --git a/src/api/resources/notes/client/Client.ts b/src/api/resources/notes/client/Client.ts index 739efba..6ddf808 100644 --- a/src/api/resources/notes/client/Client.ts +++ b/src/api/resources/notes/client/Client.ts @@ -23,6 +23,8 @@ export class NotesClient { } /** + * Retrieve a paginated list of CRM notes with optional filtering by entity type, entity IDs, and date range. Results are sorted by creation date in descending order by default, with a default limit of 50 notes per page. + * * @param {Brevo.GetCrmNotesRequest} request * @param {NotesClient.RequestOptions} requestOptions - Request-specific configuration. * @@ -67,7 +69,11 @@ export class NotesClient { ), method: "GET", headers: _headers, - queryParameters: { ..._queryParams, ...requestOptions?.queryParams }, + queryString: core.url + .queryBuilder() + .addMany(_queryParams) + .mergeAdditional(requestOptions?.queryParams) + .build(), timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, abortSignal: requestOptions?.abortSignal, @@ -95,6 +101,8 @@ export class NotesClient { } /** + * Create a new CRM note and optionally associate it with contacts, companies, or deals. The note text content is required, and you can link the note to multiple entities simultaneously during creation. + * * @param {Brevo.NoteData} request * @param {NotesClient.RequestOptions} requestOptions - Request-specific configuration. * @@ -103,7 +111,7 @@ export class NotesClient { * * @example * await client.notes.createANote({ - * text: "In communication with client_dev for resolution of queries." + * text: "

Meeting notes: Action item - visit Brevo for details.

" * }) */ public createANote( @@ -133,7 +141,7 @@ export class NotesClient { method: "POST", headers: _headers, contentType: "application/json", - queryParameters: requestOptions?.queryParams, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), requestType: "json", body: request, timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, @@ -168,6 +176,8 @@ export class NotesClient { } /** + * Retrieve the full details of a single CRM note by its identifier. The response includes the note''s text content, creation date, author, and any associated contacts, companies, or deals. + * * @param {Brevo.GetCrmNotesIdRequest} request * @param {NotesClient.RequestOptions} requestOptions - Request-specific configuration. * @@ -206,7 +216,7 @@ export class NotesClient { ), method: "GET", headers: _headers, - queryParameters: requestOptions?.queryParams, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, abortSignal: requestOptions?.abortSignal, @@ -236,6 +246,8 @@ export class NotesClient { } /** + * Permanently delete a CRM note by its identifier. This removes the note and unlinks it from any associated contacts, companies, or deals. + * * @param {Brevo.DeleteCrmNotesIdRequest} request * @param {NotesClient.RequestOptions} requestOptions - Request-specific configuration. * @@ -274,7 +286,7 @@ export class NotesClient { ), method: "DELETE", headers: _headers, - queryParameters: requestOptions?.queryParams, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, abortSignal: requestOptions?.abortSignal, @@ -304,6 +316,8 @@ export class NotesClient { } /** + * Update an existing CRM note''s text content and its associations with contacts, companies, or deals. You can modify the note text, change the pinned status, or update the linked entities. + * * @param {Brevo.PatchCrmNotesIdRequest} request * @param {NotesClient.RequestOptions} requestOptions - Request-specific configuration. * @@ -315,7 +329,7 @@ export class NotesClient { * await client.notes.updateANote({ * id: "id", * body: { - * text: "In communication with client_dev for resolution of queries." + * text: "

Meeting notes: Action item - visit Brevo for details.

" * } * }) */ @@ -347,7 +361,7 @@ export class NotesClient { method: "PATCH", headers: _headers, contentType: "application/json", - queryParameters: requestOptions?.queryParams, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), requestType: "json", body: _body, timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, diff --git a/src/api/resources/notes/client/requests/PatchCrmNotesIdRequest.ts b/src/api/resources/notes/client/requests/PatchCrmNotesIdRequest.ts index e5ee5c9..2ba14cf 100644 --- a/src/api/resources/notes/client/requests/PatchCrmNotesIdRequest.ts +++ b/src/api/resources/notes/client/requests/PatchCrmNotesIdRequest.ts @@ -7,7 +7,7 @@ import type * as Brevo from "../../../../index.js"; * { * id: "id", * body: { - * text: "In communication with client_dev for resolution of queries." + * text: "

Meeting notes: Action item - visit Brevo for details.

" * } * } */ diff --git a/src/api/resources/notes/types/PostCrmNotesResponse.ts b/src/api/resources/notes/types/PostCrmNotesResponse.ts index 2d0e24a..b1aff47 100644 --- a/src/api/resources/notes/types/PostCrmNotesResponse.ts +++ b/src/api/resources/notes/types/PostCrmNotesResponse.ts @@ -1,7 +1,7 @@ // This file was auto-generated by Fern from our API Definition. /** - * Updated Note ID + * Created Note ID */ export interface PostCrmNotesResponse { /** Unique note Id */ diff --git a/src/api/resources/payments/client/Client.ts b/src/api/resources/payments/client/Client.ts index 90f2f7a..9ebadeb 100644 --- a/src/api/resources/payments/client/Client.ts +++ b/src/api/resources/payments/client/Client.ts @@ -23,6 +23,8 @@ export class PaymentsClient { } /** + * Create a new payment request for a Brevo contact. The request requires a reference (displayed on the payment page), a contact ID, and a cart with currency and amount in cents. You can optionally configure a custom success redirect URL and enable email notifications with reminders. Returns the payment request ID and its public payment URL. A `403` error is returned if Brevo Payments is not activated or the account is not validated. + * * @param {Brevo.CreatePaymentRequestRequest} request * @param {PaymentsClient.RequestOptions} requestOptions - Request-specific configuration. * @@ -67,7 +69,7 @@ export class PaymentsClient { method: "POST", headers: _headers, contentType: "application/json", - queryParameters: requestOptions?.queryParams, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), requestType: "json", body: request, timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, @@ -101,6 +103,8 @@ export class PaymentsClient { } /** + * Retrieve the details of a specific payment request by its ID. The response includes the reference, status (created, sent, reminderSent, or paid), cart details, notification configuration, contact ID, and the number of reminders sent. Returns a `404` error if no payment request matches the provided ID. + * * @param {Brevo.GetPaymentRequestRequest} request * @param {PaymentsClient.RequestOptions} requestOptions - Request-specific configuration. * @@ -141,7 +145,7 @@ export class PaymentsClient { ), method: "GET", headers: _headers, - queryParameters: requestOptions?.queryParams, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, abortSignal: requestOptions?.abortSignal, @@ -175,6 +179,8 @@ export class PaymentsClient { } /** + * Delete a payment request by its UUID. Once deleted, the payment request can no longer be accessed or paid. Returns a `404` error if no payment request matches the provided ID, and a `403` error if Brevo Payments is not activated or the account is not validated. + * * @param {Brevo.DeletePaymentRequestRequest} request * @param {PaymentsClient.RequestOptions} requestOptions - Request-specific configuration. * @@ -214,7 +220,7 @@ export class PaymentsClient { ), method: "DELETE", headers: _headers, - queryParameters: requestOptions?.queryParams, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, abortSignal: requestOptions?.abortSignal, diff --git a/src/api/resources/process/client/Client.ts b/src/api/resources/process/client/Client.ts index 2e24f26..6968285 100644 --- a/src/api/resources/process/client/Client.ts +++ b/src/api/resources/process/client/Client.ts @@ -33,20 +33,19 @@ export class ProcessClient { * - Identify failed or stuck processes for troubleshooting * * **Key information returned:** - * - Process details (ID, name, type, status) - * - Process creation and completion timestamps - * - Process progress and completion status - * - Error information for failed processes - * - Process result data and download links + * - Process details (ID, name, status) + * - Export download URLs for completed export processes + * - Import details with CSV report URLs for completed import processes + * - Total count of processes for pagination * * **Important considerations:** * - Background processes handle long-running operations like imports and exports - * - Process status indicates current state (queued, processing, completed, failed, cancelled) + * - Process status indicates current state (queued, processing, completed) * - Export processes provide download URLs when completed - * - Failed processes include error messages for troubleshooting + * - Import processes provide CSV report URLs with details about problematic records * - Use pagination for accounts with many historical processes * - Sort options available for creation order (ascending or descending) - * - Different process types handle specific operations (imports, exports, calculations) + * - Default limit is 10 results per page, maximum is 50 * * @param {Brevo.GetProcessesRequest} request * @param {ProcessClient.RequestOptions} requestOptions - Request-specific configuration. @@ -88,7 +87,11 @@ export class ProcessClient { ), method: "GET", headers: _headers, - queryParameters: { ..._queryParams, ...requestOptions?.queryParams }, + queryString: core.url + .queryBuilder() + .addMany(_queryParams) + .mergeAdditional(requestOptions?.queryParams) + .build(), timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, abortSignal: requestOptions?.abortSignal, @@ -126,18 +129,14 @@ export class ProcessClient { * - Track process execution times * * **Key information returned:** - * - Complete process details and status - * - Import/export statistics and results - * - Error information for troubleshooting - * - Download URLs for export processes - * - Process timing and performance data + * - Complete process details (ID, name, status) + * - Download URLs for completed export processes + * - Import details with CSV report URLs for completed import processes * * **Important considerations:** - * - Process ID must exist in your account - * - Completed processes provide detailed statistics and results - * - Export processes include download URLs when successful - * - Failed processes contain error messages for debugging - * - Timing information helps with performance analysis + * - Process ID must exist in your account and not be deleted + * - Completed export processes include download URLs + * - Completed import processes include CSV report URLs with details about problematic records * - Different process types return different result structures * * @param {Brevo.GetProcessRequest} request @@ -178,7 +177,7 @@ export class ProcessClient { ), method: "GET", headers: _headers, - queryParameters: requestOptions?.queryParams, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, abortSignal: requestOptions?.abortSignal, diff --git a/src/api/resources/process/types/GetProcessResponse.ts b/src/api/resources/process/types/GetProcessResponse.ts index 8ce6ad6..55898a8 100644 --- a/src/api/resources/process/types/GetProcessResponse.ts +++ b/src/api/resources/process/types/GetProcessResponse.ts @@ -7,16 +7,10 @@ export interface GetProcessResponse { name: GetProcessResponse.Name; /** Current status of the process */ status: GetProcessResponse.Status; - /** Additional process information (for completed processes) */ - info?: (GetProcessResponse.Info | null) | undefined; - /** Download URL for completed export processes */ - export_url?: (string | null) | undefined; - /** Error message for failed processes */ - error?: (string | null) | undefined; - /** Process creation timestamp */ - created_at?: (string | null) | undefined; - /** Process completion timestamp */ - completed_at?: (string | null) | undefined; + /** Additional process information, only returned for completed IMPORTUSER processes. Contains URLs to CSV files with details about problematic records. */ + info?: GetProcessResponse.Info | undefined; + /** Download URL for completed export processes (returned for SEARCH_EXPORT_USERS, SEARCH_EXPORT_USERS_API, CAMPAIGN_USER_DETAILS, and EXPORT_WEBHOOK process types) */ + export_url?: string | undefined; } export namespace GetProcessResponse { @@ -43,44 +37,32 @@ export namespace GetProcessResponse { export type Status = (typeof Status)[keyof typeof Status]; /** - * Additional process information (for completed processes) + * Additional process information, only returned for completed IMPORTUSER processes. Contains URLs to CSV files with details about problematic records. */ export interface Info { - /** Import process details */ + /** Import process details with URLs to CSV reports */ import?: Info.Import | undefined; - /** Export process details */ - export?: Info.Export | undefined; } export namespace Info { /** - * Import process details + * Import process details with URLs to CSV reports */ export interface Import { - /** Number of invalid email addresses */ - invalid_emails?: (number | null) | undefined; - /** Number of duplicate contact IDs */ - duplicate_contact_id?: (number | null) | undefined; - /** Number of duplicate external IDs */ - duplicate_ext_id?: (number | null) | undefined; + /** URL to CSV file containing invalid email addresses, or null if none */ + invalid_emails?: (string | null) | undefined; + /** URL to CSV file containing duplicate contact IDs, or null if none */ + duplicate_contact_id?: (string | null) | undefined; + /** URL to CSV file containing duplicate external IDs, or null if none */ + duplicate_ext_id?: (string | null) | undefined; /** URL to CSV file containing duplicate email IDs, or null if none */ duplicate_email_id?: (string | null) | undefined; - /** Number of duplicate phone numbers */ - duplicate_phone_id?: (number | null) | undefined; - /** Number of duplicate WhatsApp numbers */ - duplicate_whatsapp_id?: (number | null) | undefined; - /** Number of duplicate landline numbers */ - duplicate_landline_number_id?: (number | null) | undefined; - } - - /** - * Export process details - */ - export interface Export { - /** Total number of exported records */ - total_records?: number | undefined; - /** Size of exported file in bytes */ - file_size?: number | undefined; + /** URL to CSV file containing duplicate phone numbers, or null if none */ + duplicate_phone_id?: (string | null) | undefined; + /** URL to CSV file containing duplicate WhatsApp numbers, or null if none */ + duplicate_whatsapp_id?: (string | null) | undefined; + /** URL to CSV file containing duplicate landline numbers, or null if none */ + duplicate_landline_number_id?: (string | null) | undefined; } } } diff --git a/src/api/resources/process/types/GetProcessesResponse.ts b/src/api/resources/process/types/GetProcessesResponse.ts index 7187111..a0018e1 100644 --- a/src/api/resources/process/types/GetProcessesResponse.ts +++ b/src/api/resources/process/types/GetProcessesResponse.ts @@ -18,16 +18,10 @@ export namespace GetProcessesResponse { name: Item.Name; /** Current status of the process */ status: Item.Status; - /** Additional process information (for completed processes) */ - info?: (Item.Info | null) | undefined; - /** Download URL for completed export processes */ - export_url?: (string | null) | undefined; - /** Error message for failed processes */ - error?: (string | null) | undefined; - /** Process creation timestamp */ - created_at?: (string | null) | undefined; - /** Process completion timestamp */ - completed_at?: (string | null) | undefined; + /** Additional process information, only returned for completed IMPORTUSER processes. Contains URLs to CSV files with details about problematic records. */ + info?: Item.Info | undefined; + /** Download URL for completed export processes (returned for SEARCH_EXPORT_USERS, SEARCH_EXPORT_USERS_API, CAMPAIGN_USER_DETAILS, and EXPORT_WEBHOOK process types) */ + export_url?: string | undefined; } export namespace Item { @@ -54,44 +48,32 @@ export namespace GetProcessesResponse { export type Status = (typeof Status)[keyof typeof Status]; /** - * Additional process information (for completed processes) + * Additional process information, only returned for completed IMPORTUSER processes. Contains URLs to CSV files with details about problematic records. */ export interface Info { - /** Import process details */ + /** Import process details with URLs to CSV reports */ import?: Info.Import | undefined; - /** Export process details */ - export?: Info.Export | undefined; } export namespace Info { /** - * Import process details + * Import process details with URLs to CSV reports */ export interface Import { - /** Number of invalid email addresses */ - invalid_emails?: (number | null) | undefined; - /** Number of duplicate contact IDs */ - duplicate_contact_id?: (number | null) | undefined; - /** Number of duplicate external IDs */ - duplicate_ext_id?: (number | null) | undefined; + /** URL to CSV file containing invalid email addresses, or null if none */ + invalid_emails?: (string | null) | undefined; + /** URL to CSV file containing duplicate contact IDs, or null if none */ + duplicate_contact_id?: (string | null) | undefined; + /** URL to CSV file containing duplicate external IDs, or null if none */ + duplicate_ext_id?: (string | null) | undefined; /** URL to CSV file containing duplicate email IDs, or null if none */ duplicate_email_id?: (string | null) | undefined; - /** Number of duplicate phone numbers */ - duplicate_phone_id?: (number | null) | undefined; - /** Number of duplicate WhatsApp numbers */ - duplicate_whatsapp_id?: (number | null) | undefined; - /** Number of duplicate landline numbers */ - duplicate_landline_number_id?: (number | null) | undefined; - } - - /** - * Export process details - */ - export interface Export { - /** Total number of exported records */ - total_records?: number | undefined; - /** Size of exported file in bytes */ - file_size?: number | undefined; + /** URL to CSV file containing duplicate phone numbers, or null if none */ + duplicate_phone_id?: (string | null) | undefined; + /** URL to CSV file containing duplicate WhatsApp numbers, or null if none */ + duplicate_whatsapp_id?: (string | null) | undefined; + /** URL to CSV file containing duplicate landline numbers, or null if none */ + duplicate_landline_number_id?: (string | null) | undefined; } } } diff --git a/src/api/resources/program/client/Client.ts b/src/api/resources/program/client/Client.ts index 43facb8..c418aa4 100644 --- a/src/api/resources/program/client/Client.ts +++ b/src/api/resources/program/client/Client.ts @@ -54,7 +54,7 @@ export class ProgramClient { limit, offset, sort_field: sortField != null ? sortField : undefined, - sort, + sort: sort != null ? sort : undefined, }; const _authRequest: core.AuthRequest = await this._options.authProvider.getAuthRequest(); const _headers: core.Fetcher.Args["headers"] = mergeHeaders( @@ -71,7 +71,11 @@ export class ProgramClient { ), method: "GET", headers: _headers, - queryParameters: { ..._queryParams, ...requestOptions?.queryParams }, + queryString: core.url + .queryBuilder() + .addMany(_queryParams) + .mergeAdditional(requestOptions?.queryParams) + .build(), timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, abortSignal: requestOptions?.abortSignal, @@ -155,7 +159,7 @@ export class ProgramClient { method: "POST", headers: _headers, contentType: "application/json", - queryParameters: requestOptions?.queryParams, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), requestType: "json", body: request, timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, @@ -239,7 +243,7 @@ export class ProgramClient { ), method: "GET", headers: _headers, - queryParameters: requestOptions?.queryParams, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, abortSignal: requestOptions?.abortSignal, @@ -329,7 +333,7 @@ export class ProgramClient { method: "PUT", headers: _headers, contentType: "application/json", - queryParameters: requestOptions?.queryParams, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), requestType: "json", body: _body, timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, @@ -420,7 +424,7 @@ export class ProgramClient { ), method: "DELETE", headers: _headers, - queryParameters: requestOptions?.queryParams, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, abortSignal: requestOptions?.abortSignal, @@ -509,7 +513,7 @@ export class ProgramClient { method: "PATCH", headers: _headers, contentType: "application/json", - queryParameters: requestOptions?.queryParams, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), requestType: "json", body: _body, timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, @@ -606,7 +610,11 @@ export class ProgramClient { ), method: "GET", headers: _headers, - queryParameters: { ..._queryParams, ...requestOptions?.queryParams }, + queryString: core.url + .queryBuilder() + .addMany(_queryParams) + .mergeAdditional(requestOptions?.queryParams) + .build(), timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, abortSignal: requestOptions?.abortSignal, @@ -698,7 +706,7 @@ export class ProgramClient { ), method: "DELETE", headers: _headers, - queryParameters: requestOptions?.queryParams, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, abortSignal: requestOptions?.abortSignal, @@ -787,7 +795,7 @@ export class ProgramClient { ), method: "POST", headers: _headers, - queryParameters: requestOptions?.queryParams, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, abortSignal: requestOptions?.abortSignal, @@ -877,7 +885,7 @@ export class ProgramClient { method: "POST", headers: _headers, contentType: "application/json", - queryParameters: requestOptions?.queryParams, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), requestType: "json", body: _body, timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, @@ -976,7 +984,11 @@ export class ProgramClient { ), method: "DELETE", headers: _headers, - queryParameters: { ..._queryParams, ...requestOptions?.queryParams }, + queryString: core.url + .queryBuilder() + .addMany(_queryParams) + .mergeAdditional(requestOptions?.queryParams) + .build(), timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, abortSignal: requestOptions?.abortSignal, @@ -1037,7 +1049,7 @@ export class ProgramClient { * @example * await client.program.subscribeToLoyaltyProgram({ * pid: "pid", - * contactId: 1 + * contactId: 1000000 * }) */ public subscribeToLoyaltyProgram( @@ -1068,7 +1080,7 @@ export class ProgramClient { method: "POST", headers: _headers, contentType: "application/json", - queryParameters: requestOptions?.queryParams, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), requestType: "json", body: _body, timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, diff --git a/src/api/resources/program/client/requests/GetLpListRequest.ts b/src/api/resources/program/client/requests/GetLpListRequest.ts index c8f85ed..d43a5bf 100644 --- a/src/api/resources/program/client/requests/GetLpListRequest.ts +++ b/src/api/resources/program/client/requests/GetLpListRequest.ts @@ -13,6 +13,6 @@ export interface GetLpListRequest { offset?: number; /** Sort documents by field */ sort_field?: Brevo.GetLpListRequestSortField; - /** Sort documents by field */ - sort?: string; + /** Sort order */ + sort?: Brevo.GetLpListRequestSort; } diff --git a/src/api/resources/program/client/requests/SubscribeToLoyaltyProgramRequest.ts b/src/api/resources/program/client/requests/SubscribeToLoyaltyProgramRequest.ts index c359ebf..772e9f9 100644 --- a/src/api/resources/program/client/requests/SubscribeToLoyaltyProgramRequest.ts +++ b/src/api/resources/program/client/requests/SubscribeToLoyaltyProgramRequest.ts @@ -4,7 +4,7 @@ * @example * { * pid: "pid", - * contactId: 1 + * contactId: 1000000 * } */ export interface SubscribeToLoyaltyProgramRequest { @@ -12,8 +12,10 @@ export interface SubscribeToLoyaltyProgramRequest { pid: string; /** Required contact ID; must be greater than 0. */ contactId: number; - /** Optional custom date-time format. */ - creationDate?: string; /** Optional subscription ID (max length 64). */ loyaltySubscriptionId?: string; + /** Optional creation date in ISO 8601 format (YYYY-MM-DDThh:mm:ss.ffffff+HH:MM). Must be in the past. */ + creationDate?: string; + /** Optional metadata associated with the subscription. */ + meta?: Record; } diff --git a/src/api/resources/program/types/GetLpListRequestSort.ts b/src/api/resources/program/types/GetLpListRequestSort.ts new file mode 100644 index 0000000..90e2837 --- /dev/null +++ b/src/api/resources/program/types/GetLpListRequestSort.ts @@ -0,0 +1,7 @@ +// This file was auto-generated by Fern from our API Definition. + +export const GetLpListRequestSort = { + Asc: "asc", + Desc: "desc", +} as const; +export type GetLpListRequestSort = (typeof GetLpListRequestSort)[keyof typeof GetLpListRequestSort]; diff --git a/src/api/resources/program/types/GetParameterSubscriptionInfoResponse.ts b/src/api/resources/program/types/GetParameterSubscriptionInfoResponse.ts index e9942bc..840473c 100644 --- a/src/api/resources/program/types/GetParameterSubscriptionInfoResponse.ts +++ b/src/api/resources/program/types/GetParameterSubscriptionInfoResponse.ts @@ -69,6 +69,8 @@ export namespace GetParameterSubscriptionInfoResponse { rewardId?: string | undefined; /** Timestamp when the reward was last updated. */ updatedAt?: string | undefined; + /** Date from which the voucher becomes valid. */ + validFrom?: string | undefined; } } diff --git a/src/api/resources/program/types/SubscribeMemberToASubscriptionResponse.ts b/src/api/resources/program/types/SubscribeMemberToASubscriptionResponse.ts index 775a80a..05ddc8d 100644 --- a/src/api/resources/program/types/SubscribeMemberToASubscriptionResponse.ts +++ b/src/api/resources/program/types/SubscribeMemberToASubscriptionResponse.ts @@ -1,14 +1,14 @@ // This file was auto-generated by Fern from our API Definition. export interface SubscribeMemberToASubscriptionResponse { - /** Timestamp when the subscription member was created. */ - createdAt?: string | undefined; - /** List of unique member contact IDs. */ - memberContactIds?: number[] | undefined; /** Unique identifier of the organization. */ organizationId?: number | undefined; /** Unique identifier of the subscription owner. */ ownerContactId?: number | undefined; + /** List of unique member contact IDs. */ + memberContactIds?: number[] | undefined; + /** Timestamp when the subscription member was created. */ + createdAt?: string | undefined; /** Timestamp when the subscription member was last updated. */ updatedAt?: string | undefined; } diff --git a/src/api/resources/program/types/SubscribeToLoyaltyProgramResponse.ts b/src/api/resources/program/types/SubscribeToLoyaltyProgramResponse.ts index 9030768..8444ad6 100644 --- a/src/api/resources/program/types/SubscribeToLoyaltyProgramResponse.ts +++ b/src/api/resources/program/types/SubscribeToLoyaltyProgramResponse.ts @@ -1,18 +1,20 @@ // This file was auto-generated by Fern from our API Definition. export interface SubscribeToLoyaltyProgramResponse { - /** Unique identifier of the contact. */ - contactId?: number | undefined; - /** Timestamp when the subscription was created. */ - createdAt?: string | undefined; + /** Unique identifier of the organization. */ + organizationId?: number | undefined; /** Unique identifier of the loyalty program. */ loyaltyProgramId?: string | undefined; + /** Version number of the subscription. */ + versionId?: number | undefined; + /** Unique identifier of the contact. */ + contactId?: number | undefined; /** Unique identifier of the subscription. */ loyaltySubscriptionId?: string | undefined; - /** Unique identifier of the organization. */ - organizationId?: number | undefined; + /** Metadata associated with the subscription. */ + meta?: Record | undefined; + /** Timestamp when the subscription was created. */ + createdAt?: string | undefined; /** Timestamp when the subscription was last updated. */ updatedAt?: string | undefined; - /** Version number of the subscription. */ - versionId?: number | undefined; } diff --git a/src/api/resources/program/types/index.ts b/src/api/resources/program/types/index.ts index 0cec94a..33841d5 100644 --- a/src/api/resources/program/types/index.ts +++ b/src/api/resources/program/types/index.ts @@ -1,3 +1,4 @@ +export * from "./GetLpListRequestSort.js"; export * from "./GetLpListRequestSortField.js"; export * from "./GetLpListResponse.js"; export * from "./GetParameterSubscriptionInfoResponse.js"; diff --git a/src/api/resources/reward/client/Client.ts b/src/api/resources/reward/client/Client.ts index dd836b7..5e4df1a 100644 --- a/src/api/resources/reward/client/Client.ts +++ b/src/api/resources/reward/client/Client.ts @@ -67,7 +67,7 @@ export class RewardClient { ), method: "GET", headers: _headers, - queryParameters: requestOptions?.queryParams, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, abortSignal: requestOptions?.abortSignal, @@ -161,7 +161,11 @@ export class RewardClient { ), method: "GET", headers: _headers, - queryParameters: { ..._queryParams, ...requestOptions?.queryParams }, + queryString: core.url + .queryBuilder() + .addMany(_queryParams) + .mergeAdditional(requestOptions?.queryParams) + .build(), timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, abortSignal: requestOptions?.abortSignal, @@ -254,7 +258,7 @@ export class RewardClient { method: "POST", headers: _headers, contentType: "application/json", - queryParameters: requestOptions?.queryParams, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), requestType: "json", body: _body, timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, @@ -344,7 +348,7 @@ export class RewardClient { method: "POST", headers: _headers, contentType: "application/json", - queryParameters: requestOptions?.queryParams, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), requestType: "json", body: _body, timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, @@ -439,7 +443,7 @@ export class RewardClient { method: "POST", headers: _headers, contentType: "application/json", - queryParameters: requestOptions?.queryParams, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), requestType: "json", body: _body, timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, @@ -544,7 +548,7 @@ export class RewardClient { ), method: "POST", headers: _headers, - queryParameters: requestOptions?.queryParams, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, abortSignal: requestOptions?.abortSignal, @@ -643,7 +647,11 @@ export class RewardClient { ), method: "DELETE", headers: _headers, - queryParameters: { ..._queryParams, ...requestOptions?.queryParams }, + queryString: core.url + .queryBuilder() + .addMany(_queryParams) + .mergeAdditional(requestOptions?.queryParams) + .build(), timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, abortSignal: requestOptions?.abortSignal, @@ -723,7 +731,7 @@ export class RewardClient { method: "POST", headers: _headers, contentType: "application/json", - queryParameters: requestOptions?.queryParams, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), requestType: "json", body: _body, timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, @@ -819,7 +827,11 @@ export class RewardClient { ), method: "GET", headers: _headers, - queryParameters: { ..._queryParams, ...requestOptions?.queryParams }, + queryString: core.url + .queryBuilder() + .addMany(_queryParams) + .mergeAdditional(requestOptions?.queryParams) + .build(), timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, abortSignal: requestOptions?.abortSignal, @@ -930,7 +942,11 @@ export class RewardClient { ), method: "GET", headers: _headers, - queryParameters: { ..._queryParams, ...requestOptions?.queryParams }, + queryString: core.url + .queryBuilder() + .addMany(_queryParams) + .mergeAdditional(requestOptions?.queryParams) + .build(), timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, abortSignal: requestOptions?.abortSignal, diff --git a/src/api/resources/reward/client/requests/CreateVoucherRequest.ts b/src/api/resources/reward/client/requests/CreateVoucherRequest.ts index 2ef3851..47850ec 100644 --- a/src/api/resources/reward/client/requests/CreateVoucherRequest.ts +++ b/src/api/resources/reward/client/requests/CreateVoucherRequest.ts @@ -24,4 +24,6 @@ export interface CreateVoucherRequest { rewardId: string; /** Value of the selected reward config */ value?: number; + /** Date from which the voucher becomes valid. Accepts RFC 3339 or DD/MM/YYYY HH:MM AM/PM format. Converted to UTC using the organization's timezone. */ + validFrom?: string; } diff --git a/src/api/resources/reward/client/requests/RedeemVoucherRequest.ts b/src/api/resources/reward/client/requests/RedeemVoucherRequest.ts index d7c38b1..defac8f 100644 --- a/src/api/resources/reward/client/requests/RedeemVoucherRequest.ts +++ b/src/api/resources/reward/client/requests/RedeemVoucherRequest.ts @@ -25,6 +25,8 @@ export interface RedeemVoucherRequest { rewardId?: string; /** Time to live in seconds for the redemption request */ ttl?: number; + /** Whether the redemption should be automatically completed */ + autoComplete?: boolean; } export namespace RedeemVoucherRequest { diff --git a/src/api/resources/reward/types/CreateRewardResponse.ts b/src/api/resources/reward/types/CreateRewardResponse.ts index f65d5f0..ce03cf1 100644 --- a/src/api/resources/reward/types/CreateRewardResponse.ts +++ b/src/api/resources/reward/types/CreateRewardResponse.ts @@ -1,20 +1,20 @@ // This file was auto-generated by Fern from our API Definition. export interface CreateRewardResponse { - /** Timestamp when the reward was created */ - createdAt?: string | undefined; /** Unique identifier for the reward */ id?: string | undefined; - /** Id of the loyalty program to which the current reward belongs to */ + /** Loyalty program to which the reward belongs */ loyaltyProgramId?: string | undefined; /** Name of the reward */ name?: string | undefined; - /** Public description for the reward */ + /** Public description of the reward */ publicDescription?: string | undefined; - /** Public Image for the reward */ + /** Public image URL of the reward */ publicImage?: string | undefined; - /** Public name for the reward */ + /** Public name of the reward */ publicName?: string | undefined; - /** Timestamp for when this reward was last updated. */ + /** Timestamp when the reward was created */ + createdAt?: string | undefined; + /** Timestamp when the reward was last updated */ updatedAt?: string | undefined; } diff --git a/src/api/resources/reward/types/CreateVoucherResponse.ts b/src/api/resources/reward/types/CreateVoucherResponse.ts index 56901dd..12bb420 100644 --- a/src/api/resources/reward/types/CreateVoucherResponse.ts +++ b/src/api/resources/reward/types/CreateVoucherResponse.ts @@ -23,4 +23,6 @@ export interface CreateVoucherResponse { updatedAt?: string | undefined; /** Value of the selected reward config */ value?: number | undefined; + /** Date from which the voucher becomes valid */ + validFrom?: string | undefined; } diff --git a/src/api/resources/reward/types/GetLoyaltyOfferProgramsPidVouchersResponse.ts b/src/api/resources/reward/types/GetLoyaltyOfferProgramsPidVouchersResponse.ts index 1e72ee3..d571a98 100644 --- a/src/api/resources/reward/types/GetLoyaltyOfferProgramsPidVouchersResponse.ts +++ b/src/api/resources/reward/types/GetLoyaltyOfferProgramsPidVouchersResponse.ts @@ -38,6 +38,8 @@ export namespace GetLoyaltyOfferProgramsPidVouchersResponse { updatedAt?: string | undefined; /** Value of the selected reward config */ value?: number | undefined; + /** Date from which the voucher becomes valid */ + validFrom?: string | undefined; } } } diff --git a/src/api/resources/senders/client/Client.ts b/src/api/resources/senders/client/Client.ts index 4edf96a..8ae5586 100644 --- a/src/api/resources/senders/client/Client.ts +++ b/src/api/resources/senders/client/Client.ts @@ -84,7 +84,11 @@ export class SendersClient { ), method: "GET", headers: _headers, - queryParameters: { ..._queryParams, ...requestOptions?.queryParams }, + queryString: core.url + .queryBuilder() + .addMany(_queryParams) + .mergeAdditional(requestOptions?.queryParams) + .build(), timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, abortSignal: requestOptions?.abortSignal, @@ -196,7 +200,7 @@ export class SendersClient { method: "POST", headers: _headers, contentType: "application/json", - queryParameters: requestOptions?.queryParams, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), requestType: "json", body: request, timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, @@ -270,7 +274,7 @@ export class SendersClient { ), method: "GET", headers: _headers, - queryParameters: requestOptions?.queryParams, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, abortSignal: requestOptions?.abortSignal, @@ -391,7 +395,7 @@ export class SendersClient { method: "PUT", headers: _headers, contentType: "application/json", - queryParameters: requestOptions?.queryParams, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), requestType: "json", body: _body, timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, @@ -471,7 +475,7 @@ export class SendersClient { ), method: "DELETE", headers: _headers, - queryParameters: requestOptions?.queryParams, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, abortSignal: requestOptions?.abortSignal, @@ -552,7 +556,7 @@ export class SendersClient { ), method: "GET", headers: _headers, - queryParameters: requestOptions?.queryParams, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, abortSignal: requestOptions?.abortSignal, @@ -640,7 +644,7 @@ export class SendersClient { method: "PUT", headers: _headers, contentType: "application/json", - queryParameters: requestOptions?.queryParams, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), requestType: "json", body: _body, timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, diff --git a/src/api/resources/senders/types/GetIpsResponse.ts b/src/api/resources/senders/types/GetIpsResponse.ts index 4614c77..a507d52 100644 --- a/src/api/resources/senders/types/GetIpsResponse.ts +++ b/src/api/resources/senders/types/GetIpsResponse.ts @@ -13,12 +13,12 @@ export namespace GetIpsResponse { export namespace Ips { export interface Item { + /** ID of the dedicated IP */ + id: number; /** Status of the IP (true=active, false=inactive) */ active: boolean; /** Domain associated to the IP */ domain: string; - /** ID of the dedicated IP */ - id: number; /** Dedicated IP address */ ip: string; } diff --git a/src/api/resources/smsCampaigns/client/Client.ts b/src/api/resources/smsCampaigns/client/Client.ts index 7bf2355..e552162 100644 --- a/src/api/resources/smsCampaigns/client/Client.ts +++ b/src/api/resources/smsCampaigns/client/Client.ts @@ -23,6 +23,8 @@ export class SmsCampaignsClient { } /** + * Retrieve a paginated list of all your SMS campaigns with their statistics and recipient information. Results can be filtered by status and date range, with a default limit of 500 and maximum of 1000 per page. The sort order defaults to descending by creation date; date filters are only available when status is not passed or is set to sent. + * * @param {Brevo.GetSmsCampaignsRequest} request * @param {SmsCampaignsClient.RequestOptions} requestOptions - Request-specific configuration. * @@ -66,7 +68,11 @@ export class SmsCampaignsClient { ), method: "GET", headers: _headers, - queryParameters: { ..._queryParams, ...requestOptions?.queryParams }, + queryString: core.url + .queryBuilder() + .addMany(_queryParams) + .mergeAdditional(requestOptions?.queryParams) + .build(), timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, abortSignal: requestOptions?.abortSignal, @@ -94,6 +100,8 @@ export class SmsCampaignsClient { } /** + * Create a new SMS campaign with the required name, sender, and content fields. The sender name is limited to 11 alphanumeric characters or 15 numeric characters, and the content should stay within 160 characters per SMS segment. If a scheduledAt date is provided, listIds in recipients become mandatory; accounts under validation are limited to 4 total campaigns and campaigns with more than 10 recipients will be saved as draft. + * * @param {Brevo.CreateSmsCampaignRequest} request * @param {SmsCampaignsClient.RequestOptions} requestOptions - Request-specific configuration. * @@ -133,7 +141,7 @@ export class SmsCampaignsClient { method: "POST", headers: _headers, contentType: "application/json", - queryParameters: requestOptions?.queryParams, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), requestType: "json", body: request, timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, @@ -163,6 +171,8 @@ export class SmsCampaignsClient { } /** + * Retrieve detailed information about a specific SMS campaign by its ID, including campaign content, sender, recipients with list names, statistics (delivered, sent, bounces, unsubscriptions, answered), and tags. Unlike the list endpoint, recipients are returned as objects with id and name fields rather than plain IDs. + * * @param {Brevo.GetSmsCampaignRequest} request * @param {SmsCampaignsClient.RequestOptions} requestOptions - Request-specific configuration. * @@ -201,7 +211,7 @@ export class SmsCampaignsClient { ), method: "GET", headers: _headers, - queryParameters: requestOptions?.queryParams, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, abortSignal: requestOptions?.abortSignal, @@ -231,6 +241,8 @@ export class SmsCampaignsClient { } /** + * Update an existing SMS campaign''s properties such as name, sender, content, recipients, scheduled date, organisation prefix, and unsubscribe instructions. The request body must contain at least one valid field to update. The campaign must exist and must be of type SMS; if a scheduledAt is provided, valid recipients must be present either in the request or already configured on the campaign. + * * @param {Brevo.UpdateSmsCampaignRequest} request * @param {SmsCampaignsClient.RequestOptions} requestOptions - Request-specific configuration. * @@ -270,7 +282,7 @@ export class SmsCampaignsClient { method: "PUT", headers: _headers, contentType: "application/json", - queryParameters: requestOptions?.queryParams, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), requestType: "json", body: _body, timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, @@ -302,6 +314,8 @@ export class SmsCampaignsClient { } /** + * Delete an SMS campaign by its campaign ID. Only campaigns that have not been scheduled or sent can be deleted; attempting to delete a campaign that is queued, in process, or has been sent with recipients will return a 403 permission denied error. + * * @param {Brevo.DeleteSmsCampaignRequest} request * @param {SmsCampaignsClient.RequestOptions} requestOptions - Request-specific configuration. * @@ -340,7 +354,7 @@ export class SmsCampaignsClient { ), method: "DELETE", headers: _headers, - queryParameters: requestOptions?.queryParams, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, abortSignal: requestOptions?.abortSignal, @@ -412,7 +426,7 @@ export class SmsCampaignsClient { method: "POST", headers: _headers, contentType: "application/json", - queryParameters: requestOptions?.queryParams, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), requestType: "json", body: _body, timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, @@ -452,6 +466,8 @@ export class SmsCampaignsClient { } /** + * Send an existing SMS campaign immediately by scheduling it for the current time. The system verifies your account''s SMS credit balance before dispatching; if credits are insufficient or the remaining credit is less than the number of recipients, a 402 error is returned. The campaign must have valid recipients and content already configured. + * * @param {Brevo.SendSmsCampaignNowRequest} request * @param {SmsCampaignsClient.RequestOptions} requestOptions - Request-specific configuration. * @@ -491,7 +507,7 @@ export class SmsCampaignsClient { ), method: "POST", headers: _headers, - queryParameters: requestOptions?.queryParams, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, abortSignal: requestOptions?.abortSignal, @@ -578,7 +594,7 @@ export class SmsCampaignsClient { method: "POST", headers: _headers, contentType: "application/json", - queryParameters: requestOptions?.queryParams, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), requestType: "json", body: _body, timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, @@ -615,6 +631,8 @@ export class SmsCampaignsClient { } /** + * Send a test SMS to a specified phone number to preview the campaign before sending it to all recipients. The phone number must belong to one of your existing contacts in your Brevo account and must not be blacklisted. The number should include the country code (e.g. 33689965433). + * * @param {Brevo.SendTestSmsRequest} request * @param {SmsCampaignsClient.RequestOptions} requestOptions - Request-specific configuration. * @@ -654,7 +672,7 @@ export class SmsCampaignsClient { method: "POST", headers: _headers, contentType: "application/json", - queryParameters: requestOptions?.queryParams, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), requestType: "json", body: _body, timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, @@ -691,6 +709,8 @@ export class SmsCampaignsClient { } /** + * Update the status of an SMS campaign, such as suspending, archiving, or replicating it. Available status values include suspended, archive, darchive, sent, queued, replicate, replicateTemplate, cancel, and draft. Note that the replicateTemplate status is only available for template type campaigns. + * * @param {Brevo.UpdateSmsCampaignStatusRequest} request * @param {SmsCampaignsClient.RequestOptions} requestOptions - Request-specific configuration. * @@ -731,7 +751,7 @@ export class SmsCampaignsClient { method: "PUT", headers: _headers, contentType: "application/json", - queryParameters: requestOptions?.queryParams, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), requestType: "json", body: _body, timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, diff --git a/src/api/resources/smsCampaigns/client/requests/GetSmsCampaignsRequest.ts b/src/api/resources/smsCampaigns/client/requests/GetSmsCampaignsRequest.ts index 31e8ff6..b99e102 100644 --- a/src/api/resources/smsCampaigns/client/requests/GetSmsCampaignsRequest.ts +++ b/src/api/resources/smsCampaigns/client/requests/GetSmsCampaignsRequest.ts @@ -9,11 +9,11 @@ import type * as Brevo from "../../../../index.js"; export interface GetSmsCampaignsRequest { /** Status of campaign. */ status?: Brevo.GetSmsCampaignsRequestStatus; - /** **Mandatory if endDate is used.** Starting (urlencoded) UTC date-time (YYYY-MM-DDTHH:mm:ss.SSSZ) to filter the sent sms campaigns. **Prefer to pass your timezone in date-time format for accurate result** ( only available if either 'status' not passed and if passed is set to 'sent' ) */ + /** **Mandatory if endDate is used.** Starting (urlencoded) UTC date-time (YYYY-MM-DDTHH:mm:ss.SSSZ) to filter the sent SMS campaigns. **Prefer to pass your timezone in date-time format for accurate result.** Only available if `status` is not passed or is set to `sent`. `startDate` must not be in the future. */ startDate?: string; - /** **Mandatory if startDate is used.** Ending (urlencoded) UTC date-time (YYYY-MM-DDTHH:mm:ss.SSSZ) to filter the sent sms campaigns. **Prefer to pass your timezone in date-time format for accurate result** ( only available if either 'status' not passed and if passed is set to 'sent' ) */ + /** **Mandatory if startDate is used.** Ending (urlencoded) UTC date-time (YYYY-MM-DDTHH:mm:ss.SSSZ) to filter the sent SMS campaigns. **Prefer to pass your timezone in date-time format for accurate result.** Only available if `status` is not passed or is set to `sent`. `endDate` must not be in the future. */ endDate?: string; - /** Number limitation for the result returned */ + /** Number of documents per page */ limit?: number; /** Beginning point in the list to retrieve from. */ offset?: number; diff --git a/src/api/resources/smsCampaigns/types/GetSmsCampaignResponse.ts b/src/api/resources/smsCampaigns/types/GetSmsCampaignResponse.ts index e58d7f3..8301516 100644 --- a/src/api/resources/smsCampaigns/types/GetSmsCampaignResponse.ts +++ b/src/api/resources/smsCampaigns/types/GetSmsCampaignResponse.ts @@ -13,14 +13,23 @@ export interface GetSmsCampaignResponse { modifiedAt: string; /** Name of the SMS Campaign */ name: string; - /** UTC date-time on which SMS campaign is scheduled. Should be in YYYY-MM-DDTHH:mm:ss.SSSZ format */ + /** A recognizable prefix added as the Brand Name before the message content. Empty string if not set. */ + organisationPrefix?: string | undefined; + /** UTC date-time on which SMS campaign is scheduled. Should be in YYYY-MM-DDTHH:mm:ss.SSSZ format. Empty string if not scheduled. */ scheduledAt?: string | undefined; /** Sender of the SMS Campaign */ sender: string; + /** UTC date-time on which the SMS campaign was sent (YYYY-MM-DDTHH:mm:ss.SSSZ). Only available if the campaign status is 'sent'. */ + sentDate?: string | undefined; /** Status of the SMS Campaign */ status: GetSmsCampaignResponse.Status; - recipients: Brevo.GetCampaignRecipients; + /** Instructions to unsubscribe from future communications. Empty string if not set. */ + unsubscribeInstruction?: string | undefined; + /** Recipients of the SMS campaign. For a single campaign, lists and exclusion lists are returned as objects with id and name. */ + recipients: GetSmsCampaignResponse.Recipients; statistics: Brevo.GetSmsCampaignStats; + /** Tags (labels) associated with the SMS campaign. Only available when retrieving a single campaign. */ + tags?: string[] | undefined; } export namespace GetSmsCampaignResponse { @@ -34,4 +43,36 @@ export namespace GetSmsCampaignResponse { InProcess: "inProcess", } as const; export type Status = (typeof Status)[keyof typeof Status]; + + /** + * Recipients of the SMS campaign. For a single campaign, lists and exclusion lists are returned as objects with id and name. + */ + export interface Recipients { + exclusionLists?: Recipients.ExclusionLists.Item[] | undefined; + lists?: Recipients.Lists.Item[] | undefined; + } + + export namespace Recipients { + export type ExclusionLists = ExclusionLists.Item[]; + + export namespace ExclusionLists { + export interface Item { + /** ID of the exclusion list */ + id?: number | undefined; + /** Name of the exclusion list */ + name?: string | undefined; + } + } + + export type Lists = Lists.Item[]; + + export namespace Lists { + export interface Item { + /** ID of the list */ + id?: number | undefined; + /** Name of the list */ + name?: string | undefined; + } + } + } } diff --git a/src/api/resources/smsCampaigns/types/GetSmsCampaignsResponse.ts b/src/api/resources/smsCampaigns/types/GetSmsCampaignsResponse.ts index 2e07b14..db58610 100644 --- a/src/api/resources/smsCampaigns/types/GetSmsCampaignsResponse.ts +++ b/src/api/resources/smsCampaigns/types/GetSmsCampaignsResponse.ts @@ -23,12 +23,18 @@ export namespace GetSmsCampaignsResponse { modifiedAt: string; /** Name of the SMS Campaign */ name: string; - /** UTC date-time on which SMS campaign is scheduled. Should be in YYYY-MM-DDTHH:mm:ss.SSSZ format */ + /** A recognizable prefix added as the Brand Name before the message content. Empty string if not set. */ + organisationPrefix?: string | undefined; + /** UTC date-time on which SMS campaign is scheduled. Should be in YYYY-MM-DDTHH:mm:ss.SSSZ format. Empty string if not scheduled. */ scheduledAt?: string | undefined; /** Sender of the SMS Campaign */ sender: string; + /** UTC date-time on which the SMS campaign was sent (YYYY-MM-DDTHH:mm:ss.SSSZ). Only available if the campaign status is 'sent'. */ + sentDate?: string | undefined; /** Status of the SMS Campaign */ status: Item.Status; + /** Instructions to unsubscribe from future communications. Empty string if not set. */ + unsubscribeInstruction?: string | undefined; recipients: Brevo.GetCampaignRecipients; statistics: Brevo.GetSmsCampaignStats; } diff --git a/src/api/resources/smsTemplates/client/Client.ts b/src/api/resources/smsTemplates/client/Client.ts index b9c2fd2..7535b93 100644 --- a/src/api/resources/smsTemplates/client/Client.ts +++ b/src/api/resources/smsTemplates/client/Client.ts @@ -63,7 +63,11 @@ export class SmsTemplatesClient { ), method: "GET", headers: _headers, - queryParameters: { ..._queryParams, ...requestOptions?.queryParams }, + queryString: core.url + .queryBuilder() + .addMany(_queryParams) + .mergeAdditional(requestOptions?.queryParams) + .build(), timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, abortSignal: requestOptions?.abortSignal, diff --git a/src/api/resources/tasks/client/Client.ts b/src/api/resources/tasks/client/Client.ts index 4e85ecc..477bee5 100644 --- a/src/api/resources/tasks/client/Client.ts +++ b/src/api/resources/tasks/client/Client.ts @@ -23,6 +23,8 @@ export class TasksClient { } /** + * Retrieve a paginated list of CRM tasks with optional filtering by task type, status, date range, assignee, and linked entities (contacts, deals, companies). Results are sorted by creation date in descending order by default, with a default limit of 50 tasks per page. + * * @param {Brevo.GetCrmTasksRequest} request * @param {TasksClient.RequestOptions} requestOptions - Request-specific configuration. * @@ -89,7 +91,11 @@ export class TasksClient { ), method: "GET", headers: _headers, - queryParameters: { ..._queryParams, ...requestOptions?.queryParams }, + queryString: core.url + .queryBuilder() + .addMany(_queryParams) + .mergeAdditional(requestOptions?.queryParams) + .build(), timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, abortSignal: requestOptions?.abortSignal, @@ -117,6 +123,8 @@ export class TasksClient { } /** + * Create a new CRM task with the specified name, type, due date, and optional associations to contacts, companies, or deals. A task requires a name, task type ID, and due date at minimum. You can also set a duration, notes, a reminder, and assign the task to a specific user. + * * @param {Brevo.PostCrmTasksRequest} request * @param {TasksClient.RequestOptions} requestOptions - Request-specific configuration. * @@ -125,7 +133,7 @@ export class TasksClient { * @example * await client.tasks.createATask({ * date: "2021-11-01T17:44:54Z", - * name: "Task: Connect with client_dev", + * name: "Task: Connect with client", * taskTypeId: "61a5cd07ca1347c82306ad09" * }) */ @@ -156,7 +164,7 @@ export class TasksClient { method: "POST", headers: _headers, contentType: "application/json", - queryParameters: requestOptions?.queryParams, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), requestType: "json", body: request, timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, @@ -186,6 +194,8 @@ export class TasksClient { } /** + * Retrieve the full details of a single CRM task by its identifier. The response includes the task''s name, type, status, due date, duration, notes, assignee, reminder settings, and linked contacts, companies, or deals. + * * @param {Brevo.GetCrmTasksIdRequest} request * @param {TasksClient.RequestOptions} requestOptions - Request-specific configuration. * @@ -224,7 +234,7 @@ export class TasksClient { ), method: "GET", headers: _headers, - queryParameters: requestOptions?.queryParams, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, abortSignal: requestOptions?.abortSignal, @@ -254,6 +264,8 @@ export class TasksClient { } /** + * Permanently delete a CRM task by its identifier. This removes the task and cancels any associated reminders. The requesting user must be the task assignee or have manage permission on tasks. + * * @param {Brevo.DeleteCrmTasksIdRequest} request * @param {TasksClient.RequestOptions} requestOptions - Request-specific configuration. * @@ -292,7 +304,7 @@ export class TasksClient { ), method: "DELETE", headers: _headers, - queryParameters: requestOptions?.queryParams, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, abortSignal: requestOptions?.abortSignal, @@ -322,6 +334,8 @@ export class TasksClient { } /** + * Update an existing CRM task''s properties such as name, type, due date, status, duration, notes, assignee, reminder, or linked entities. Only the fields provided in the request body will be updated; omitted fields remain unchanged. + * * @param {Brevo.PatchCrmTasksIdRequest} request * @param {TasksClient.RequestOptions} requestOptions - Request-specific configuration. * @@ -361,7 +375,7 @@ export class TasksClient { method: "PATCH", headers: _headers, contentType: "application/json", - queryParameters: requestOptions?.queryParams, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), requestType: "json", body: _body, timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, @@ -393,20 +407,24 @@ export class TasksClient { } /** + * Retrieve the list of all available task types, such as Email, Call, Meeting, Todo, Lunch, Deadline, and LinkedIn. If no task types exist yet, the default set is automatically created and returned. Use the task type ID when creating or updating tasks. + * * @param {TasksClient.RequestOptions} requestOptions - Request-specific configuration. * + * @throws {@link Brevo.BadRequestError} + * * @example * await client.tasks.getAllTaskTypes() */ public getAllTaskTypes( requestOptions?: TasksClient.RequestOptions, - ): core.HttpResponsePromise { + ): core.HttpResponsePromise { return core.HttpResponsePromise.fromPromise(this.__getAllTaskTypes(requestOptions)); } private async __getAllTaskTypes( requestOptions?: TasksClient.RequestOptions, - ): Promise> { + ): Promise> { const _authRequest: core.AuthRequest = await this._options.authProvider.getAuthRequest(); const _headers: core.Fetcher.Args["headers"] = mergeHeaders( _authRequest.headers, @@ -422,7 +440,7 @@ export class TasksClient { ), method: "GET", headers: _headers, - queryParameters: requestOptions?.queryParams, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, abortSignal: requestOptions?.abortSignal, @@ -430,15 +448,20 @@ export class TasksClient { logging: this._options.logging, }); if (_response.ok) { - return { data: _response.body as Brevo.GetCrmTasktypesResponse, rawResponse: _response.rawResponse }; + return { data: _response.body as Brevo.GetCrmTasktypesResponseItem[], rawResponse: _response.rawResponse }; } if (_response.error.reason === "status-code") { - throw new errors.BrevoError({ - statusCode: _response.error.statusCode, - body: _response.error.body, - rawResponse: _response.rawResponse, - }); + switch (_response.error.statusCode) { + case 400: + throw new Brevo.BadRequestError(_response.error.body as unknown, _response.rawResponse); + default: + throw new errors.BrevoError({ + statusCode: _response.error.statusCode, + body: _response.error.body, + rawResponse: _response.rawResponse, + }); + } } return handleNonStatusCodeError(_response.error, _response.rawResponse, "GET", "/crm/tasktypes"); diff --git a/src/api/resources/tasks/client/requests/PostCrmTasksRequest.ts b/src/api/resources/tasks/client/requests/PostCrmTasksRequest.ts index 407964c..ff65e41 100644 --- a/src/api/resources/tasks/client/requests/PostCrmTasksRequest.ts +++ b/src/api/resources/tasks/client/requests/PostCrmTasksRequest.ts @@ -6,7 +6,7 @@ import type * as Brevo from "../../../../index.js"; * @example * { * date: "2021-11-01T17:44:54Z", - * name: "Task: Connect with client_dev", + * name: "Task: Connect with client", * taskTypeId: "61a5cd07ca1347c82306ad09" * } */ diff --git a/src/api/resources/tasks/types/GetCrmTasktypesResponse.ts b/src/api/resources/tasks/types/GetCrmTasktypesResponseItem.ts similarity index 71% rename from src/api/resources/tasks/types/GetCrmTasktypesResponse.ts rename to src/api/resources/tasks/types/GetCrmTasktypesResponseItem.ts index b9317e3..48532c6 100644 --- a/src/api/resources/tasks/types/GetCrmTasktypesResponse.ts +++ b/src/api/resources/tasks/types/GetCrmTasktypesResponseItem.ts @@ -1,9 +1,6 @@ // This file was auto-generated by Fern from our API Definition. -/** - * Task types details - */ -export interface GetCrmTasktypesResponse { +export interface GetCrmTasktypesResponseItem { /** Id of task type */ id?: string | undefined; /** Title of task type */ diff --git a/src/api/resources/tasks/types/index.ts b/src/api/resources/tasks/types/index.ts index cb1bf53..2426afd 100644 --- a/src/api/resources/tasks/types/index.ts +++ b/src/api/resources/tasks/types/index.ts @@ -2,5 +2,5 @@ export * from "./GetCrmTasksRequestFilterDate.js"; export * from "./GetCrmTasksRequestFilterStatus.js"; export * from "./GetCrmTasksRequestSort.js"; export * from "./GetCrmTasksResponse.js"; -export * from "./GetCrmTasktypesResponse.js"; +export * from "./GetCrmTasktypesResponseItem.js"; export * from "./PostCrmTasksResponse.js"; diff --git a/src/api/resources/tier/client/Client.ts b/src/api/resources/tier/client/Client.ts index d97c22b..453ef50 100644 --- a/src/api/resources/tier/client/Client.ts +++ b/src/api/resources/tier/client/Client.ts @@ -70,7 +70,7 @@ export class TierClient { ), method: "POST", headers: _headers, - queryParameters: requestOptions?.queryParams, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, abortSignal: requestOptions?.abortSignal, @@ -164,7 +164,11 @@ export class TierClient { ), method: "GET", headers: _headers, - queryParameters: { ..._queryParams, ...requestOptions?.queryParams }, + queryString: core.url + .queryBuilder() + .addMany(_queryParams) + .mergeAdditional(requestOptions?.queryParams) + .build(), timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, abortSignal: requestOptions?.abortSignal, @@ -254,7 +258,7 @@ export class TierClient { method: "POST", headers: _headers, contentType: "application/json", - queryParameters: requestOptions?.queryParams, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), requestType: "json", body: _body, timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, @@ -349,7 +353,11 @@ export class TierClient { ), method: "GET", headers: _headers, - queryParameters: { ..._queryParams, ...requestOptions?.queryParams }, + queryString: core.url + .queryBuilder() + .addMany(_queryParams) + .mergeAdditional(requestOptions?.queryParams) + .build(), timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, abortSignal: requestOptions?.abortSignal, @@ -442,7 +450,7 @@ export class TierClient { method: "PUT", headers: _headers, contentType: "application/json", - queryParameters: requestOptions?.queryParams, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), requestType: "json", body: _body, timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, @@ -533,7 +541,7 @@ export class TierClient { ), method: "DELETE", headers: _headers, - queryParameters: requestOptions?.queryParams, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, abortSignal: requestOptions?.abortSignal, @@ -626,7 +634,7 @@ export class TierClient { method: "POST", headers: _headers, contentType: "application/json", - queryParameters: requestOptions?.queryParams, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), requestType: "json", body: _body, timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, @@ -718,7 +726,11 @@ export class TierClient { ), method: "GET", headers: _headers, - queryParameters: { ..._queryParams, ...requestOptions?.queryParams }, + queryString: core.url + .queryBuilder() + .addMany(_queryParams) + .mergeAdditional(requestOptions?.queryParams) + .build(), timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, abortSignal: requestOptions?.abortSignal, @@ -810,7 +822,7 @@ export class TierClient { method: "PUT", headers: _headers, contentType: "application/json", - queryParameters: requestOptions?.queryParams, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), requestType: "json", body: _body, timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, @@ -900,7 +912,7 @@ export class TierClient { ), method: "DELETE", headers: _headers, - queryParameters: requestOptions?.queryParams, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, abortSignal: requestOptions?.abortSignal, diff --git a/src/api/resources/tier/client/requests/CreateTierGroupRequest.ts b/src/api/resources/tier/client/requests/CreateTierGroupRequest.ts index 642d878..f2eaf20 100644 --- a/src/api/resources/tier/client/requests/CreateTierGroupRequest.ts +++ b/src/api/resources/tier/client/requests/CreateTierGroupRequest.ts @@ -20,6 +20,10 @@ export interface CreateTierGroupRequest { tierOrder?: string[]; /** Select real_time to upgrade tier on real time balance updates. Select membership_anniversary to upgrade tier on subscription anniversary. Select tier_anniversary to upgrade tier on tier anniversary. */ upgradeStrategy?: CreateTierGroupRequest.UpgradeStrategy; + /** Schedule configuration for tier upgrades. Required when upgradeStrategy is set to a schedule-based strategy. */ + upgradeSchedule?: CreateTierGroupRequest.UpgradeSchedule; + /** Schedule configuration for tier downgrades. Required when downgradeStrategy is set to a schedule-based strategy. */ + downgradeSchedule?: CreateTierGroupRequest.DowngradeSchedule; } export namespace CreateTierGroupRequest { @@ -48,4 +52,66 @@ export namespace CreateTierGroupRequest { TierAnniversary: "tier_anniversary", } as const; export type UpgradeStrategy = (typeof UpgradeStrategy)[keyof typeof UpgradeStrategy]; + + /** + * Schedule configuration for tier upgrades. Required when upgradeStrategy is set to a schedule-based strategy. + */ + export interface UpgradeSchedule { + /** Duration value for the schedule. */ + durationValue?: number | undefined; + /** Duration unit for the schedule. */ + durationUnit?: UpgradeSchedule.DurationUnit | undefined; + /** Modifier for the duration. */ + durationModifier?: UpgradeSchedule.DurationModifier | undefined; + /** Scheduled date in DD/MM format. */ + scheduledDate?: string | undefined; + } + + export namespace UpgradeSchedule { + /** Duration unit for the schedule. */ + export const DurationUnit = { + Day: "day", + Week: "week", + Month: "month", + Year: "year", + } as const; + export type DurationUnit = (typeof DurationUnit)[keyof typeof DurationUnit]; + /** Modifier for the duration. */ + export const DurationModifier = { + StartOfPeriod: "start_of_period", + EndOfPeriod: "end_of_period", + } as const; + export type DurationModifier = (typeof DurationModifier)[keyof typeof DurationModifier]; + } + + /** + * Schedule configuration for tier downgrades. Required when downgradeStrategy is set to a schedule-based strategy. + */ + export interface DowngradeSchedule { + /** Duration value for the schedule. */ + durationValue?: number | undefined; + /** Duration unit for the schedule. */ + durationUnit?: DowngradeSchedule.DurationUnit | undefined; + /** Modifier for the duration. */ + durationModifier?: DowngradeSchedule.DurationModifier | undefined; + /** Scheduled date in DD/MM format. */ + scheduledDate?: string | undefined; + } + + export namespace DowngradeSchedule { + /** Duration unit for the schedule. */ + export const DurationUnit = { + Day: "day", + Week: "week", + Month: "month", + Year: "year", + } as const; + export type DurationUnit = (typeof DurationUnit)[keyof typeof DurationUnit]; + /** Modifier for the duration. */ + export const DurationModifier = { + StartOfPeriod: "start_of_period", + EndOfPeriod: "end_of_period", + } as const; + export type DurationModifier = (typeof DurationModifier)[keyof typeof DurationModifier]; + } } diff --git a/src/api/resources/transactionalEmails/client/Client.ts b/src/api/resources/transactionalEmails/client/Client.ts index 4d7da71..d0eb476 100644 --- a/src/api/resources/transactionalEmails/client/Client.ts +++ b/src/api/resources/transactionalEmails/client/Client.ts @@ -23,6 +23,8 @@ export class TransactionalEmailsClient { } /** + * Retrieve a paginated list of transactional contacts that have been blocked or unsubscribed, along with the reason for blocking (e.g. hard bounce, admin blocked, spam complaint, or unsubscription via email/API/Marketing Automation). Both `startDate` and `endDate` must be provided together when filtering by date range, and neither date can be in the future. Results default to 50 per page (max 100) and are sorted in descending order of record creation unless overridden with the `sort` parameter. + * * @param {Brevo.GetTransacBlockedContactsRequest} request * @param {TransactionalEmailsClient.RequestOptions} requestOptions - Request-specific configuration. * @@ -66,7 +68,12 @@ export class TransactionalEmailsClient { ), method: "GET", headers: _headers, - queryParameters: { ..._queryParams, ...requestOptions?.queryParams }, + queryString: core.url + .queryBuilder() + .addMany(_queryParams) + .add("senders", _queryParams.senders, { style: "comma" }) + .mergeAdditional(requestOptions?.queryParams) + .build(), timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, abortSignal: requestOptions?.abortSignal, @@ -97,6 +104,8 @@ export class TransactionalEmailsClient { } /** + * Unblock or resubscribe a transactional contact by removing their email address from the blacklist. The email address must be URL-encoded in the path parameter and must be a valid email format. If the contact is not found in the blocklist, a 404 error is returned. + * * @param {Brevo.DeleteSmtpBlockedContactsEmailRequest} request * @param {TransactionalEmailsClient.RequestOptions} requestOptions - Request-specific configuration. * @@ -137,7 +146,7 @@ export class TransactionalEmailsClient { ), method: "DELETE", headers: _headers, - queryParameters: requestOptions?.queryParams, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, abortSignal: requestOptions?.abortSignal, @@ -176,6 +185,8 @@ export class TransactionalEmailsClient { * * @param {TransactionalEmailsClient.RequestOptions} requestOptions - Request-specific configuration. * + * @throws {@link Brevo.BadRequestError} + * * @example * await client.transactionalEmails.getBlockedDomains() */ @@ -203,7 +214,7 @@ export class TransactionalEmailsClient { ), method: "GET", headers: _headers, - queryParameters: requestOptions?.queryParams, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, abortSignal: requestOptions?.abortSignal, @@ -215,11 +226,16 @@ export class TransactionalEmailsClient { } if (_response.error.reason === "status-code") { - throw new errors.BrevoError({ - statusCode: _response.error.statusCode, - body: _response.error.body, - rawResponse: _response.rawResponse, - }); + switch (_response.error.statusCode) { + case 400: + throw new Brevo.BadRequestError(_response.error.body as unknown, _response.rawResponse); + default: + throw new errors.BrevoError({ + statusCode: _response.error.statusCode, + body: _response.error.body, + rawResponse: _response.rawResponse, + }); + } } return handleNonStatusCodeError(_response.error, _response.rawResponse, "GET", "/smtp/blockedDomains"); @@ -265,7 +281,7 @@ export class TransactionalEmailsClient { method: "POST", headers: _headers, contentType: "application/json", - queryParameters: requestOptions?.queryParams, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), requestType: "json", body: request, timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, @@ -335,7 +351,7 @@ export class TransactionalEmailsClient { ), method: "DELETE", headers: _headers, - queryParameters: requestOptions?.queryParams, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, abortSignal: requestOptions?.abortSignal, @@ -407,7 +423,7 @@ export class TransactionalEmailsClient { method: "POST", headers: _headers, contentType: "application/json", - queryParameters: requestOptions?.queryParams, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), requestType: "json", body: request, timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, @@ -437,6 +453,8 @@ export class TransactionalEmailsClient { } /** + * Send a transactional email to one or more recipients, either using inline HTML content or a pre-built template via `templateId`. You can schedule emails for future delivery using `scheduledAt` (UTC, up to 5-minute delay), send multiple personalized versions with `messageVersions` (max 2000 total recipients, 99 per version), and attach files via URL or base64-encoded content. A `sender` and `subject` are required when no `templateId` is provided; when a `templateId` is used, the template''s sender and subject are applied unless overridden. + * * @param {Brevo.SendTransacEmailRequest} request * @param {TransactionalEmailsClient.RequestOptions} requestOptions - Request-specific configuration. * @@ -501,7 +519,7 @@ export class TransactionalEmailsClient { method: "POST", headers: _headers, contentType: "application/json", - queryParameters: requestOptions?.queryParams, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), requestType: "json", body: request, timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, @@ -571,7 +589,7 @@ export class TransactionalEmailsClient { ), method: "DELETE", headers: _headers, - queryParameters: requestOptions?.queryParams, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, abortSignal: requestOptions?.abortSignal, @@ -651,7 +669,11 @@ export class TransactionalEmailsClient { ), method: "GET", headers: _headers, - queryParameters: { ..._queryParams, ...requestOptions?.queryParams }, + queryString: core.url + .queryBuilder() + .addMany(_queryParams) + .mergeAdditional(requestOptions?.queryParams) + .build(), timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, abortSignal: requestOptions?.abortSignal, @@ -733,7 +755,11 @@ export class TransactionalEmailsClient { ), method: "GET", headers: _headers, - queryParameters: { ..._queryParams, ...requestOptions?.queryParams }, + queryString: core.url + .queryBuilder() + .addMany(_queryParams) + .mergeAdditional(requestOptions?.queryParams) + .build(), timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, abortSignal: requestOptions?.abortSignal, @@ -768,6 +794,9 @@ export class TransactionalEmailsClient { * @param {Brevo.GetTransacEmailContentRequest} request * @param {TransactionalEmailsClient.RequestOptions} requestOptions - Request-specific configuration. * + * @throws {@link Brevo.BadRequestError} + * @throws {@link Brevo.NotFoundError} + * * @example * await client.transactionalEmails.getTransacEmailContent({ * uuid: "uuid" @@ -800,7 +829,7 @@ export class TransactionalEmailsClient { ), method: "GET", headers: _headers, - queryParameters: requestOptions?.queryParams, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, abortSignal: requestOptions?.abortSignal, @@ -812,17 +841,26 @@ export class TransactionalEmailsClient { } if (_response.error.reason === "status-code") { - throw new errors.BrevoError({ - statusCode: _response.error.statusCode, - body: _response.error.body, - rawResponse: _response.rawResponse, - }); + switch (_response.error.statusCode) { + case 400: + throw new Brevo.BadRequestError(_response.error.body as unknown, _response.rawResponse); + case 404: + throw new Brevo.NotFoundError(_response.error.body as unknown, _response.rawResponse); + default: + throw new errors.BrevoError({ + statusCode: _response.error.statusCode, + body: _response.error.body, + rawResponse: _response.rawResponse, + }); + } } return handleNonStatusCodeError(_response.error, _response.rawResponse, "GET", "/smtp/emails/{uuid}"); } /** + * Delete SMTP transactional log entries identified by a message ID (enclosed in angle brackets with an @ sign) or a valid email address. Optionally narrow the deletion to a specific date range using `from_date` and `to_date` query parameters (YYYY-MM-DD format). The operation also removes any associated stored email preview content. + * * @param {Brevo.DeleteSmtpLogIdentifierRequest} request * @param {TransactionalEmailsClient.RequestOptions} requestOptions - Request-specific configuration. * @@ -845,7 +883,11 @@ export class TransactionalEmailsClient { request: Brevo.DeleteSmtpLogIdentifierRequest, requestOptions?: TransactionalEmailsClient.RequestOptions, ): Promise> { - const { identifier } = request; + const { identifier, from_date: fromDate, to_date: toDate } = request; + const _queryParams: Record = { + from_date: fromDate, + to_date: toDate, + }; const _authRequest: core.AuthRequest = await this._options.authProvider.getAuthRequest(); const _headers: core.Fetcher.Args["headers"] = mergeHeaders( _authRequest.headers, @@ -861,7 +903,11 @@ export class TransactionalEmailsClient { ), method: "DELETE", headers: _headers, - queryParameters: requestOptions?.queryParams, + queryString: core.url + .queryBuilder() + .addMany(_queryParams) + .mergeAdditional(requestOptions?.queryParams) + .build(), timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, abortSignal: requestOptions?.abortSignal, @@ -934,7 +980,11 @@ export class TransactionalEmailsClient { ), method: "GET", headers: _headers, - queryParameters: { ..._queryParams, ...requestOptions?.queryParams }, + queryString: core.url + .queryBuilder() + .addMany(_queryParams) + .mergeAdditional(requestOptions?.queryParams) + .build(), timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, abortSignal: requestOptions?.abortSignal, @@ -1020,7 +1070,11 @@ export class TransactionalEmailsClient { ), method: "GET", headers: _headers, - queryParameters: { ..._queryParams, ...requestOptions?.queryParams }, + queryString: core.url + .queryBuilder() + .addMany(_queryParams) + .mergeAdditional(requestOptions?.queryParams) + .build(), timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, abortSignal: requestOptions?.abortSignal, @@ -1048,6 +1102,8 @@ export class TransactionalEmailsClient { } /** + * This endpoint will show the aggregated stats per day for the past 10 days by default if `startDate` and `endDate` OR `days` is not passed. The date range can not exceed 30 days. + * * @param {Brevo.GetSmtpReportRequest} request * @param {TransactionalEmailsClient.RequestOptions} requestOptions - Request-specific configuration. * @@ -1092,7 +1148,11 @@ export class TransactionalEmailsClient { ), method: "GET", headers: _headers, - queryParameters: { ..._queryParams, ...requestOptions?.queryParams }, + queryString: core.url + .queryBuilder() + .addMany(_queryParams) + .mergeAdditional(requestOptions?.queryParams) + .build(), timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, abortSignal: requestOptions?.abortSignal, @@ -1120,7 +1180,9 @@ export class TransactionalEmailsClient { } /** - * @param {unknown} request + * Generate a fully rendered preview of a transactional email template by resolving dynamic variables. Provide either an `email` address (to populate variables from the contact''s attributes) or a `params` object with key-value pairs for manual substitution; at least one of these is required alongside the mandatory `templateId`. The response includes the rendered HTML, subject, sender details, preview text, and any feed names used in the template. + * + * @param {Brevo.PostPreviewSmtpEmailTemplatesRequest} request * @param {TransactionalEmailsClient.RequestOptions} requestOptions - Request-specific configuration. * * @throws {@link Brevo.BadRequestError} @@ -1131,14 +1193,14 @@ export class TransactionalEmailsClient { * }) */ public postPreviewSmtpEmailTemplates( - request?: unknown, + request: Brevo.PostPreviewSmtpEmailTemplatesRequest, requestOptions?: TransactionalEmailsClient.RequestOptions, ): core.HttpResponsePromise { return core.HttpResponsePromise.fromPromise(this.__postPreviewSmtpEmailTemplates(request, requestOptions)); } private async __postPreviewSmtpEmailTemplates( - request?: unknown, + request: Brevo.PostPreviewSmtpEmailTemplatesRequest, requestOptions?: TransactionalEmailsClient.RequestOptions, ): Promise> { const _authRequest: core.AuthRequest = await this._options.authProvider.getAuthRequest(); @@ -1157,7 +1219,7 @@ export class TransactionalEmailsClient { method: "POST", headers: _headers, contentType: "application/json", - queryParameters: requestOptions?.queryParams, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), requestType: "json", body: request, timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, @@ -1190,6 +1252,8 @@ export class TransactionalEmailsClient { } /** + * Retrieve a paginated list of all transactional email templates (including automation templates) with their details such as name, subject, sender, status, HTML content, and timestamps. Results default to 50 per page (max 1000) and are sorted in descending creation order unless overridden. You can filter by active/inactive status using `templateStatus` and by editor type using `editorType` (currently only `richTextEditor` is supported). + * * @param {Brevo.GetSmtpTemplatesRequest} request * @param {TransactionalEmailsClient.RequestOptions} requestOptions - Request-specific configuration. * @@ -1209,12 +1273,13 @@ export class TransactionalEmailsClient { request: Brevo.GetSmtpTemplatesRequest = {}, requestOptions?: TransactionalEmailsClient.RequestOptions, ): Promise> { - const { templateStatus, limit, offset, sort } = request; + const { templateStatus, limit, offset, sort, editorType } = request; const _queryParams: Record = { templateStatus, limit, offset, sort: sort != null ? sort : undefined, + editorType: editorType != null ? editorType : undefined, }; const _authRequest: core.AuthRequest = await this._options.authProvider.getAuthRequest(); const _headers: core.Fetcher.Args["headers"] = mergeHeaders( @@ -1231,7 +1296,11 @@ export class TransactionalEmailsClient { ), method: "GET", headers: _headers, - queryParameters: { ..._queryParams, ...requestOptions?.queryParams }, + queryString: core.url + .queryBuilder() + .addMany(_queryParams) + .mergeAdditional(requestOptions?.queryParams) + .build(), timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, abortSignal: requestOptions?.abortSignal, @@ -1259,6 +1328,8 @@ export class TransactionalEmailsClient { } /** + * Create a new transactional email template with the specified sender, subject, and content. The `sender`, `subject`, and `templateName` fields are required. Template content can be provided via `htmlContent` (minimum 10 characters) or `htmlUrl`; at least one must be supplied. Templates are created as inactive by default unless `isActive` is explicitly set to `true`. + * * @param {Brevo.CreateSmtpTemplateRequest} request * @param {TransactionalEmailsClient.RequestOptions} requestOptions - Request-specific configuration. * @@ -1298,7 +1369,7 @@ export class TransactionalEmailsClient { method: "POST", headers: _headers, contentType: "application/json", - queryParameters: requestOptions?.queryParams, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), requestType: "json", body: request, timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, @@ -1328,6 +1399,8 @@ export class TransactionalEmailsClient { } /** + * Retrieve the full details of a specific transactional email template by its numeric ID or custom template identifier string. The response includes the template name, subject, sender information, HTML content, active status, creation and modification timestamps, reply-to address, tag, and a `doiTemplate` flag indicating whether the template is a double opt-in template (detected by the presence of optin-related tags or variables in the content). + * * @param {Brevo.GetSmtpTemplateRequest} request * @param {TransactionalEmailsClient.RequestOptions} requestOptions - Request-specific configuration. * @@ -1366,7 +1439,7 @@ export class TransactionalEmailsClient { ), method: "GET", headers: _headers, - queryParameters: requestOptions?.queryParams, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, abortSignal: requestOptions?.abortSignal, @@ -1396,6 +1469,8 @@ export class TransactionalEmailsClient { } /** + * Update an existing transactional email template by its numeric ID or custom template identifier string. All fields in the request body are optional; only the provided fields will be updated. You can update the template name, subject, sender, reply-to address, HTML content (via `htmlContent` or `htmlUrl`), active status, tag, attachment URL, and the personalized `toField`. Only one of sender email or sender ID should be provided per request. + * * @param {Brevo.UpdateSmtpTemplateRequest} request * @param {TransactionalEmailsClient.RequestOptions} requestOptions - Request-specific configuration. * @@ -1435,7 +1510,7 @@ export class TransactionalEmailsClient { method: "PUT", headers: _headers, contentType: "application/json", - queryParameters: requestOptions?.queryParams, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), requestType: "json", body: _body, timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, @@ -1467,6 +1542,8 @@ export class TransactionalEmailsClient { } /** + * Permanently delete a transactional email template by its numeric ID. Only inactive templates can be deleted; attempting to delete an active template returns a 405 error. To deactivate a template before deletion, use `PUT /smtp/templates/{templateId}` with `isActive` set to `false`. Deletion also removes associated newsletter template data and triggers asynchronous cleanup of shared assets. + * * @param {Brevo.DeleteSmtpTemplateRequest} request * @param {TransactionalEmailsClient.RequestOptions} requestOptions - Request-specific configuration. * @@ -1505,7 +1582,7 @@ export class TransactionalEmailsClient { ), method: "DELETE", headers: _headers, - queryParameters: requestOptions?.queryParams, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, abortSignal: requestOptions?.abortSignal, @@ -1540,6 +1617,8 @@ export class TransactionalEmailsClient { } /** + * Send a test email of the specified transactional template to one or more recipients. Provide an array of email addresses in the `emailTo` field; if left empty, the test mail is sent to your entire test list. You can send a maximum of 50 test emails per day, and all provided email addresses must be valid. + * * @param {Brevo.SendTestTemplateRequest} request * @param {TransactionalEmailsClient.RequestOptions} requestOptions - Request-specific configuration. * @@ -1580,7 +1659,7 @@ export class TransactionalEmailsClient { method: "POST", headers: _headers, contentType: "application/json", - queryParameters: requestOptions?.queryParams, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), requestType: "json", body: _body, timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, diff --git a/src/api/resources/transactionalEmails/client/requests/DeleteScheduledEmailByIdRequest.ts b/src/api/resources/transactionalEmails/client/requests/DeleteScheduledEmailByIdRequest.ts index 8d943ea..13a0d9a 100644 --- a/src/api/resources/transactionalEmails/client/requests/DeleteScheduledEmailByIdRequest.ts +++ b/src/api/resources/transactionalEmails/client/requests/DeleteScheduledEmailByIdRequest.ts @@ -7,6 +7,6 @@ * } */ export interface DeleteScheduledEmailByIdRequest { - /** The `batchId` of scheduled emails batch (Should be a valid UUIDv4) or the `messageId` of scheduled email. */ + /** The `batchId` of scheduled emails batch (must be a valid UUIDv4) or the `messageId` of scheduled email (enclosed in angle brackets with @ sign, e.g. `<...@domain>`). */ identifier: string; } diff --git a/src/api/resources/transactionalEmails/client/requests/DeleteSmtpLogIdentifierRequest.ts b/src/api/resources/transactionalEmails/client/requests/DeleteSmtpLogIdentifierRequest.ts index 2b0e9d8..a4a24f1 100644 --- a/src/api/resources/transactionalEmails/client/requests/DeleteSmtpLogIdentifierRequest.ts +++ b/src/api/resources/transactionalEmails/client/requests/DeleteSmtpLogIdentifierRequest.ts @@ -7,6 +7,10 @@ * } */ export interface DeleteSmtpLogIdentifierRequest { - /** MessageId of the transactional log(s) to delete */ + /** MessageId or email address of the transactional log(s) to delete. Must be a valid message ID (enclosed in angle brackets with @ sign) or a valid email address. */ identifier: string; + /** Starting date (YYYY-MM-DD) to narrow down logs for deletion */ + from_date?: string; + /** Ending date (YYYY-MM-DD) to narrow down logs for deletion */ + to_date?: string; } diff --git a/src/api/resources/transactionalEmails/client/requests/GetAggregatedSmtpReportRequest.ts b/src/api/resources/transactionalEmails/client/requests/GetAggregatedSmtpReportRequest.ts index a2871dd..1269716 100644 --- a/src/api/resources/transactionalEmails/client/requests/GetAggregatedSmtpReportRequest.ts +++ b/src/api/resources/transactionalEmails/client/requests/GetAggregatedSmtpReportRequest.ts @@ -9,7 +9,7 @@ export interface GetAggregatedSmtpReportRequest { startDate?: string; /** **Mandatory if startDate is used.** Ending date of the report (YYYY-MM-DD). Must be greater than equal to startDate */ endDate?: string; - /** Number of days in the past including today (positive integer). _Not compatible with 'startDate' and 'endDate'_ */ + /** Number of days in the past including today (positive integer, maximum 90). _Not compatible with 'startDate' and 'endDate'_. Defaults to 90 if neither dates nor days are provided. */ days?: number; /** Tag of the emails */ tag?: string; diff --git a/src/api/resources/transactionalEmails/client/requests/GetEmailEventReportRequest.ts b/src/api/resources/transactionalEmails/client/requests/GetEmailEventReportRequest.ts index 7da330b..80c8300 100644 --- a/src/api/resources/transactionalEmails/client/requests/GetEmailEventReportRequest.ts +++ b/src/api/resources/transactionalEmails/client/requests/GetEmailEventReportRequest.ts @@ -15,7 +15,7 @@ export interface GetEmailEventReportRequest { startDate?: string; /** **Mandatory if startDate is used.** Ending date of the report (YYYY-MM-DD). Must be greater than equal to startDate */ endDate?: string; - /** Number of days in the past including today (positive integer). _Not compatible with 'startDate' and 'endDate'_ */ + /** Number of days in the past including today (positive integer, maximum 90). _Not compatible with 'startDate' and 'endDate'_. Defaults to 30 if neither dates nor days are provided. */ days?: number; /** Filter the report for a specific email addresses */ email?: string; diff --git a/src/api/resources/transactionalEmails/client/requests/GetScheduledEmailByIdRequest.ts b/src/api/resources/transactionalEmails/client/requests/GetScheduledEmailByIdRequest.ts index 1f724df..b9a6e91 100644 --- a/src/api/resources/transactionalEmails/client/requests/GetScheduledEmailByIdRequest.ts +++ b/src/api/resources/transactionalEmails/client/requests/GetScheduledEmailByIdRequest.ts @@ -11,9 +11,9 @@ import type * as Brevo from "../../../../index.js"; * } */ export interface GetScheduledEmailByIdRequest { - /** The `batchId` of scheduled emails batch (Should be a valid UUIDv4) or the `messageId` of scheduled email. */ + /** The `batchId` of scheduled emails batch (must be a valid UUIDv4) or the `messageId` of scheduled email (enclosed in angle brackets with @ sign, e.g. `<...@domain>`). When using `messageId`, the `limit`, `offset`, `sort`, and `status` query parameters are ignored. */ identifier: string; - /** Mandatory if `endDate` is used. Starting date (YYYY-MM-DD) from which you want to fetch the list. Can be maximum 30 days older tha current date. */ + /** Mandatory if `endDate` is used. Starting date (YYYY-MM-DD) from which you want to fetch the list. Cannot be more than 30 days older than the current date. */ startDate?: string; /** Mandatory if `startDate` is used. Ending date (YYYY-MM-DD) till which you want to fetch the list. Maximum time period that can be selected is one month. */ endDate?: string; diff --git a/src/api/resources/transactionalEmails/client/requests/GetSmtpReportRequest.ts b/src/api/resources/transactionalEmails/client/requests/GetSmtpReportRequest.ts index f2fd0b2..b313520 100644 --- a/src/api/resources/transactionalEmails/client/requests/GetSmtpReportRequest.ts +++ b/src/api/resources/transactionalEmails/client/requests/GetSmtpReportRequest.ts @@ -15,7 +15,7 @@ export interface GetSmtpReportRequest { startDate?: string; /** **Mandatory if startDate is used.** Ending date of the report (YYYY-MM-DD) */ endDate?: string; - /** Number of days in the past including today (positive integer). _Not compatible with 'startDate' and 'endDate'_ */ + /** Number of days in the past including today (positive integer, maximum 30). _Not compatible with 'startDate' and 'endDate'_ */ days?: number; /** Tag of the emails */ tag?: string; diff --git a/src/api/resources/transactionalEmails/client/requests/GetSmtpTemplateRequest.ts b/src/api/resources/transactionalEmails/client/requests/GetSmtpTemplateRequest.ts index b674209..29bd0a9 100644 --- a/src/api/resources/transactionalEmails/client/requests/GetSmtpTemplateRequest.ts +++ b/src/api/resources/transactionalEmails/client/requests/GetSmtpTemplateRequest.ts @@ -1,5 +1,7 @@ // This file was auto-generated by Fern from our API Definition. +import type * as Brevo from "../../../../index.js"; + /** * @example * { @@ -7,6 +9,6 @@ * } */ export interface GetSmtpTemplateRequest { - /** id of the template */ - templateId: number; + /** ID of the template. Can be a numeric template ID or a custom template identifier string (alphanumeric, hyphens, and underscores only, max 64 characters, must start with a letter). */ + templateId: Brevo.GetSmtpTemplateRequestTemplateId; } diff --git a/src/api/resources/transactionalEmails/client/requests/GetSmtpTemplatesRequest.ts b/src/api/resources/transactionalEmails/client/requests/GetSmtpTemplatesRequest.ts index 368e057..81f4b20 100644 --- a/src/api/resources/transactionalEmails/client/requests/GetSmtpTemplatesRequest.ts +++ b/src/api/resources/transactionalEmails/client/requests/GetSmtpTemplatesRequest.ts @@ -15,4 +15,6 @@ export interface GetSmtpTemplatesRequest { offset?: number; /** Sort the results in the ascending/descending order of record creation. Default order is **descending** if `sort` is not passed */ sort?: Brevo.GetSmtpTemplatesRequestSort; + /** Filter on the editor type used to create the template. Currently only `richTextEditor` is supported as a filter value. */ + editorType?: "richTextEditor"; } diff --git a/src/api/resources/transactionalEmails/client/requests/UpdateSmtpTemplateRequest.ts b/src/api/resources/transactionalEmails/client/requests/UpdateSmtpTemplateRequest.ts index ef44548..8a2581c 100644 --- a/src/api/resources/transactionalEmails/client/requests/UpdateSmtpTemplateRequest.ts +++ b/src/api/resources/transactionalEmails/client/requests/UpdateSmtpTemplateRequest.ts @@ -1,5 +1,7 @@ // This file was auto-generated by Fern from our API Definition. +import type * as Brevo from "../../../../index.js"; + /** * @example * { @@ -7,8 +9,8 @@ * } */ export interface UpdateSmtpTemplateRequest { - /** id of the template */ - templateId: number; + /** ID of the template. Can be a numeric template ID or a custom template identifier string. */ + templateId: Brevo.UpdateSmtpTemplateRequestTemplateId; /** Absolute url of the attachment (**no local file**). Extensions allowed: #### xlsx, xls, ods, docx, docm, doc, csv, pdf, txt, gif, jpg, jpeg, png, tif, tiff, rtf, bmp, cgm, css, shtml, html, htm, zip, xml, ppt, pptx, tar, ez, ics, mobi, msg, pub and eps */ attachmentUrl?: string; /** **Required if htmlUrl is empty**. If the template is designed using Drag & Drop editor via HTML content, then the design page will not have Drag & Drop editor access for that template. Body of the message (HTML must have more than 10 characters) */ diff --git a/src/api/resources/transactionalEmails/types/GetSmtpTemplateRequestTemplateId.ts b/src/api/resources/transactionalEmails/types/GetSmtpTemplateRequestTemplateId.ts new file mode 100644 index 0000000..29ae6f7 --- /dev/null +++ b/src/api/resources/transactionalEmails/types/GetSmtpTemplateRequestTemplateId.ts @@ -0,0 +1,3 @@ +// This file was auto-generated by Fern from our API Definition. + +export type GetSmtpTemplateRequestTemplateId = number | string; diff --git a/src/api/resources/transactionalEmails/types/GetTransacEmailContentResponse.ts b/src/api/resources/transactionalEmails/types/GetTransacEmailContentResponse.ts index 810cecd..32002f7 100644 --- a/src/api/resources/transactionalEmails/types/GetTransacEmailContentResponse.ts +++ b/src/api/resources/transactionalEmails/types/GetTransacEmailContentResponse.ts @@ -2,9 +2,9 @@ export interface GetTransacEmailContentResponse { /** Count of the attachments that were sent in the email */ - attachmentCount: number; + attachmentCount?: number | undefined; /** Actual content of the transactional email that has been sent */ - body: string; + body?: string | undefined; /** Date on which transactional email was sent */ date: string; /** Email address to which transactional email has been sent */ diff --git a/src/api/resources/transactionalEmails/types/PostPreviewSmtpEmailTemplatesRequest.ts b/src/api/resources/transactionalEmails/types/PostPreviewSmtpEmailTemplatesRequest.ts new file mode 100644 index 0000000..a7e99c4 --- /dev/null +++ b/src/api/resources/transactionalEmails/types/PostPreviewSmtpEmailTemplatesRequest.ts @@ -0,0 +1,3 @@ +// This file was auto-generated by Fern from our API Definition. + +export type PostPreviewSmtpEmailTemplatesRequest = unknown; diff --git a/src/api/resources/transactionalEmails/types/UpdateSmtpTemplateRequestTemplateId.ts b/src/api/resources/transactionalEmails/types/UpdateSmtpTemplateRequestTemplateId.ts new file mode 100644 index 0000000..158368f --- /dev/null +++ b/src/api/resources/transactionalEmails/types/UpdateSmtpTemplateRequestTemplateId.ts @@ -0,0 +1,3 @@ +// This file was auto-generated by Fern from our API Definition. + +export type UpdateSmtpTemplateRequestTemplateId = number | string; diff --git a/src/api/resources/transactionalEmails/types/index.ts b/src/api/resources/transactionalEmails/types/index.ts index cc5fc42..e880a1b 100644 --- a/src/api/resources/transactionalEmails/types/index.ts +++ b/src/api/resources/transactionalEmails/types/index.ts @@ -9,6 +9,7 @@ export * from "./GetScheduledEmailByIdRequestStatus.js"; export * from "./GetScheduledEmailByIdResponse.js"; export * from "./GetSmtpReportRequestSort.js"; export * from "./GetSmtpReportResponse.js"; +export * from "./GetSmtpTemplateRequestTemplateId.js"; export * from "./GetSmtpTemplatesRequestSort.js"; export * from "./GetSmtpTemplatesResponse.js"; export * from "./GetTransacBlockedContactsRequestSort.js"; @@ -16,5 +17,7 @@ export * from "./GetTransacBlockedContactsResponse.js"; export * from "./GetTransacEmailContentResponse.js"; export * from "./GetTransacEmailsListRequestSort.js"; export * from "./GetTransacEmailsListResponse.js"; +export * from "./PostPreviewSmtpEmailTemplatesRequest.js"; export * from "./PostPreviewSmtpEmailTemplatesResponse.js"; export * from "./SendTransacEmailResponse.js"; +export * from "./UpdateSmtpTemplateRequestTemplateId.js"; diff --git a/src/api/resources/transactionalSms/client/Client.ts b/src/api/resources/transactionalSms/client/Client.ts index 3ad1b61..1c9d8fd 100644 --- a/src/api/resources/transactionalSms/client/Client.ts +++ b/src/api/resources/transactionalSms/client/Client.ts @@ -65,7 +65,7 @@ export class TransactionalSmsClient { method: "POST", headers: _headers, contentType: "application/json", - queryParameters: requestOptions?.queryParams, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), requestType: "json", body: request, timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, @@ -100,11 +100,14 @@ export class TransactionalSmsClient { /** * @deprecated * + * Send a transactional SMS message to a single mobile number. The `sender`, `recipient`, and either `content` or `templateId` fields are required. The sender name is limited to 11 alphanumeric characters or 15 numeric characters, and the recipient must be a valid international phone number (6-15 digits, optional leading +). Tags can be a string or an array of up to 10 strings. The SMS type defaults to `transactional` but can be set to `marketing`; if the content includes a stop code, it is automatically treated as marketing. Returns the message ID, SMS count, credits used, and remaining credits. + * * @param {Brevo.SendTransacSms} request * @param {TransactionalSmsClient.RequestOptions} requestOptions - Request-specific configuration. * * @throws {@link Brevo.BadRequestError} * @throws {@link Brevo.PaymentRequiredError} + * @throws {@link Brevo.TooManyRequestsError} * * @example * await client.transactionalSms.sendTransacSms({ @@ -139,7 +142,7 @@ export class TransactionalSmsClient { method: "POST", headers: _headers, contentType: "application/json", - queryParameters: requestOptions?.queryParams, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), requestType: "json", body: request, timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, @@ -161,6 +164,11 @@ export class TransactionalSmsClient { _response.error.body as Brevo.ErrorModel, _response.rawResponse, ); + case 429: + throw new Brevo.TooManyRequestsError( + _response.error.body as Brevo.ErrorModel, + _response.rawResponse, + ); default: throw new errors.BrevoError({ statusCode: _response.error.statusCode, @@ -174,6 +182,8 @@ export class TransactionalSmsClient { } /** + * Retrieve an aggregated report of your transactional SMS activity over a specified time period, including counts for requests, delivered, hard bounces, soft bounces, blocked, unsubscribed, replied, accepted, rejected, and skipped messages. Filter by date range using `startDate` and `endDate` (both required together, YYYY-MM-DD format) or by a number of past `days` (not compatible with date range). You can further narrow results by `tag`. If no date filter is provided, the report covers all available data and returns the auto-detected date range. + * * @param {Brevo.GetTransacAggregatedSmsReportRequest} request * @param {TransactionalSmsClient.RequestOptions} requestOptions - Request-specific configuration. * @@ -215,7 +225,11 @@ export class TransactionalSmsClient { ), method: "GET", headers: _headers, - queryParameters: { ..._queryParams, ...requestOptions?.queryParams }, + queryString: core.url + .queryBuilder() + .addMany(_queryParams) + .mergeAdditional(requestOptions?.queryParams) + .build(), timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, abortSignal: requestOptions?.abortSignal, @@ -251,6 +265,8 @@ export class TransactionalSmsClient { } /** + * Retrieve a paginated list of individual SMS event records (unaggregated), including event type, phone number, message ID, timestamp, tag, and reason or reply content where applicable. Results default to 50 per page (max 100) and are sorted in descending order unless overridden. Filter by date range (`startDate`/`endDate`), past `days` (not compatible with date range), specific `event` type (e.g. delivered, bounces, replies), `phoneNumber`, or `tags`. Bounce events include the failure reason, and reply events include the reply content. + * * @param {Brevo.GetSmsEventsRequest} request * @param {TransactionalSmsClient.RequestOptions} requestOptions - Request-specific configuration. * @@ -297,7 +313,11 @@ export class TransactionalSmsClient { ), method: "GET", headers: _headers, - queryParameters: { ..._queryParams, ...requestOptions?.queryParams }, + queryString: core.url + .queryBuilder() + .addMany(_queryParams) + .mergeAdditional(requestOptions?.queryParams) + .build(), timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, abortSignal: requestOptions?.abortSignal, @@ -330,6 +350,8 @@ export class TransactionalSmsClient { } /** + * Retrieve a day-by-day breakdown of your transactional SMS activity, with each entry containing the date and counts for requests, delivered, hard bounces, soft bounces, blocked, unsubscribed, replied, accepted, rejected, and skipped messages. Filter by date range using `startDate` and `endDate` (both required together, YYYY-MM-DD format), by a number of past `days` (not compatible with date range), or by `tag`. Results are sorted in descending order by default unless overridden with the `sort` parameter. + * * @param {Brevo.GetTransacSmsReportRequest} request * @param {TransactionalSmsClient.RequestOptions} requestOptions - Request-specific configuration. * @@ -372,7 +394,11 @@ export class TransactionalSmsClient { ), method: "GET", headers: _headers, - queryParameters: { ..._queryParams, ...requestOptions?.queryParams }, + queryString: core.url + .queryBuilder() + .addMany(_queryParams) + .mergeAdditional(requestOptions?.queryParams) + .build(), timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, abortSignal: requestOptions?.abortSignal, diff --git a/src/api/resources/transactionalWhatsApp/client/Client.ts b/src/api/resources/transactionalWhatsApp/client/Client.ts index 9ef4c07..e4d3f96 100644 --- a/src/api/resources/transactionalWhatsApp/client/Client.ts +++ b/src/api/resources/transactionalWhatsApp/client/Client.ts @@ -66,7 +66,7 @@ export class TransactionalWhatsAppClient { method: "POST", headers: _headers, contentType: "application/json", - queryParameters: requestOptions?.queryParams, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), requestType: "json", body: request, timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, @@ -143,7 +143,11 @@ export class TransactionalWhatsAppClient { ), method: "GET", headers: _headers, - queryParameters: { ..._queryParams, ...requestOptions?.queryParams }, + queryString: core.url + .queryBuilder() + .addMany(_queryParams) + .mergeAdditional(requestOptions?.queryParams) + .build(), timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, abortSignal: requestOptions?.abortSignal, diff --git a/src/api/resources/user/client/Client.ts b/src/api/resources/user/client/Client.ts index dcc94ed..c05af50 100644 --- a/src/api/resources/user/client/Client.ts +++ b/src/api/resources/user/client/Client.ts @@ -23,6 +23,8 @@ export class UserClient { } /** + * Retrieves the list of all users associated with your organization, including both active and pending invited users. Each user entry includes their email address, owner status, current invitation status, and feature access levels for marketing, CRM, and conversations. + * * @param {UserClient.RequestOptions} requestOptions - Request-specific configuration. * * @throws {@link Brevo.BadRequestError} @@ -54,7 +56,7 @@ export class UserClient { ), method: "GET", headers: _headers, - queryParameters: requestOptions?.queryParams, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, abortSignal: requestOptions?.abortSignal, @@ -82,6 +84,8 @@ export class UserClient { } /** + * Revokes all permissions for an invited user in the organization, effectively removing their access to the platform. If the user''s plan change generated credit notes, they are returned in the response for billing reconciliation. + * * @param {Brevo.PutRevokeUserPermissionRequest} request * @param {UserClient.RequestOptions} requestOptions - Request-specific configuration. * @@ -119,7 +123,7 @@ export class UserClient { ), method: "PUT", headers: _headers, - queryParameters: requestOptions?.queryParams, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, abortSignal: requestOptions?.abortSignal, @@ -263,7 +267,7 @@ export class UserClient { method: "POST", headers: _headers, contentType: "application/json", - queryParameters: requestOptions?.queryParams, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), requestType: "json", body: request, timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, @@ -298,6 +302,8 @@ export class UserClient { } /** + * Resends or cancels a pending invitation for a user in the organization, depending on the action path parameter. Use `resend` to send a new invitation email to the user, or `cancel` to revoke the pending invitation entirely and remove the user''s pending access. + * * @param {Brevo.PutresendcancelinvitationRequest} request * @param {UserClient.RequestOptions} requestOptions - Request-specific configuration. * @@ -336,7 +342,7 @@ export class UserClient { ), method: "PUT", headers: _headers, - queryParameters: requestOptions?.queryParams, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, abortSignal: requestOptions?.abortSignal, @@ -479,7 +485,7 @@ export class UserClient { method: "POST", headers: _headers, contentType: "application/json", - queryParameters: requestOptions?.queryParams, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), requestType: "json", body: request, timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, @@ -514,6 +520,8 @@ export class UserClient { } /** + * Retrieves the granular feature-level permissions assigned to a specific user in the organization, identified by their email address. The response includes the user''s current status (active or pending) and a detailed list of privileges specifying which features and permission levels are granted. + * * @param {Brevo.GetUserPermissionRequest} request * @param {UserClient.RequestOptions} requestOptions - Request-specific configuration. * @@ -551,7 +559,7 @@ export class UserClient { ), method: "GET", headers: _headers, - queryParameters: requestOptions?.queryParams, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, abortSignal: requestOptions?.abortSignal, diff --git a/src/api/resources/webhooks/client/Client.ts b/src/api/resources/webhooks/client/Client.ts index 1ce80b5..11d6401 100644 --- a/src/api/resources/webhooks/client/Client.ts +++ b/src/api/resources/webhooks/client/Client.ts @@ -78,7 +78,11 @@ export class WebhooksClient { ), method: "GET", headers: _headers, - queryParameters: { ..._queryParams, ...requestOptions?.queryParams }, + queryString: core.url + .queryBuilder() + .addMany(_queryParams) + .mergeAdditional(requestOptions?.queryParams) + .build(), timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, abortSignal: requestOptions?.abortSignal, @@ -126,7 +130,6 @@ export class WebhooksClient { * * @example * await client.webhooks.createWebhook({ - * events: ["sent"], * url: "http://requestb.in/173lyyx1" * }) */ @@ -157,7 +160,7 @@ export class WebhooksClient { method: "POST", headers: _headers, contentType: "application/json", - queryParameters: requestOptions?.queryParams, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), requestType: "json", body: request, timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, @@ -237,7 +240,7 @@ export class WebhooksClient { method: "POST", headers: _headers, contentType: "application/json", - queryParameters: requestOptions?.queryParams, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), requestType: "json", body: request, timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, @@ -321,7 +324,7 @@ export class WebhooksClient { ), method: "GET", headers: _headers, - queryParameters: requestOptions?.queryParams, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, abortSignal: requestOptions?.abortSignal, @@ -402,7 +405,7 @@ export class WebhooksClient { method: "PUT", headers: _headers, contentType: "application/json", - queryParameters: requestOptions?.queryParams, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), requestType: "json", body: _body, timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, @@ -483,7 +486,7 @@ export class WebhooksClient { ), method: "DELETE", headers: _headers, - queryParameters: requestOptions?.queryParams, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, abortSignal: requestOptions?.abortSignal, diff --git a/src/api/resources/webhooks/client/requests/CreateWebhookRequest.ts b/src/api/resources/webhooks/client/requests/CreateWebhookRequest.ts index 0c734aa..c523d74 100644 --- a/src/api/resources/webhooks/client/requests/CreateWebhookRequest.ts +++ b/src/api/resources/webhooks/client/requests/CreateWebhookRequest.ts @@ -3,7 +3,6 @@ /** * @example * { - * events: ["sent"], * url: "http://requestb.in/173lyyx1" * } */ @@ -12,7 +11,7 @@ export interface CreateWebhookRequest { auth?: CreateWebhookRequest.Auth; /** To send batched webhooks */ batched?: boolean; - /** channel of webhook */ + /** Channel of the webhook */ channel?: CreateWebhookRequest.Channel; /** Description of the webhook */ description?: string; @@ -22,24 +21,18 @@ export interface CreateWebhookRequest { */ domain?: string; /** - * - Events triggering the webhook. Possible values for - * **Transactional** type webhook: #### `sent` OR `request`, - * `delivered`, `hardBounce`, `softBounce`, `blocked`, `spam`, - * `invalid`, `deferred`, `click`, `opened`, `uniqueOpened` and - * `unsubscribed` - Possible values for **Marketing** type webhook: - * #### `spam`, `opened`, `click`, `hardBounce`, `softBounce`, - * `unsubscribed`, `listAddition` & `delivered` - Possible values - * for **Inbound** type webhook: #### `inboundEmailProcessed` - - * Possible values for type **Transactional** and channel **SMS** - * #### - * `accepted`,`delivered`,`softBounce`,`hardBounce`,`unsubscribe`,`reply`, - * `subscribe`,`sent`,`blacklisted`,`skip` - Possible values for - * type **Marketing** channel **SMS** #### - * `sent`,`delivered`,`softBounce`,`hardBounce`,`unsubscribe`,`reply`, - * `subscribe`,`skip` - * #### `reply` + * Events triggering the webhook. Required for transactional and + * marketing types, optional for inbound type (defaults to + * `inboundEmailProcessed`). Possible values for **Transactional** + * type webhook: `sent` OR `request`, `delivered`, `hardBounce`, + * `softBounce`, `blocked`, `spam`, `invalid`, `deferred`, `click`, + * `opened`, `uniqueOpened` and `unsubscribed`. Possible values for + * **Marketing** type webhook: `spam`, `opened`, `click`, + * `hardBounce`, `softBounce`, `unsubscribed`, `listAddition`, + * `delivered`, `contactUpdated` & `contactDeleted`. Possible values + * for **Inbound** type webhook: `inboundEmailProcessed`. */ - events: CreateWebhookRequest.Events.Item[]; + events?: CreateWebhookRequest.Events.Item[]; /** Custom headers to be send with webhooks */ headers?: CreateWebhookRequest.Headers.Item[]; /** Type of the webhook */ @@ -59,10 +52,10 @@ export namespace CreateWebhookRequest { type?: string | undefined; } - /** channel of webhook */ + /** Channel of the webhook */ export const Channel = { - Sms: "sms", Email: "email", + Sms: "sms", } as const; export type Channel = (typeof Channel)[keyof typeof Channel]; export type Events = Events.Item[]; diff --git a/src/api/resources/webhooks/client/requests/ExportWebhooksHistoryRequest.ts b/src/api/resources/webhooks/client/requests/ExportWebhooksHistoryRequest.ts index 354c438..39943b6 100644 --- a/src/api/resources/webhooks/client/requests/ExportWebhooksHistoryRequest.ts +++ b/src/api/resources/webhooks/client/requests/ExportWebhooksHistoryRequest.ts @@ -27,7 +27,7 @@ export interface ExportWebhooksHistoryRequest { * Filter the history for a specific message id. Applicable * only for transactional webhooks. */ - messageId?: number; + messageId?: string; /** Webhook URL to receive CSV file link */ notifyURL: string; /** Sorting order of records (asc or desc) */ diff --git a/src/api/resources/whatsAppCampaigns/client/Client.ts b/src/api/resources/whatsAppCampaigns/client/Client.ts index aa9e3b8..af60c91 100644 --- a/src/api/resources/whatsAppCampaigns/client/Client.ts +++ b/src/api/resources/whatsAppCampaigns/client/Client.ts @@ -23,6 +23,8 @@ export class WhatsAppCampaignsClient { } /** + * Retrieve a paginated list of all your WhatsApp campaigns with their statistics and metadata. Results can be filtered by creation date range using startDate and endDate, with a default limit of 50 and maximum of 100 per page. The sort order defaults to descending by modification date. + * * @param {Brevo.GetWhatsAppCampaignsRequest} request * @param {WhatsAppCampaignsClient.RequestOptions} requestOptions - Request-specific configuration. * @@ -65,7 +67,11 @@ export class WhatsAppCampaignsClient { ), method: "GET", headers: _headers, - queryParameters: { ..._queryParams, ...requestOptions?.queryParams }, + queryString: core.url + .queryBuilder() + .addMany(_queryParams) + .mergeAdditional(requestOptions?.queryParams) + .build(), timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, abortSignal: requestOptions?.abortSignal, @@ -139,7 +145,7 @@ export class WhatsAppCampaignsClient { method: "POST", headers: _headers, contentType: "application/json", - queryParameters: requestOptions?.queryParams, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), requestType: "json", body: request, timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, @@ -203,7 +209,7 @@ export class WhatsAppCampaignsClient { ), method: "GET", headers: _headers, - queryParameters: requestOptions?.queryParams, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, abortSignal: requestOptions?.abortSignal, @@ -274,7 +280,7 @@ export class WhatsAppCampaignsClient { method: "POST", headers: _headers, contentType: "application/json", - queryParameters: requestOptions?.queryParams, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), requestType: "json", body: request, timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, @@ -304,6 +310,8 @@ export class WhatsAppCampaignsClient { } /** + * Retrieve a paginated list of all your WhatsApp templates with their status, category, language, and metadata. Results can be filtered by creation date range and optionally by source (Automation or Conversations), with a default limit of 50 and maximum of 100 per page. The sort order defaults to descending by modification date. + * * @param {Brevo.GetWhatsAppTemplatesRequest} request * @param {WhatsAppCampaignsClient.RequestOptions} requestOptions - Request-specific configuration. * @@ -347,7 +355,11 @@ export class WhatsAppCampaignsClient { ), method: "GET", headers: _headers, - queryParameters: { ..._queryParams, ...requestOptions?.queryParams }, + queryString: core.url + .queryBuilder() + .addMany(_queryParams) + .mergeAdditional(requestOptions?.queryParams) + .build(), timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, abortSignal: requestOptions?.abortSignal, @@ -420,7 +432,7 @@ export class WhatsAppCampaignsClient { ), method: "POST", headers: _headers, - queryParameters: requestOptions?.queryParams, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, abortSignal: requestOptions?.abortSignal, @@ -497,7 +509,7 @@ export class WhatsAppCampaignsClient { ), method: "GET", headers: _headers, - queryParameters: requestOptions?.queryParams, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, abortSignal: requestOptions?.abortSignal, @@ -576,7 +588,7 @@ export class WhatsAppCampaignsClient { method: "PUT", headers: _headers, contentType: "application/json", - queryParameters: requestOptions?.queryParams, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), requestType: "json", body: _body, timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, @@ -611,6 +623,8 @@ export class WhatsAppCampaignsClient { } /** + * Delete a WhatsApp campaign by its campaign ID. The campaign must exist; if the campaign ID is not found, a 404 error is returned. This action is permanent and cannot be undone. + * * @param {Brevo.DeleteWhatsAppCampaignRequest} request * @param {WhatsAppCampaignsClient.RequestOptions} requestOptions - Request-specific configuration. * @@ -649,7 +663,7 @@ export class WhatsAppCampaignsClient { ), method: "DELETE", headers: _headers, - queryParameters: requestOptions?.queryParams, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, abortSignal: requestOptions?.abortSignal, diff --git a/src/api/resources/whatsAppCampaigns/types/GetWhatsAppCampaignResponse.ts b/src/api/resources/whatsAppCampaigns/types/GetWhatsAppCampaignResponse.ts index 81b80ef..c5b8eec 100644 --- a/src/api/resources/whatsAppCampaigns/types/GetWhatsAppCampaignResponse.ts +++ b/src/api/resources/whatsAppCampaigns/types/GetWhatsAppCampaignResponse.ts @@ -15,6 +15,8 @@ export interface GetWhatsAppCampaignResponse { modifiedAt: string; /** UTC date-time on which WhatsApp campaign is scheduled. Should be in YYYY-MM-DDTHH:mm:ss.SSSZ format */ scheduledAt?: string | undefined; + /** Recipients of the WhatsApp Campaign */ + recipients: GetWhatsAppCampaignResponse.Recipients; /** Sender of the WhatsApp Campaign */ senderNumber: string; stats?: Brevo.WhatsappCampStats | undefined; @@ -35,6 +37,20 @@ export namespace GetWhatsAppCampaignResponse { } as const; export type CampaignStatus = (typeof CampaignStatus)[keyof typeof CampaignStatus]; + /** + * Recipients of the WhatsApp Campaign + */ + export interface Recipients { + /** List of excluded list IDs */ + excludedLists?: number[] | undefined; + /** List of included list IDs */ + includedLists?: number[] | undefined; + /** List of segment IDs */ + segments?: number[] | undefined; + /** Type of recipients (list or segment) */ + type?: string | undefined; + } + export interface Template { /** array of variables item variables */ body_variables?: Brevo.VariablesItems[] | undefined; diff --git a/src/api/resources/whatsAppCampaigns/types/GetWhatsAppTemplatesResponse.ts b/src/api/resources/whatsAppCampaigns/types/GetWhatsAppTemplatesResponse.ts index d4ab0d9..ddef796 100644 --- a/src/api/resources/whatsAppCampaigns/types/GetWhatsAppTemplatesResponse.ts +++ b/src/api/resources/whatsAppCampaigns/types/GetWhatsAppTemplatesResponse.ts @@ -27,6 +27,8 @@ export namespace GetWhatsAppTemplatesResponse { name: string; /** Status of the whatsApp template */ status: string; + /** Type of the whatsApp template */ + type: string; } } } diff --git a/src/api/types/BalanceDefinition.ts b/src/api/types/BalanceDefinition.ts index 7cf72c3..f4a08cf 100644 --- a/src/api/types/BalanceDefinition.ts +++ b/src/api/types/BalanceDefinition.ts @@ -1,54 +1,107 @@ // This file was auto-generated by Fern from our API Definition. export interface BalanceDefinition { - /** startOfPeriod depicts the balancy expiry on start of day/week/month/year. endOfPeriod depicts the balancy expiry on end of day/week/month/year */ - balanceAvailabilityDurationModifier?: BalanceDefinition.BalanceAvailabilityDurationModifier | undefined; - /** Unit of time for the balance's availability (e.g., day/week/month/year). */ - balanceAvailabilityDurationUnit?: string | undefined; - /** Number of days/weeks/month/year for balance expiry */ - balanceAvailabilityDurationValue?: number | undefined; - /** Date when the balance expires and can no longer be used, in dd/mm format. The balance will be expired when this date appears next in the calendar and only one of balanceExpirationDate or balance availability fields can be used. */ - balanceExpirationDate?: string | undefined; - /** Partial enables partial credit of balance if maximum balance limit is reaching. Strict enables rejection of transaction if it will breach the max credit amount limit. */ - balanceOptionAmountOvertakingStrategy?: string | undefined; - /** Rounding strategy for credit transactions. */ - balanceOptionCreditRounding?: string | undefined; - /** Rounding strategy for debit transactions. */ - balanceOptionDebitRounding?: string | undefined; - /** Timestamp of balance definition creation. */ - createdAt?: string | undefined; - /** Timestamp of balance definition deletion (nullable). */ - deletedAt?: string | undefined; - /** Short description of the balance definition. */ - description?: string | undefined; /** Unique identifier for the balance definition. */ id?: string | undefined; + /** Name of the balance definition. */ + name?: string | undefined; + /** Short description of the balance definition. */ + description?: string | undefined; /** Optional image reference URL. */ imageRef?: string | undefined; - /** Maximum allowable balance. */ - maxAmount?: number | undefined; - /** Max credit allowed per operation. */ - maxCreditAmountLimit?: number | undefined; - /** Max debit allowed per operation. */ - maxDebitAmountLimit?: number | undefined; /** Additional metadata for the balance definition. */ meta?: Record | undefined; + /** Unit of balance measurement. */ + unit?: BalanceDefinition.Unit | undefined; /** Minimum allowable balance. */ minAmount?: number | undefined; - /** Name of the balance definition. */ - name?: string | undefined; - /** Unit of balance (e.g., points, currency). */ - unit?: string | undefined; + /** Maximum allowable balance. */ + maxAmount?: number | undefined; + /** Maximum credit allowed per operation. */ + maxCreditAmountLimit?: number | undefined; + /** Maximum debit allowed per operation. */ + maxDebitAmountLimit?: number | undefined; + /** Partial enables partial credit of balance if maximum balance limit is reached. Strict enables rejection of a transaction if it will breach the max balance limit. */ + balanceOptionAmountOvertakingStrategy?: BalanceDefinition.BalanceOptionAmountOvertakingStrategy | undefined; + /** Rounding strategy for credit transactions. */ + balanceOptionCreditRounding?: BalanceDefinition.BalanceOptionCreditRounding | undefined; + /** Rounding strategy for debit transactions. */ + balanceOptionDebitRounding?: BalanceDefinition.BalanceOptionDebitRounding | undefined; + /** Number of time units before the balance expires. */ + balanceAvailabilityDurationValue?: number | undefined; + /** Unit of time for the balance availability duration. */ + balanceAvailabilityDurationUnit?: BalanceDefinition.BalanceAvailabilityDurationUnit | undefined; + /** Modifier for balance availability duration. startOfPeriod causes expiry at the start of the period, endOfPeriod at the end. noModification uses the exact duration from the credit date. */ + balanceAvailabilityDurationModifier?: BalanceDefinition.BalanceAvailabilityDurationModifier | undefined; + /** Fixed expiration date in dd/mm format. The balance expires when this date next appears in the calendar. Only one of balanceExpirationDate or balance availability duration fields can be used. */ + balanceExpirationDate?: string | undefined; + /** Timestamp of balance definition creation. */ + createdAt?: string | undefined; /** Timestamp of the last update. */ updatedAt?: string | undefined; + /** Timestamp of balance definition deletion (nullable). */ + deletedAt?: string | undefined; } export namespace BalanceDefinition { - /** startOfPeriod depicts the balancy expiry on start of day/week/month/year. endOfPeriod depicts the balancy expiry on end of day/week/month/year */ + /** Unit of balance measurement. */ + export const Unit = { + Points: "POINTS", + Eur: "EUR", + Usd: "USD", + Mxn: "MXN", + Gbp: "GBP", + Inr: "INR", + Cad: "CAD", + Sgd: "SGD", + Ron: "RON", + Jpy: "JPY", + Myr: "MYR", + Clp: "CLP", + Pen: "PEN", + Mad: "MAD", + Aud: "AUD", + Chf: "CHF", + Brl: "BRL", + } as const; + export type Unit = (typeof Unit)[keyof typeof Unit]; + /** Partial enables partial credit of balance if maximum balance limit is reached. Strict enables rejection of a transaction if it will breach the max balance limit. */ + export const BalanceOptionAmountOvertakingStrategy = { + Strict: "strict", + Partial: "partial", + } as const; + export type BalanceOptionAmountOvertakingStrategy = + (typeof BalanceOptionAmountOvertakingStrategy)[keyof typeof BalanceOptionAmountOvertakingStrategy]; + /** Rounding strategy for credit transactions. */ + export const BalanceOptionCreditRounding = { + Lower: "lower", + Upper: "upper", + Natural: "natural", + } as const; + export type BalanceOptionCreditRounding = + (typeof BalanceOptionCreditRounding)[keyof typeof BalanceOptionCreditRounding]; + /** Rounding strategy for debit transactions. */ + export const BalanceOptionDebitRounding = { + Lower: "lower", + Upper: "upper", + Natural: "natural", + } as const; + export type BalanceOptionDebitRounding = + (typeof BalanceOptionDebitRounding)[keyof typeof BalanceOptionDebitRounding]; + /** Unit of time for the balance availability duration. */ + export const BalanceAvailabilityDurationUnit = { + Day: "day", + Week: "week", + Month: "month", + Year: "year", + } as const; + export type BalanceAvailabilityDurationUnit = + (typeof BalanceAvailabilityDurationUnit)[keyof typeof BalanceAvailabilityDurationUnit]; + /** Modifier for balance availability duration. startOfPeriod causes expiry at the start of the period, endOfPeriod at the end. noModification uses the exact duration from the credit date. */ export const BalanceAvailabilityDurationModifier = { + NoModification: "noModification", StartOfPeriod: "startOfPeriod", EndOfPeriod: "endOfPeriod", - NoModification: "noModification", } as const; export type BalanceAvailabilityDurationModifier = (typeof BalanceAvailabilityDurationModifier)[keyof typeof BalanceAvailabilityDurationModifier]; diff --git a/src/api/types/BalanceLimit.ts b/src/api/types/BalanceLimit.ts index 4706149..ba55f3e 100644 --- a/src/api/types/BalanceLimit.ts +++ b/src/api/types/BalanceLimit.ts @@ -1,24 +1,48 @@ // This file was auto-generated by Fern from our API Definition. export interface BalanceLimit { - /** balance definition ID */ + /** Unique identifier for the balance limit. */ + id?: string | undefined; + /** Balance definition ID. */ balanceDefinitionId?: string | undefined; - /** Defines the type of constraint (e.g., transaction-based or amount-based). */ - constraintType?: string | undefined; - /** Timestamp of when the balance limit was created. */ - createdAt: string; - /** Time unit for the balance limit (day, week, month, year). */ - durationUnit?: string | undefined; + /** Specifies whether the limit applies to credit or debit transactions. */ + transactionType?: BalanceLimit.TransactionType | undefined; + /** Defines the type of constraint (transaction count or amount). */ + constraintType?: BalanceLimit.ConstraintType | undefined; /** Number of time units the balance limit applies to. */ durationValue?: number | undefined; - /** Unique identifier for the balance limit. */ - id?: string | undefined; + /** Time unit for the balance limit. */ + durationUnit?: BalanceLimit.DurationUnit | undefined; + /** The maximum allowed value for the defined constraint. */ + value?: number | undefined; /** Indicates if the limit resets periodically based on a sliding schedule. */ slidingSchedule?: boolean | undefined; - /** Specifies whether the limit applies to credit or debit transactions. */ - transactionType?: string | undefined; + /** Timestamp of when the balance limit was created. */ + createdAt?: string | undefined; /** Timestamp of the last update to the balance limit. */ - updatedAt: string; - /** The maximum allowed value for the defined constraint. */ - value?: number | undefined; + updatedAt?: string | undefined; +} + +export namespace BalanceLimit { + /** Specifies whether the limit applies to credit or debit transactions. */ + export const TransactionType = { + Credit: "credit", + Debit: "debit", + } as const; + export type TransactionType = (typeof TransactionType)[keyof typeof TransactionType]; + /** Defines the type of constraint (transaction count or amount). */ + export const ConstraintType = { + Transaction: "transaction", + Amount: "amount", + } as const; + export type ConstraintType = (typeof ConstraintType)[keyof typeof ConstraintType]; + /** Time unit for the balance limit. */ + export const DurationUnit = { + Hour: "hour", + Day: "day", + Week: "week", + Month: "month", + Year: "year", + } as const; + export type DurationUnit = (typeof DurationUnit)[keyof typeof DurationUnit]; } diff --git a/src/api/types/Company.ts b/src/api/types/Company.ts index d5a58d3..1823c02 100644 --- a/src/api/types/Company.ts +++ b/src/api/types/Company.ts @@ -10,6 +10,6 @@ export interface Company { id?: string | undefined; /** Contact ids for contacts linked to this company */ linkedContactsIds?: number[] | undefined; - /** Deals ids for companies linked to this company */ + /** Deal ids for deals linked to this company */ linkedDealsIds?: string[] | undefined; } diff --git a/src/api/types/ConversationsMessage.ts b/src/api/types/ConversationsMessage.ts index b56c13c..d521e66 100644 --- a/src/api/types/ConversationsMessage.ts +++ b/src/api/types/ConversationsMessage.ts @@ -55,6 +55,14 @@ export interface ConversationsMessage { to?: ConversationsMessage.To.Item[] | undefined; /** `"agent"` for agents’ messages, `"visitor"` for visitors’ messages. */ type?: ConversationsMessage.Type | undefined; + /** ‘`true` if the message was sent via JavaScript API.’ */ + isSentViaJsApi?: boolean | undefined; + /** The type of message content (e.g. for integration-specific message types). */ + messageType?: string | undefined; + /** ‘`true` if the message is a forwarded message.’ */ + isForward?: boolean | undefined; + /** Source information for the message. */ + source?: Record | undefined; /** visitor’s ID */ visitorId?: string | undefined; } @@ -65,17 +73,39 @@ export namespace ConversationsMessage { export namespace Attachments { export interface Item { /** The name of the file. */ - fileName?: string | undefined; - /** The ID of the inline file. */ - inlineId?: string | undefined; + name?: string | undefined; + /** The URL of the file. */ + link?: string | undefined; + /** The MIME type of the file. */ + mimeType?: string | undefined; /** `true` for images. */ isImage?: boolean | undefined; + /** `true` for sticker files. */ + isSticker?: boolean | undefined; /** `true` for inline files. */ - isInline?: string | undefined; + isInline?: boolean | undefined; + /** The ID of the inline file. */ + inlineId?: string | undefined; /** The size of the file in bytes. */ size?: number | undefined; - /** The URL of the file. */ - url?: string | undefined; + /** Image information (only present for image files). */ + imageInfo?: Item.ImageInfo | undefined; + /** Whether the file extension is allowed for download. */ + isAllowedFileType?: boolean | undefined; + } + + export namespace Item { + /** + * Image information (only present for image files). + */ + export interface ImageInfo { + /** Width of the image in pixels. */ + width?: number | undefined; + /** Height of the image in pixels. */ + height?: number | undefined; + /** URL of the image preview. */ + previewLink?: string | undefined; + } } } @@ -98,29 +128,39 @@ export namespace ConversationsMessage { } export interface File_ { - /** Name of the file */ - filename?: string | undefined; - /** image info is passed in case the file is an image */ - imageInfo?: File_.ImageInfo | undefined; - /** Whether the file is an image */ + /** Name of the file. */ + name?: string | undefined; + /** URL of the file. */ + link?: string | undefined; + /** MIME type of the file. */ + mimeType?: string | undefined; + /** Whether the file is an image. */ isImage?: boolean | undefined; - /** Size in bytes */ + /** Whether the file is a sticker. */ + isSticker?: boolean | undefined; + /** Whether the file is inline. */ + isInline?: boolean | undefined; + /** The ID of the inline file. */ + inlineId?: string | undefined; + /** Size in bytes. */ size?: number | undefined; - /** URL of the file */ - url?: string | undefined; + /** Image info, present when the file is an image. */ + imageInfo?: File_.ImageInfo | undefined; + /** Whether the file extension is allowed for download. */ + isAllowedFileType?: boolean | undefined; } export namespace File_ { /** - * image info is passed in case the file is an image + * Image info, present when the file is an image. */ export interface ImageInfo { - /** height of the image */ - height?: number | undefined; - /** URL of the preview */ - previewUrl?: string | undefined; - /** Width of the image */ + /** Width of the image in pixels. */ width?: number | undefined; + /** Height of the image in pixels. */ + height?: number | undefined; + /** URL of the image preview. */ + previewLink?: string | undefined; } } diff --git a/src/api/types/Deal.ts b/src/api/types/Deal.ts index a0ad470..6afd225 100644 --- a/src/api/types/Deal.ts +++ b/src/api/types/Deal.ts @@ -4,12 +4,12 @@ * Deal Details */ export interface Deal { - /** Deal attributes with values */ - attributes?: Record | undefined; /** Unique deal id */ id?: string | undefined; - /** Companies ids for companies linked to this deal */ - linkedCompaniesIds?: string[] | undefined; + /** Deal attributes with values */ + attributes?: Record | undefined; /** Contact ids for contacts linked to this deal */ linkedContactsIds?: number[] | undefined; + /** Companies ids for companies linked to this deal */ + linkedCompaniesIds?: string[] | undefined; } diff --git a/src/api/types/FileData.ts b/src/api/types/FileData.ts index f528215..8d77a36 100644 --- a/src/api/types/FileData.ts +++ b/src/api/types/FileData.ts @@ -4,18 +4,20 @@ * File data that is uploaded */ export interface FileData { + /** Unique file id */ + id?: string | undefined; + /** Name of uploaded file */ + name?: string | undefined; /** Account id of user which created the file */ authorId?: string | undefined; - /** Company id linked to a file */ - companyId?: string | undefined; /** Contact id of contact on which file is uploaded */ contactId?: number | undefined; - /** File created date/time */ - createdAt?: string | undefined; /** Deal id linked to a file */ dealId?: string | undefined; - /** Name of uploaded file */ - name?: string | undefined; + /** Company id linked to a file */ + companyId?: string | undefined; /** Size of file in bytes */ size?: number | undefined; + /** File created date/time */ + createdAt?: string | undefined; } diff --git a/src/api/types/GetCampaignRecipients.ts b/src/api/types/GetCampaignRecipients.ts index 975fe8e..ecd745e 100644 --- a/src/api/types/GetCampaignRecipients.ts +++ b/src/api/types/GetCampaignRecipients.ts @@ -1,6 +1,10 @@ // This file was auto-generated by Fern from our API Definition. export interface GetCampaignRecipients { + /** Segment IDs excluded from the campaign */ + excludedSegments?: number[] | undefined; exclusionLists: number[]; lists: number[]; + /** Segment IDs included in the campaign */ + segments?: number[] | undefined; } diff --git a/src/api/types/GetCampaignStats.ts b/src/api/types/GetCampaignStats.ts index 76f44c9..9f34aac 100644 --- a/src/api/types/GetCampaignStats.ts +++ b/src/api/types/GetCampaignStats.ts @@ -11,9 +11,9 @@ export interface GetCampaignStats { deferred?: number | undefined; /** Number of delivered emails for the campaign */ delivered: number; - /** Rate of recipients without any privacy protection option enabled in their email client_dev, applied to all delivered emails */ + /** Rate of recipients without any privacy protection option enabled in their email client, applied to all delivered emails */ estimatedViews?: number | undefined; - /** Number of harbounce for the campaign */ + /** Number of hard bounces for the campaign */ hardBounces: number; /** List Id of email campaign (only in case of get email campaign(s)(not for global stats)) */ listId?: number | undefined; @@ -25,9 +25,9 @@ export interface GetCampaignStats { sent: number; /** Number of softbounce for the campaign */ softBounces: number; - /** Recipients without any privacy protection option enabled in their email client_dev */ + /** Recipients without any privacy protection option enabled in their email email client */ trackableViews: number; - /** Rate of recipients without any privacy protection option enabled in their email client_dev */ + /** Rate of recipients without any privacy protection option enabled in their email client */ trackableViewsRate?: number | undefined; /** Number of unique clicks for the campaign */ uniqueClicks: number; diff --git a/src/api/types/GetContactDetails.ts b/src/api/types/GetContactDetails.ts index 124eb51..a6b854e 100644 --- a/src/api/types/GetContactDetails.ts +++ b/src/api/types/GetContactDetails.ts @@ -17,6 +17,8 @@ export interface GetContactDetails { modifiedAt: string; /** Blacklist status for SMS campaigns (true=blacklisted, false=not blacklisted) */ smsBlacklisted: boolean; + /** Blacklist status for WhatsApp campaigns (true=blacklisted, false=not blacklisted) */ + whatsappBlacklisted: boolean; } export namespace GetContactDetails { diff --git a/src/api/types/GetEventsList.ts b/src/api/types/GetEventsList.ts index 5388d5d..9427184 100644 --- a/src/api/types/GetEventsList.ts +++ b/src/api/types/GetEventsList.ts @@ -23,8 +23,6 @@ export namespace GetEventsList { event_name?: string | undefined; /** Filter ID of the event */ event_filter_id?: string | undefined; - /** Source of the event */ - source?: string | undefined; /** Object type associated with the event */ object_type?: string | undefined; /** Event-level custom properties */ diff --git a/src/api/types/GetExtendedCampaignOverview.ts b/src/api/types/GetExtendedCampaignOverview.ts index 114e7e6..caecd00 100644 --- a/src/api/types/GetExtendedCampaignOverview.ts +++ b/src/api/types/GetExtendedCampaignOverview.ts @@ -31,8 +31,12 @@ export interface GetExtendedCampaignOverview { winnerCriteria?: string | undefined; /** The duration of the test in hours at the end of which the winning version will be sent. Only available if `abTesting` flag of the campaign is `true` */ winnerDelay?: number | undefined; + /** URL of the attachment file associated with the campaign. Empty string if no attachment is present. */ + attachmentUrl?: string | undefined; /** Creation UTC date-time of the campaign (YYYY-MM-DDTHH:mm:ss.SSSZ) */ createdAt: string; + /** Expiration date configuration for the email campaign, if set. Contains the duration and unit of the email expiry. */ + emailExpirationDate?: GetExtendedCampaignOverview.EmailExpirationDate | undefined; /** Footer of the campaign */ footer: string; /** Header of the campaign */ @@ -54,7 +58,7 @@ export interface GetExtendedCampaignOverview { sender: GetExtendedCampaignOverview.Sender; /** Sent UTC date-time of the campaign (YYYY-MM-DDTHH:mm:ss.SSSZ). Only available if 'status' of the campaign is 'sent' */ sentDate?: string | undefined; - /** Link to share the campaign on social medias */ + /** Link to share the campaign on social media. For trigger campaigns, this returns a descriptive message instead of a URL. For classic campaigns that have not been sent, this also returns a descriptive message. */ shareLink?: string | undefined; /** Tag of the campaign */ tag?: string | undefined; @@ -64,12 +68,13 @@ export interface GetExtendedCampaignOverview { testSent: boolean; /** Customisation of the "to" field of the campaign */ toField?: string | undefined; - /** utm parameter associated with campaign */ + /** The utm_campaign value associated with the campaign. Only present if a UTM campaign value was set. */ utmCampaignValue?: string | undefined; - /** utm id active */ - utmIDActive?: boolean | undefined; + /** The campaign ID used as utm_id parameter. Only present if UTM campaign tracking with ID is enabled. */ + utmID?: number | undefined; + /** The utm_medium value. Set to "EMAIL" when UTM campaign tracking is enabled. */ utmMedium?: string | undefined; - /** source of utm */ + /** The utm_source value. Set to "Brevo" when UTM campaign tracking is enabled. */ utmSource?: string | undefined; } @@ -94,6 +99,26 @@ export namespace GetExtendedCampaignOverview { } as const; export type Type = (typeof Type)[keyof typeof Type]; + /** + * Expiration date configuration for the email campaign, if set. Contains the duration and unit of the email expiry. + */ + export interface EmailExpirationDate { + /** Duration of the email expiry */ + duration?: number | undefined; + /** Unit of the duration */ + unit?: EmailExpirationDate.Unit | undefined; + } + + export namespace EmailExpirationDate { + /** Unit of the duration */ + export const Unit = { + Days: "days", + Weeks: "weeks", + Months: "months", + } as const; + export type Unit = (typeof Unit)[keyof typeof Unit]; + } + export interface Sender { /** Sender email of the campaign */ email?: string | undefined; diff --git a/src/api/types/GetExtendedCampaignStats.ts b/src/api/types/GetExtendedCampaignStats.ts index 7f8b3fb..348b68e 100644 --- a/src/api/types/GetExtendedCampaignStats.ts +++ b/src/api/types/GetExtendedCampaignStats.ts @@ -7,23 +7,20 @@ export interface GetExtendedCampaignStats { campaignStats: Brevo.GetCampaignStats[]; /** Overall statistics of the campaign */ globalStats: Brevo.GetCampaignStats; - /** Statistics about the number of clicks for the links */ - linksStats: GetExtendedCampaignStats.LinksStats; + /** Statistics about the number of clicks for each link in the campaign. Keys are the link URLs, values are click counts. Only populated when the `statistics` query parameter is set to `linksStats`. */ + linksStats: Record; /** Number of clicks on mirror link */ mirrorClick: number; - /** Number of remaning emails to send */ + /** Number of remaining emails to send */ remaining: number; - statsByBrowser: Record; - statsByDevice: GetExtendedCampaignStats.StatsByDevice; - statsByDomain: Record; + /** Statistics of the campaign grouped by browser. Only available when retrieving a single campaign with the `statistics` query parameter set to `statsByBrowser`. */ + statsByBrowser?: Record | undefined; + statsByDevice?: GetExtendedCampaignStats.StatsByDevice | undefined; + /** Statistics of the campaign grouped by email domain. Only populated when the `statistics` query parameter is set to `statsByDomain`. */ + statsByDomain?: Record | undefined; } export namespace GetExtendedCampaignStats { - /** - * Statistics about the number of clicks for the links - */ - export type LinksStats = {}; - export interface StatsByDevice { /** Statistics of the campaign on the basis of desktop devices */ desktop?: Record | undefined; diff --git a/src/api/types/GetProductDetails.ts b/src/api/types/GetProductDetails.ts index ae430f8..8b948d2 100644 --- a/src/api/types/GetProductDetails.ts +++ b/src/api/types/GetProductDetails.ts @@ -13,7 +13,7 @@ export interface GetProductDetails { id: string; /** Absolute URL to the cover image of the product */ imageUrl?: string | undefined; - /** Product get deleted from the shop's database but not from Brevo */ + /** Product deleted from the shop's database but not from Brevo */ isDeleted?: boolean | undefined; /** Meta data of product such as description, vendor, producer, stock level, etc. */ metaInfo?: Record | undefined; @@ -25,6 +25,8 @@ export interface GetProductDetails { parentId?: string | undefined; /** Price of the product */ price?: number | undefined; + /** Alternative price of the product */ + alternativePrice?: number | undefined; /** S3 url of original image */ s3Original?: string | undefined; /** S3 thumbnail url of original image in 120x120 dimension for analytics section */ diff --git a/src/api/types/GetSmsCampaignOverview.ts b/src/api/types/GetSmsCampaignOverview.ts index 0339585..69bf580 100644 --- a/src/api/types/GetSmsCampaignOverview.ts +++ b/src/api/types/GetSmsCampaignOverview.ts @@ -11,12 +11,18 @@ export interface GetSmsCampaignOverview { modifiedAt: string; /** Name of the SMS Campaign */ name: string; - /** UTC date-time on which SMS campaign is scheduled. Should be in YYYY-MM-DDTHH:mm:ss.SSSZ format */ + /** A recognizable prefix added as the Brand Name before the message content. Empty string if not set. */ + organisationPrefix?: string | undefined; + /** UTC date-time on which SMS campaign is scheduled. Should be in YYYY-MM-DDTHH:mm:ss.SSSZ format. Empty string if not scheduled. */ scheduledAt?: string | undefined; /** Sender of the SMS Campaign */ sender: string; + /** UTC date-time on which the SMS campaign was sent (YYYY-MM-DDTHH:mm:ss.SSSZ). Only available if the campaign status is 'sent'. */ + sentDate?: string | undefined; /** Status of the SMS Campaign */ status: GetSmsCampaignOverview.Status; + /** Instructions to unsubscribe from future communications. Empty string if not set. */ + unsubscribeInstruction?: string | undefined; } export namespace GetSmsCampaignOverview { diff --git a/src/api/types/GetSmtpTemplateOverview.ts b/src/api/types/GetSmtpTemplateOverview.ts index 156e587..58bf0b6 100644 --- a/src/api/types/GetSmtpTemplateOverview.ts +++ b/src/api/types/GetSmtpTemplateOverview.ts @@ -26,6 +26,8 @@ export interface GetSmtpTemplateOverview { testSent: boolean; /** Customisation of the "to" field for the template */ toField: string; + /** Custom template identifier, if one was assigned during template creation. Only present when the template has a custom ID. */ + customTemplateId?: string | undefined; } export namespace GetSmtpTemplateOverview { @@ -34,7 +36,7 @@ export namespace GetSmtpTemplateOverview { email?: string | undefined; /** Sender id of the template */ id?: string | undefined; - /** From email for the template */ + /** Sender name for the template */ name?: string | undefined; } } diff --git a/src/api/types/GetWebhook.ts b/src/api/types/GetWebhook.ts index 15afb08..d79902f 100644 --- a/src/api/types/GetWebhook.ts +++ b/src/api/types/GetWebhook.ts @@ -8,8 +8,6 @@ export interface GetWebhook { * true */ batched?: boolean | undefined; - /** channel of webhook */ - channel?: GetWebhook.Channel | undefined; /** Creation UTC date-time of the webhook (YYYY-MM-DDTHH:mm:ss.SSSZ) */ createdAt: string; /** Description of the webhook */ @@ -20,23 +18,20 @@ export interface GetWebhook { id: number; /** Last modification UTC date-time of the webhook (YYYY-MM-DDTHH:mm:ss.SSSZ) */ modifiedAt: string; - /** Type of webhook (marketing or transactional) */ + /** Type of webhook (marketing, transactional, or inbound) */ type: GetWebhook.Type; + /** Inbound domain of the webhook, only returned for inbound type webhooks */ + domain?: string | undefined; /** URL of the webhook */ url: string; } export namespace GetWebhook { - /** channel of webhook */ - export const Channel = { - Sms: "sms", - Email: "email", - } as const; - export type Channel = (typeof Channel)[keyof typeof Channel]; - /** Type of webhook (marketing or transactional) */ + /** Type of webhook (marketing, transactional, or inbound) */ export const Type = { Marketing: "marketing", Transactional: "transactional", + Inbound: "inbound", } as const; export type Type = (typeof Type)[keyof typeof Type]; } diff --git a/src/api/types/LoyaltyProgram.ts b/src/api/types/LoyaltyProgram.ts index 19a675b..d77d673 100644 --- a/src/api/types/LoyaltyProgram.ts +++ b/src/api/types/LoyaltyProgram.ts @@ -1,37 +1,40 @@ // This file was auto-generated by Fern from our API Definition. export interface LoyaltyProgram { - /** Loyalty Program code count */ - codeCount?: number | undefined; - /** Loyalty Program creation date */ - createdAt?: string | undefined; - /** Loyalty Program description */ - description?: string | undefined; - /** string */ - documentId?: string | undefined; - /** Loyalty Program ID */ + /** Loyalty Program unique identifier. */ id?: string | undefined; - /** Loyalty Program meta data */ - meta?: Record | undefined; - /** Loyalty Program name */ + /** Loyalty Program name. */ name?: string | undefined; - /** string */ - pattern?: string | undefined; - /** Loyalty Program state */ + /** Loyalty Program description. */ + description?: string | undefined; + /** Loyalty Program metadata. */ + meta?: Record | undefined; + /** Current state of the loyalty program. */ state?: LoyaltyProgram.State | undefined; - /** Loyalty Program subscription generator ID */ - subscriptionGeneratorId?: string | undefined; - /** Loyalty Program subscription pool ID */ + /** Loyalty Program subscription pool ID. */ subscriptionPoolId?: string | undefined; - /** Loyalty Program last modification date */ + /** Loyalty Program subscription generator ID. */ + subscriptionGeneratorId?: string | undefined; + /** Subscription code pattern. */ + pattern?: string | undefined; + /** Number of available subscription codes. */ + codeCount?: number | undefined; + /** Associated document identifier. */ + documentId?: string | undefined; + /** Contact attribute name used for birthday tracking. */ + birthdayAttribute?: string | undefined; + /** Timestamp when the loyalty program was created. */ + createdAt?: string | undefined; + /** Timestamp when the loyalty program was last modified. */ updatedAt?: string | undefined; } export namespace LoyaltyProgram { - /** Loyalty Program state */ + /** Current state of the loyalty program. */ export const State = { Inactive: "inactive", Active: "active", + Draft: "draft", } as const; export type State = (typeof State)[keyof typeof State]; } diff --git a/src/api/types/Note.ts b/src/api/types/Note.ts index e2dc39d..b178f0b 100644 --- a/src/api/types/Note.ts +++ b/src/api/types/Note.ts @@ -4,18 +4,20 @@ * Note Details */ export interface Note { - /** Account details of user which created the note */ - authorId?: Record | undefined; + /** Unique note Id */ + id?: string | undefined; + /** Content of the note. Supports HTML for rich text formatting. Supported tags include: `

` (paragraph), `` / `` (bold), `` / `` (italic), `` (underline), `
` (line break), `` (labelled hyperlink). Example labelled link: `Link text`. */ + text: string; /** Contact ids linked to a note */ contactIds?: number[] | undefined; - /** Note created date/time */ - createdAt?: string | undefined; + /** Company ids linked to a note */ + companyIds?: string[] | undefined; /** Deal ids linked to a note */ dealIds?: string[] | undefined; - /** Unique note Id */ - id?: string | undefined; - /** Text content of a note */ - text: string; + /** Account details of user which created the note */ + authorId?: Record | undefined; + /** Note created date/time */ + createdAt?: string | undefined; /** Note updated date/time */ updatedAt?: string | undefined; } diff --git a/src/api/types/NoteData.ts b/src/api/types/NoteData.ts index 7d9df9e..dcfc9e3 100644 --- a/src/api/types/NoteData.ts +++ b/src/api/types/NoteData.ts @@ -10,6 +10,6 @@ export interface NoteData { contactIds?: number[] | undefined; /** Deal Ids linked to a note */ dealIds?: string[] | undefined; - /** Text content of a note */ + /** Content of the note. Supports HTML for rich text formatting. Supported tags include: `

` (paragraph), `` / `` (bold), `` / `` (italic), `` (underline), `
` (line break), `` (labelled hyperlink). Example labelled link: `Link text`. */ text: string; } diff --git a/src/api/types/Order.ts b/src/api/types/Order.ts index 34a51e7..9b6646f 100644 --- a/src/api/types/Order.ts +++ b/src/api/types/Order.ts @@ -13,7 +13,7 @@ export interface Order { id: string; /** Identifies the contact associated with the order. */ identifiers?: Order.Identifiers | undefined; - /** Meta data of order to store additional detal such as custom message, customer type, source. */ + /** Meta data of order to store additional detail such as custom message, customer type, source. */ metaInfo?: Record | undefined; products: Order.Products.Item[]; /** State of the order. */ diff --git a/src/api/types/Pipeline.ts b/src/api/types/Pipeline.ts index 72551f5..d43e5ae 100644 --- a/src/api/types/Pipeline.ts +++ b/src/api/types/Pipeline.ts @@ -1,14 +1,14 @@ // This file was auto-generated by Fern from our API Definition. /** - * List of stages + * Pipeline details with stages */ export interface Pipeline { /** Pipeline id */ pipeline?: string | undefined; /** Pipeline Name */ pipeline_name?: string | undefined; - /** List of stages */ + /** List of pipeline stages */ stages?: Pipeline.Stages.Item[] | undefined; } @@ -17,7 +17,7 @@ export namespace Pipeline { export namespace Stages { /** - * List of stages + * Stage details */ export interface Item { /** Stage id */ diff --git a/src/api/types/SendTransacSms.ts b/src/api/types/SendTransacSms.ts index ed8686c..14b0024 100644 --- a/src/api/types/SendTransacSms.ts +++ b/src/api/types/SendTransacSms.ts @@ -3,11 +3,11 @@ export interface SendTransacSms { /** A recognizable prefix will ensure your audience knows who you are. Recommended by U.S. carriers. This will be added as your Brand Name before the message content. **Prefer verifying maximum length of 160 characters including this prefix in message content to avoid multiple sending of same sms.** */ organisationPrefix?: string | undefined; - /** Mobile number to send SMS with the country code */ + /** Mobile number to send SMS with the country code. Must contain between 6 and 15 digits, optionally prefixed with '+'. */ recipient: string; - /** Name of the sender. **The number of characters is limited to 11 for alphanumeric characters and 15 for numeric characters** */ + /** Name of the sender. **The number of characters is limited to 11 for alphanumeric characters and 15 for numeric characters.** Alphanumeric sender names (up to 11 characters) must contain only letters and digits. Numeric sender names (12-15 characters) must contain only digits. */ sender: string; - /** Tag of the message */ + /** Tag of the message. Can be a single string or an array of strings (maximum 10 tags). Each tag must be a non-empty string. */ tag?: SendTransacSms.Tag | undefined; /** Type of the SMS. Marketing SMS messages are those sent typically with marketing content. Transactional SMS messages are sent to individuals and are triggered in response to some action, such as a sign-up, purchase, etc. */ type?: SendTransacSms.Type | undefined; @@ -15,6 +15,8 @@ export interface SendTransacSms { unicodeEnabled?: boolean | undefined; /** Webhook to call for each event triggered by the message (delivered etc.) */ webUrl?: string | undefined; + /** Pass the set of attributes to customize the template. For example, {"FNAME":"Joe", "LNAME":"Doe"}. These are the placeholder variables in the template that will be replaced with the corresponding values passed in the params object. Applicable only if `templateId` is used. */ + params?: Record | undefined; /** Template ID to send SMS with the template. When provided, overrides the content parameter. Mandatory if 'content' is not passed. */ templateId?: number | undefined; /** Content of the message. If more than **160 characters** long, will be sent as multiple text messages. Mandatory if 'templateId' is not passed, ignored if 'templateId' is passed. */ @@ -23,20 +25,9 @@ export interface SendTransacSms { export namespace SendTransacSms { /** - * Tag of the message + * Tag of the message. Can be a single string or an array of strings (maximum 10 tags). Each tag must be a non-empty string. */ - export interface Tag { - /** A tag can be a string or an array of strings. */ - field?: Tag.Field | undefined; - } - - export namespace Tag { - /** - * A tag can be a string or an array of strings. - */ - export type Field = string | string[]; - } - + export type Tag = string | string[]; /** Type of the SMS. Marketing SMS messages are those sent typically with marketing content. Transactional SMS messages are sent to individuals and are triggered in response to some action, such as a sign-up, purchase, etc. */ export const Type = { Transactional: "transactional", diff --git a/src/api/types/Task.ts b/src/api/types/Task.ts index 455b6ab..7743987 100644 --- a/src/api/types/Task.ts +++ b/src/api/types/Task.ts @@ -4,16 +4,28 @@ * Task Details */ export interface Task { - /** Companies ids for companies a task is linked to */ - companiesIds?: string[] | undefined; - /** Contact ids for contacts linked to this task */ - contactsIds?: number[] | undefined; - /** Deal ids for deals a task is linked to */ - dealsIds?: string[] | undefined; /** Unique task id */ id?: string | undefined; - /** Name of task */ - name: string; /** Id for type of task e.g Call / Email / Meeting etc. */ taskTypeId: string; + /** Name of task */ + name: string; + /** Companies ids for companies a task is linked to */ + companiesIds?: string[] | undefined; + /** Deal ids for deals a task is linked to */ + dealsIds?: string[] | undefined; + /** Contact ids for contacts linked to this task */ + contactsIds?: number[] | undefined; + /** Account id of the user assigned to this task */ + assignToId?: string | undefined; + /** Task due date and time */ + date: string; + /** Notes added to a task */ + notes?: string | undefined; + /** Whether the task is marked as done */ + done?: boolean | undefined; + /** Task creation date/time */ + createdAt?: string | undefined; + /** Task last update date/time */ + updatedAt?: string | undefined; } diff --git a/src/api/types/TierGroup.ts b/src/api/types/TierGroup.ts index 758f977..9f23e76 100644 --- a/src/api/types/TierGroup.ts +++ b/src/api/types/TierGroup.ts @@ -17,6 +17,10 @@ export interface TierGroup { updatedAt?: string | undefined; /** Select real_time to upgrade tier on real time balance updates. Select membership_anniversary to upgrade tier on subscription anniversary. Select tier_anniversary to upgrade tier on tier anniversary. */ upgradeStrategy?: TierGroup.UpgradeStrategy | undefined; + /** Schedule configuration for tier upgrades. */ + upgradeSchedule?: TierGroup.UpgradeSchedule | undefined; + /** Schedule configuration for tier downgrades. */ + downgradeSchedule?: TierGroup.DowngradeSchedule | undefined; } export namespace TierGroup { @@ -34,4 +38,70 @@ export namespace TierGroup { TierAnniversary: "tier_anniversary", } as const; export type UpgradeStrategy = (typeof UpgradeStrategy)[keyof typeof UpgradeStrategy]; + + /** + * Schedule configuration for tier upgrades. + */ + export interface UpgradeSchedule { + /** Schedule strategy type. */ + strategy?: string | undefined; + /** Duration value for the schedule. */ + durationValue?: number | undefined; + /** Duration unit for the schedule. */ + durationUnit?: UpgradeSchedule.DurationUnit | undefined; + /** Modifier for the duration. */ + durationModifier?: UpgradeSchedule.DurationModifier | undefined; + /** Scheduled date in DD/MM format. */ + scheduledDate?: string | undefined; + } + + export namespace UpgradeSchedule { + /** Duration unit for the schedule. */ + export const DurationUnit = { + Day: "day", + Week: "week", + Month: "month", + Year: "year", + } as const; + export type DurationUnit = (typeof DurationUnit)[keyof typeof DurationUnit]; + /** Modifier for the duration. */ + export const DurationModifier = { + StartOfPeriod: "start_of_period", + EndOfPeriod: "end_of_period", + } as const; + export type DurationModifier = (typeof DurationModifier)[keyof typeof DurationModifier]; + } + + /** + * Schedule configuration for tier downgrades. + */ + export interface DowngradeSchedule { + /** Schedule strategy type. */ + strategy?: string | undefined; + /** Duration value for the schedule. */ + durationValue?: number | undefined; + /** Duration unit for the schedule. */ + durationUnit?: DowngradeSchedule.DurationUnit | undefined; + /** Modifier for the duration. */ + durationModifier?: DowngradeSchedule.DurationModifier | undefined; + /** Scheduled date in DD/MM format. */ + scheduledDate?: string | undefined; + } + + export namespace DowngradeSchedule { + /** Duration unit for the schedule. */ + export const DurationUnit = { + Day: "day", + Week: "week", + Month: "month", + Year: "year", + } as const; + export type DurationUnit = (typeof DurationUnit)[keyof typeof DurationUnit]; + /** Modifier for the duration. */ + export const DurationModifier = { + StartOfPeriod: "start_of_period", + EndOfPeriod: "end_of_period", + } as const; + export type DurationModifier = (typeof DurationModifier)[keyof typeof DurationModifier]; + } } diff --git a/src/api/types/Transaction.ts b/src/api/types/Transaction.ts index 48a8675..1050fc2 100644 --- a/src/api/types/Transaction.ts +++ b/src/api/types/Transaction.ts @@ -4,34 +4,54 @@ * Represents a transaction involving a balance, including status and timestamps. */ export interface Transaction { + /** Unique identifier (UUID) of the transaction. */ + id?: string | undefined; /** The transaction amount. */ amount?: number | undefined; + /** The type of the transaction. */ + transactionType?: Transaction.TransactionType | undefined; + /** Optional metadata associated with the transaction. */ + meta?: Record | undefined; + /** The current status of the transaction. */ + status?: Transaction.Status | undefined; + /** Unique identifier (UUID) of the associated loyalty program. */ + loyaltyProgramId?: string | undefined; /** Unique identifier (UUID) of the associated balance definition. */ balanceDefinitionId?: string | undefined; - /** Timestamp when the transaction was canceled (nullable). */ - cancelledAt?: string | undefined; - /** Timestamp when the transaction was completed (nullable). */ - completedAt?: string | undefined; /** Unique identifier of the contact associated with the transaction. */ contactId?: number | undefined; - /** Timestamp when the transaction was created. */ - createdAt?: string | undefined; - /** Optional timestamp indicating when the transaction event occurred. */ + /** Optional timestamp indicating when the transaction event occurred (ISO 8601 format). */ eventTime?: string | undefined; - /** Expiry date of the transaction (nullable). */ - expirationDate?: string | undefined; - /** Unique identifier (UUID) of the transaction. */ - id?: string | undefined; - /** Unique identifier (UUID) of the associated loyalty program. */ - loyaltyProgramId?: string | undefined; - /** Optional metadata associated with the transaction. */ - meta?: Record | undefined; /** Reason for rejection if the transaction was declined (nullable). */ rejectReason?: string | undefined; /** Timestamp when the transaction was rejected (nullable). */ rejectedAt?: string | undefined; - /** The current status of the transaction (e.g., pending, completed, rejected). */ - status?: string | undefined; + /** Expiry date of the transaction (nullable). */ + expirationDate?: string | undefined; + /** Timestamp when the transaction was completed (nullable). */ + completedAt?: string | undefined; + /** Timestamp when the transaction was canceled (nullable). */ + cancelledAt?: string | undefined; + /** Timestamp when the transaction was created. */ + createdAt?: string | undefined; /** Timestamp when the transaction was last updated. */ updatedAt?: string | undefined; } + +export namespace Transaction { + /** The type of the transaction. */ + export const TransactionType = { + Credit: "credit", + Debit: "debit", + } as const; + export type TransactionType = (typeof TransactionType)[keyof typeof TransactionType]; + /** The current status of the transaction. */ + export const Status = { + Pending: "pending", + Complete: "complete", + Rejected: "rejected", + Cancelled: "cancelled", + Expired: "expired", + } as const; + export type Status = (typeof Status)[keyof typeof Status]; +} diff --git a/src/core/auth/AuthProvider.ts b/src/core/auth/AuthProvider.ts index 895a50f..c947866 100644 --- a/src/core/auth/AuthProvider.ts +++ b/src/core/auth/AuthProvider.ts @@ -4,3 +4,12 @@ import type { AuthRequest } from "./AuthRequest.js"; export interface AuthProvider { getAuthRequest(arg?: { endpointMetadata?: EndpointMetadata }): Promise; } + +export function isAuthProvider(value: unknown): value is AuthProvider { + return ( + typeof value === "object" && + value !== null && + "getAuthRequest" in value && + typeof value.getAuthRequest === "function" + ); +} diff --git a/src/core/auth/index.ts b/src/core/auth/index.ts index 2215b22..77effd0 100644 --- a/src/core/auth/index.ts +++ b/src/core/auth/index.ts @@ -1,4 +1,4 @@ -export type { AuthProvider } from "./AuthProvider.js"; +export { type AuthProvider, isAuthProvider } from "./AuthProvider.js"; export type { AuthRequest } from "./AuthRequest.js"; export { BasicAuth } from "./BasicAuth.js"; export { BearerToken } from "./BearerToken.js"; diff --git a/src/core/fetcher/Fetcher.ts b/src/core/fetcher/Fetcher.ts index 928dfea..943ec1b 100644 --- a/src/core/fetcher/Fetcher.ts +++ b/src/core/fetcher/Fetcher.ts @@ -21,7 +21,13 @@ export declare namespace Fetcher { method: string; contentType?: string; headers?: Record; + /** + * @deprecated Prefer `queryString` (produced by `core.url.queryBuilder()`). + * Retained for backwards compatibility with custom fetchers and callers that + * still construct request args with a query-parameter object. + */ queryParameters?: Record; + queryString?: string; body?: unknown; timeoutMs?: number; maxRetries?: number; @@ -118,17 +124,15 @@ const SENSITIVE_QUERY_PARAMS = new Set([ "session-id", ]); -function redactQueryParameters(queryParameters?: Record): Record | undefined { +function redactQueryParameters( + queryParameters: Record | undefined, +): Record | undefined { if (queryParameters == null) { - return queryParameters; + return undefined; } const redacted: Record = {}; for (const [key, value] of Object.entries(queryParameters)) { - if (SENSITIVE_QUERY_PARAMS.has(key.toLowerCase())) { - redacted[key] = "[REDACTED]"; - } else { - redacted[key] = value; - } + redacted[key] = SENSITIVE_QUERY_PARAMS.has(key.toLowerCase()) ? "[REDACTED]" : value; } return redacted; } @@ -251,7 +255,12 @@ async function getHeaders(args: Fetcher.Args): Promise { } export async function fetcherImpl(args: Fetcher.Args): Promise> { - const url = createRequestUrl(args.url, args.queryParameters); + let url = args.url; + if (args.queryString != null && args.queryString.length > 0) { + url = `${url}?${args.queryString}`; + } else { + url = createRequestUrl(args.url, args.queryParameters); + } const requestBody: BodyInit | undefined = await getRequestBody({ body: args.body, type: args.requestType ?? "other", diff --git a/src/core/fetcher/requestWithRetries.ts b/src/core/fetcher/requestWithRetries.ts index 1f68968..5e66b93 100644 --- a/src/core/fetcher/requestWithRetries.ts +++ b/src/core/fetcher/requestWithRetries.ts @@ -3,6 +3,10 @@ const MAX_RETRY_DELAY = 60000; // in milliseconds const DEFAULT_MAX_RETRIES = 2; const JITTER_FACTOR = 0.2; // 20% random jitter +function isRetryableStatusCode(statusCode: number): boolean { + return [408, 429].includes(statusCode) || statusCode >= 500; +} + function addPositiveJitter(delay: number): number { const jitterMultiplier = 1 + Math.random() * JITTER_FACTOR; return delay * jitterMultiplier; @@ -51,7 +55,7 @@ export async function requestWithRetries( let response: Response = await requestFn(); for (let i = 0; i < maxRetries; ++i) { - if ([408, 429].includes(response.status) || response.status >= 500) { + if (isRetryableStatusCode(response.status)) { const delay = getRetryDelayFromHeaders(response, i); await new Promise((resolve) => setTimeout(resolve, delay)); diff --git a/src/core/url/QueryStringBuilder.ts b/src/core/url/QueryStringBuilder.ts new file mode 100644 index 0000000..b045221 --- /dev/null +++ b/src/core/url/QueryStringBuilder.ts @@ -0,0 +1,87 @@ +import { toQueryString } from "./qs.js"; + +/** + * Creates a fluent builder for constructing URL query strings. + * + * Each `.add()` call serializes its value immediately (like C#'s builder), + * so no format tracking is needed — the style is applied at add-time. + * + * Usage (generated code): + * + * const qs = core.url.queryBuilder() + * .add("limit", limit) + * .add("tags", tags, { style: "comma" }) // explode: false + * .mergeAdditional(requestOptions?.queryParams) + * .build(); + */ +export function queryBuilder(): QueryStringBuilder { + return new QueryStringBuilder(); +} + +class QueryStringBuilder { + private parts: Map = new Map(); + + /** + * Adds a query parameter, serializing it immediately. + * + * By default arrays use "repeat" format (`key=a&key=b`). + * Pass `{ style: "comma" }` for OpenAPI `explode: false` parameters + * to get comma-separated values (`key=a,b,c`). + * + * Null / undefined values are silently skipped. + */ + add(key: string, value: unknown, options?: { style?: "comma" }): this { + if (value === undefined || value === null) { + return this; + } + const serialized = toQueryString( + { [key]: value }, + { arrayFormat: options?.style === "comma" ? "comma" : "repeat" }, + ); + if (serialized.length > 0) { + this.parts.set(key, serialized); + } + return this; + } + + /** + * Adds multiple query parameters at once from a record. + * All parameters use the default "repeat" array format. + * Null / undefined values are silently skipped. + */ + addMany(params: Record): this { + if (params != null) { + for (const [key, value] of Object.entries(params)) { + this.add(key, value); + } + } + return this; + } + + /** + * Merges additional query parameters supplied at call-time via + * `requestOptions.queryParams`. Overrides existing keys (last-write-wins). + */ + mergeAdditional(additionalParams?: Record): this { + if (additionalParams != null) { + for (const [key, value] of Object.entries(additionalParams)) { + if (value === undefined || value === null) { + continue; + } + const serialized = toQueryString({ [key]: value }, { arrayFormat: "repeat" }); + if (serialized.length > 0) { + this.parts.set(key, serialized); + } + } + } + return this; + } + + /** + * Returns the assembled query string (without the leading `?`). + * Returns an empty string when no parameters were added. + */ + build(): string { + return [...this.parts.values()].join("&"); + } +} diff --git a/src/core/url/index.ts b/src/core/url/index.ts index f2e0fa2..ca9d4fb 100644 --- a/src/core/url/index.ts +++ b/src/core/url/index.ts @@ -1,3 +1,4 @@ export { encodePathParam } from "./encodePathParam.js"; export { join } from "./join.js"; +export { queryBuilder } from "./QueryStringBuilder.js"; export { toQueryString } from "./qs.js"; diff --git a/src/core/url/qs.ts b/src/core/url/qs.ts index 13e89be..f8b4556 100644 --- a/src/core/url/qs.ts +++ b/src/core/url/qs.ts @@ -1,5 +1,7 @@ +type ArrayFormat = "indices" | "repeat" | "comma"; + interface QueryStringOptions { - arrayFormat?: "indices" | "repeat"; + arrayFormat?: ArrayFormat; encode?: boolean; } @@ -33,18 +35,29 @@ function stringifyObject(obj: Record, prefix = "", options: Req if (value.length === 0) { continue; } - for (let i = 0; i < value.length; i++) { - const item = value[i]; - if (item === undefined) { - continue; + const effectiveFormat = options.arrayFormat; + if (effectiveFormat === "comma") { + const encodedKey = options.encode ? encodeURIComponent(fullKey) : fullKey; + const encodedValues = value + .filter((item) => item !== undefined && item !== null) + .map((item) => encodeValue(item, options.encode)); + if (encodedValues.length > 0) { + parts.push(`${encodedKey}=${encodedValues.join(",")}`); } - if (typeof item === "object" && !Array.isArray(item) && item !== null) { - const arrayKey = options.arrayFormat === "indices" ? `${fullKey}[${i}]` : fullKey; - parts.push(...stringifyObject(item as Record, arrayKey, options)); - } else { - const arrayKey = options.arrayFormat === "indices" ? `${fullKey}[${i}]` : fullKey; - const encodedKey = options.encode ? encodeURIComponent(arrayKey) : arrayKey; - parts.push(`${encodedKey}=${encodeValue(item, options.encode)}`); + } else { + for (let i = 0; i < value.length; i++) { + const item = value[i]; + if (item === undefined) { + continue; + } + if (typeof item === "object" && !Array.isArray(item) && item !== null) { + const arrayKey = effectiveFormat === "indices" ? `${fullKey}[${i}]` : fullKey; + parts.push(...stringifyObject(item as Record, arrayKey, options)); + } else { + const arrayKey = effectiveFormat === "indices" ? `${fullKey}[${i}]` : fullKey; + const encodedKey = options.encode ? encodeURIComponent(arrayKey) : arrayKey; + parts.push(`${encodedKey}=${encodeValue(item, options.encode)}`); + } } } } else if (typeof value === "object" && value !== null) { diff --git a/src/version.ts b/src/version.ts index cbd547a..7ba3a93 100644 --- a/src/version.ts +++ b/src/version.ts @@ -1 +1 @@ -export const SDK_VERSION = "5.0.4"; +export const SDK_VERSION = "6.0.0"; diff --git a/tests/unit/fetcher/createRequestUrl.test.ts b/tests/unit/fetcher/createRequestUrl.test.ts index a92f1b5..f8afeaf 100644 --- a/tests/unit/fetcher/createRequestUrl.test.ts +++ b/tests/unit/fetcher/createRequestUrl.test.ts @@ -160,4 +160,8 @@ describe("Test createRequestUrl", () => { expect(createRequestUrl(baseUrl, queryParams)).toBe(expected); }); }); + + it("should default to repeat format for arrays", () => { + expect(createRequestUrl(BASE_URL, { items: ["a", "b"] })).toBe("https://api.example.com?items=a&items=b"); + }); }); diff --git a/tests/unit/fetcher/makePassthroughRequest.test.ts b/tests/unit/fetcher/makePassthroughRequest.test.ts index 1850d1f..cb8f226 100644 --- a/tests/unit/fetcher/makePassthroughRequest.test.ts +++ b/tests/unit/fetcher/makePassthroughRequest.test.ts @@ -246,7 +246,7 @@ describe("makePassthroughRequest", () => { }); it("should use requestOptions maxRetries over client maxRetries", async () => { - mockFetch.mockResolvedValue(new Response("", { status: 500 })); + mockFetch.mockResolvedValue(new Response("", { status: 502 })); vi.spyOn(global, "setTimeout").mockImplementation((callback: (args: void) => void) => { process.nextTick(callback); return null as any; diff --git a/tests/unit/fetcher/redacting.test.ts b/tests/unit/fetcher/redacting.test.ts index d599376..685f1dd 100644 --- a/tests/unit/fetcher/redacting.test.ts +++ b/tests/unit/fetcher/redacting.test.ts @@ -703,6 +703,112 @@ describe("Redacting Logic", () => { }); }); + describe("Query String Redaction", () => { + it("should redact api_key in queryString via URL", async () => { + const mockLogger = createMockLogger(); + mockSuccessResponse(); + + await fetcherImpl({ + url: "https://example.com/api", + method: "GET", + queryString: "api_key=secret-key&page=1", + responseType: "json", + maxRetries: 0, + logging: { + level: "debug", + logger: mockLogger, + silent: false, + }, + }); + + expect(mockLogger.debug).toHaveBeenCalledWith( + "Making HTTP request", + expect.objectContaining({ + url: "https://example.com/api?api_key=[REDACTED]&page=1", + }), + ); + }); + + it("should redact multiple sensitive params in queryString", async () => { + const mockLogger = createMockLogger(); + mockSuccessResponse(); + + await fetcherImpl({ + url: "https://example.com/api", + method: "GET", + queryString: "token=t&password=p&page=1", + responseType: "json", + maxRetries: 0, + logging: { + level: "debug", + logger: mockLogger, + silent: false, + }, + }); + + expect(mockLogger.debug).toHaveBeenCalledWith( + "Making HTTP request", + expect.objectContaining({ + url: "https://example.com/api?token=[REDACTED]&password=[REDACTED]&page=1", + }), + ); + }); + + it("should not redact non-sensitive params in queryString", async () => { + const mockLogger = createMockLogger(); + mockSuccessResponse(); + + await fetcherImpl({ + url: "https://example.com/api", + method: "GET", + queryString: "page=1&limit=10&sort=name", + responseType: "json", + maxRetries: 0, + logging: { + level: "debug", + logger: mockLogger, + silent: false, + }, + }); + + expect(mockLogger.debug).toHaveBeenCalledWith( + "Making HTTP request", + expect.objectContaining({ + url: "https://example.com/api?page=1&limit=10&sort=name", + }), + ); + }); + + it("should prefer queryString over queryParameters when both provided", async () => { + const mockLogger = createMockLogger(); + mockSuccessResponse(); + + await fetcherImpl({ + url: "https://example.com/api", + method: "GET", + queryString: "page=1", + queryParameters: { api_key: "secret-key" }, + responseType: "json", + maxRetries: 0, + logging: { + level: "debug", + logger: mockLogger, + silent: false, + }, + }); + + expect(mockLogger.debug).toHaveBeenCalledWith( + "Making HTTP request", + expect.objectContaining({ + url: "https://example.com/api?page=1", + queryParameters: expect.objectContaining({ + api_key: "[REDACTED]", + }), + }), + ); + }); + }); + describe("URL Redaction", () => { it("should redact credentials in URL", async () => { const mockLogger = createMockLogger(); diff --git a/tests/unit/fetcher/requestWithRetries.test.ts b/tests/unit/fetcher/requestWithRetries.test.ts index d226613..7c98c0a 100644 --- a/tests/unit/fetcher/requestWithRetries.test.ts +++ b/tests/unit/fetcher/requestWithRetries.test.ts @@ -36,13 +36,13 @@ describe("requestWithRetries", () => { vi.clearAllTimers(); }); - it("should retry on retryable status codes", async () => { + it("should retry on retryable status codes (legacy mode)", async () => { setTimeoutSpy = vi.spyOn(global, "setTimeout").mockImplementation((callback: (args: void) => void) => { process.nextTick(callback); return null as any; }); - const retryableStatuses = [408, 429, 500, 502]; + const retryableStatuses = [408, 429, 500, 501, 502, 503, 504, 505]; let callCount = 0; mockFetch.mockImplementation(async () => { @@ -60,6 +60,24 @@ describe("requestWithRetries", () => { expect(response.status).toBe(200); }); + it("should retry on 500 Internal Server Error in legacy mode", async () => { + setTimeoutSpy = vi.spyOn(global, "setTimeout").mockImplementation((callback: (args: void) => void) => { + process.nextTick(callback); + return null as any; + }); + + mockFetch + .mockResolvedValueOnce(new Response("", { status: 500 })) + .mockResolvedValueOnce(new Response("", { status: 200 })); + + const responsePromise = requestWithRetries(() => mockFetch(), 3); + await vi.runAllTimersAsync(); + const response = await responsePromise; + + expect(mockFetch).toHaveBeenCalledTimes(2); + expect(response.status).toBe(200); + }); + it("should respect maxRetries limit", async () => { setTimeoutSpy = vi.spyOn(global, "setTimeout").mockImplementation((callback: (args: void) => void) => { process.nextTick(callback); @@ -67,14 +85,48 @@ describe("requestWithRetries", () => { }); const maxRetries = 2; - mockFetch.mockResolvedValue(new Response("", { status: 500 })); + mockFetch.mockResolvedValue(new Response("", { status: 503 })); const responsePromise = requestWithRetries(() => mockFetch(), maxRetries); await vi.runAllTimersAsync(); const response = await responsePromise; expect(mockFetch).toHaveBeenCalledTimes(maxRetries + 1); - expect(response.status).toBe(500); + expect(response.status).toBe(503); + }); + + it("should retry on status 599 (upper boundary of retryable 5xx in legacy mode)", async () => { + setTimeoutSpy = vi.spyOn(global, "setTimeout").mockImplementation((callback: (args: void) => void) => { + process.nextTick(callback); + return null as any; + }); + + mockFetch + .mockResolvedValueOnce(new Response("", { status: 599 })) + .mockResolvedValueOnce(new Response("", { status: 200 })); + + const responsePromise = requestWithRetries(() => mockFetch(), 3); + await vi.runAllTimersAsync(); + const response = await responsePromise; + + expect(mockFetch).toHaveBeenCalledTimes(2); + expect(response.status).toBe(200); + }); + + it("should not retry on non-retryable client error (400)", async () => { + setTimeoutSpy = vi.spyOn(global, "setTimeout").mockImplementation((callback: (args: void) => void) => { + process.nextTick(callback); + return null as any; + }); + + mockFetch.mockResolvedValueOnce(new Response("", { status: 400 })); + + const responsePromise = requestWithRetries(() => mockFetch(), 3); + await vi.runAllTimersAsync(); + const response = await responsePromise; + + expect(mockFetch).toHaveBeenCalledTimes(1); + expect(response.status).toBe(400); }); it("should not retry on success status codes", async () => { @@ -166,7 +218,7 @@ describe("requestWithRetries", () => { return null as any; }); - mockFetch.mockResolvedValue(new Response("", { status: 500 })); + mockFetch.mockResolvedValue(new Response("", { status: 502 })); const maxRetries = 3; const expectedDelays = [1000, 2000, 4000]; @@ -190,8 +242,8 @@ describe("requestWithRetries", () => { }); mockFetch - .mockResolvedValueOnce(new Response("", { status: 500 })) - .mockResolvedValueOnce(new Response("", { status: 500 })) + .mockResolvedValueOnce(new Response("", { status: 502 })) + .mockResolvedValueOnce(new Response("", { status: 502 })) .mockResolvedValueOnce(new Response("", { status: 200 })) .mockResolvedValueOnce(new Response("", { status: 200 })); diff --git a/tests/unit/url/QueryStringBuilder.test.ts b/tests/unit/url/QueryStringBuilder.test.ts new file mode 100644 index 0000000..1afa2d2 --- /dev/null +++ b/tests/unit/url/QueryStringBuilder.test.ts @@ -0,0 +1,236 @@ +import { queryBuilder } from "../../../src/core/url/QueryStringBuilder"; + +describe("QueryStringBuilder", () => { + describe("add() — default repeat format", () => { + it("adds a scalar string value", () => { + const qs = queryBuilder().add("key", "value").build(); + expect(qs).toBe("key=value"); + }); + + it("adds a scalar number value", () => { + const qs = queryBuilder().add("limit", 10).build(); + expect(qs).toBe("limit=10"); + }); + + it("adds a boolean value", () => { + const qs = queryBuilder().add("active", true).build(); + expect(qs).toBe("active=true"); + }); + + it("skips undefined values", () => { + const qs = queryBuilder().add("key", undefined).build(); + expect(qs).toBe(""); + }); + + it("skips null values", () => { + const qs = queryBuilder().add("key", null).build(); + expect(qs).toBe(""); + }); + + it("repeats array elements as separate key=value pairs", () => { + const qs = queryBuilder().add("color", ["red", "blue", "green"]).build(); + expect(qs).toBe("color=red&color=blue&color=green"); + }); + + it("skips undefined items within arrays", () => { + const qs = queryBuilder().add("color", ["red", undefined, "blue"]).build(); + expect(qs).toBe("color=red&color=blue"); + }); + + it("returns empty string for empty array", () => { + const qs = queryBuilder().add("color", []).build(); + expect(qs).toBe(""); + }); + + it("encodes special characters in keys and values", () => { + const qs = queryBuilder().add("my key", "hello world").build(); + expect(qs).toBe("my%20key=hello%20world"); + }); + + it("handles nested objects", () => { + const qs = queryBuilder().add("filter", { status: "active" }).build(); + expect(qs).toBe("filter%5Bstatus%5D=active"); + }); + }); + + describe("add() — comma style", () => { + it("joins array values with literal commas", () => { + const qs = queryBuilder().add("tags", ["a", "b", "c"], { style: "comma" }).build(); + expect(qs).toBe("tags=a,b,c"); + }); + + it("handles single-element array", () => { + const qs = queryBuilder().add("tags", ["only"], { style: "comma" }).build(); + expect(qs).toBe("tags=only"); + }); + + it("returns empty string for empty array", () => { + const qs = queryBuilder().add("tags", [], { style: "comma" }).build(); + expect(qs).toBe(""); + }); + + it("skips undefined values", () => { + const qs = queryBuilder().add("tags", undefined, { style: "comma" }).build(); + expect(qs).toBe(""); + }); + + it("skips null values", () => { + const qs = queryBuilder().add("tags", null, { style: "comma" }).build(); + expect(qs).toBe(""); + }); + + it("treats scalar values same as default add()", () => { + const qs = queryBuilder().add("tag", "single", { style: "comma" }).build(); + expect(qs).toBe("tag=single"); + }); + + it("encodes commas within individual values as %2C", () => { + const qs = queryBuilder().add("items", ["a,b", "c"], { style: "comma" }).build(); + expect(qs).toBe("items=a%2Cb,c"); + }); + + it("encodes special characters in values", () => { + const qs = queryBuilder().add("tags", ["hello world", "foo&bar"], { style: "comma" }).build(); + expect(qs).toBe("tags=hello%20world,foo%26bar"); + }); + }); + + describe("chaining", () => { + it("chains multiple add() calls", () => { + const qs = queryBuilder().add("limit", 10).add("offset", 20).build(); + expect(qs).toBe("limit=10&offset=20"); + }); + + it("chains add() with default and comma styles", () => { + const qs = queryBuilder() + .add("limit", 10) + .add("tags", ["ACCESS_GRANTED", "COPY", "DELETE"], { style: "comma" }) + .add("active", true) + .build(); + expect(qs).toBe("limit=10&tags=ACCESS_GRANTED,COPY,DELETE&active=true"); + }); + + it("skips undefined/null params in chain without breaking", () => { + const qs = queryBuilder() + .add("a", "1") + .add("b", undefined) + .add("c", null, { style: "comma" }) + .add("d", "4") + .build(); + expect(qs).toBe("a=1&d=4"); + }); + }); + + describe("addMany()", () => { + it("adds all params from a record", () => { + const qs = queryBuilder().addMany({ limit: 10, offset: 20, name: "test" }).build(); + expect(qs).toBe("limit=10&offset=20&name=test"); + }); + + it("skips null and undefined values", () => { + const qs = queryBuilder().addMany({ a: "1", b: null, c: undefined, d: "4" }).build(); + expect(qs).toBe("a=1&d=4"); + }); + + it("handles empty record", () => { + const qs = queryBuilder().addMany({}).build(); + expect(qs).toBe(""); + }); + + it("works with comma-style override after addMany", () => { + const params = { limit: 10, tags: ["a", "b"], active: true }; + const qs = queryBuilder().addMany(params).add("tags", params.tags, { style: "comma" }).build(); + expect(qs).toBe("limit=10&tags=a,b&active=true"); + }); + + it("handles array values with default repeat format", () => { + const qs = queryBuilder() + .addMany({ ids: [1, 2, 3] }) + .build(); + expect(qs).toBe("ids=1&ids=2&ids=3"); + }); + }); + + describe("mergeAdditional()", () => { + it("appends additional params", () => { + const qs = queryBuilder().add("limit", 10).mergeAdditional({ extra: "value" }).build(); + expect(qs).toBe("limit=10&extra=value"); + }); + + it("overrides existing keys (last-write-wins)", () => { + const qs = queryBuilder().add("limit", 10).mergeAdditional({ limit: 20 }).build(); + expect(qs).toBe("limit=20"); + }); + + it("handles undefined additional params", () => { + const qs = queryBuilder().add("limit", 10).mergeAdditional(undefined).build(); + expect(qs).toBe("limit=10"); + }); + + it("skips undefined values in additional params", () => { + const qs = queryBuilder().add("limit", 10).mergeAdditional({ extra: undefined }).build(); + expect(qs).toBe("limit=10"); + }); + + it("skips null values in additional params", () => { + const qs = queryBuilder().add("limit", 10).mergeAdditional({ extra: null }).build(); + expect(qs).toBe("limit=10"); + }); + + it("handles array values in additional params using repeat format", () => { + const qs = queryBuilder() + .mergeAdditional({ ids: [1, 2, 3] }) + .build(); + expect(qs).toBe("ids=1&ids=2&ids=3"); + }); + + it("overrides a comma-style param with repeat format", () => { + const qs = queryBuilder() + .add("tags", ["a", "b"], { style: "comma" }) + .mergeAdditional({ tags: ["x", "y"] }) + .build(); + expect(qs).toBe("tags=x&tags=y"); + }); + }); + + describe("build()", () => { + it("returns empty string when no params added", () => { + const qs = queryBuilder().build(); + expect(qs).toBe(""); + }); + + it("does not include leading ?", () => { + const qs = queryBuilder().add("key", "value").build(); + expect(qs).not.toContain("?"); + }); + }); + + describe("end-to-end scenarios", () => { + it("matches expected query-parameters-openapi output pattern", () => { + const params: Record = { + limit: 1, + id: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32", + date: "2023-01-15", + deadline: "2024-01-15T09:30:00.000Z", + bytes: "SGVsbG8gd29ybGQh", + user: "user", + userList: ["user"], + optionalString: "optionalString", + nestedUser: "nestedUser", + excludeUser: "excludeUser", + filter: "filter", + tags: ["tags"], + optionalTags: undefined, + }; + const qs = queryBuilder() + .addMany(params) + .add("tags", params.tags, { style: "comma" }) + .add("optionalTags", params.optionalTags, { style: "comma" }) + .mergeAdditional(undefined) + .build(); + expect(qs).toContain("limit=1"); + expect(qs).toContain("tags=tags"); + expect(qs).not.toContain("optionalTags"); + }); + }); +}); diff --git a/tests/unit/url/qs.test.ts b/tests/unit/url/qs.test.ts index 42cdffb..1099b95 100644 --- a/tests/unit/url/qs.test.ts +++ b/tests/unit/url/qs.test.ts @@ -34,7 +34,7 @@ describe("Test qs toQueryString", () => { interface ArrayTestCase { description: string; input: any; - options?: { arrayFormat?: "repeat" | "indices" }; + options?: { arrayFormat?: "repeat" | "indices" | "comma" }; expected: string; } @@ -150,7 +150,7 @@ describe("Test qs toQueryString", () => { interface MixedTestCase { description: string; input: any; - options?: { arrayFormat?: "repeat" | "indices" }; + options?: { arrayFormat?: "repeat" | "indices" | "comma" }; expected: string; } @@ -241,11 +241,107 @@ describe("Test qs toQueryString", () => { }); }); + describe("Comma array format", () => { + interface CommaTestCase { + description: string; + input: any; + options?: { arrayFormat?: "comma"; encode?: boolean }; + expected: string; + } + + const commaTests: CommaTestCase[] = [ + { + description: "should join array values with commas", + input: { event_type: ["ACCESS_GRANTED", "COPY", "DELETE"] }, + options: { arrayFormat: "comma" }, + expected: "event_type=ACCESS_GRANTED,COPY,DELETE", + }, + { + description: "should handle single-element array", + input: { event_type: ["ACCESS_GRANTED"] }, + options: { arrayFormat: "comma" }, + expected: "event_type=ACCESS_GRANTED", + }, + { + description: "should handle empty array", + input: { event_type: [] }, + options: { arrayFormat: "comma" }, + expected: "", + }, + { + description: "should not percent-encode commas", + input: { items: ["a", "b", "c"] }, + options: { arrayFormat: "comma" }, + expected: "items=a,b,c", + }, + { + description: "should encode values but not commas", + input: { items: ["a b", "c d"] }, + options: { arrayFormat: "comma" }, + expected: "items=a%20b,c%20d", + }, + { + description: "should not encode when encode is false", + input: { items: ["a b", "c d"] }, + options: { arrayFormat: "comma", encode: false }, + expected: "items=a b,c d", + }, + { + description: "should handle mixed parameters with comma and non-array values", + input: { event_type: ["ACCESS_GRANTED", "COPY", "DELETE"], limit: 10, offset: 0 }, + options: { arrayFormat: "comma" }, + expected: "event_type=ACCESS_GRANTED,COPY,DELETE&limit=10&offset=0", + }, + { + description: "should handle numeric array values", + input: { ids: [1, 2, 3] }, + options: { arrayFormat: "comma" }, + expected: "ids=1,2,3", + }, + { + description: "should handle boolean array values", + input: { flags: [true, false, true] }, + options: { arrayFormat: "comma" }, + expected: "flags=true,false,true", + }, + { + description: "should skip null values in comma format", + input: { items: ["a", null, "c"] }, + options: { arrayFormat: "comma" }, + expected: "items=a,c", + }, + { + description: "should skip undefined values in comma format", + input: { items: ["a", undefined, "c"] }, + options: { arrayFormat: "comma" }, + expected: "items=a,c", + }, + { + description: "should produce empty string for all-null array in comma format", + input: { items: [null, undefined] }, + options: { arrayFormat: "comma" }, + expected: "", + }, + { + description: "should encode commas within values while keeping separator commas literal", + input: { items: ["a,b", "c"] }, + options: { arrayFormat: "comma" }, + expected: "items=a%2Cb,c", + }, + ]; + + commaTests.forEach(({ description, input, options, expected }) => { + it(description, () => { + expect(toQueryString(input, options)).toBe(expected); + }); + }); + }); + describe("Options combinations", () => { interface OptionsTestCase { description: string; input: any; - options?: { arrayFormat?: "repeat" | "indices"; encode?: boolean }; + options?: { arrayFormat?: "repeat" | "indices" | "comma"; encode?: boolean }; expected: string; } diff --git a/tests/wire/account.test.ts b/tests/wire/account.test.ts index 130fc50..93757d0 100644 --- a/tests/wire/account.test.ts +++ b/tests/wire/account.test.ts @@ -5,7 +5,7 @@ import { BrevoClient } from "../../src/Client"; import { mockServerPool } from "../mock-server/MockServerPool"; describe("AccountClient", () => { - test("getAccount", async () => { + test("getAccount (1)", async () => { const server = mockServerPool.createServer(); const client = new BrevoClient({ maxRetries: 0, apiKey: "test", environment: server.baseUrl }); @@ -18,7 +18,6 @@ describe("AccountClient", () => { firstName: "Michael", lastName: "Davis", address: { city: "New York", country: "United States", street: "456 Business Ave", zipCode: "10001" }, - dateTimePreferences: { timezone: "America/New_York", timeFormat: "12", dateFormat: "mm-dd-yyyy" }, marketingAutomation: { enabled: true, key: "ma8k2x9v4h7p3d6f1c5e8b2a" }, plan: [ { @@ -74,6 +73,19 @@ describe("AccountClient", () => { expect(response).toEqual(rawResponseBody); }); + test("getAccount (2)", async () => { + const server = mockServerPool.createServer(); + const client = new BrevoClient({ maxRetries: 0, apiKey: "test", environment: server.baseUrl }); + + const rawResponseBody = { key: "value" }; + + server.mockEndpoint().get("/account").respondWith().statusCode(400).jsonBody(rawResponseBody).build(); + + await expect(async () => { + return await client.account.getAccount(); + }).rejects.toThrow(Brevo.BadRequestError); + }); + test("getAccountActivity (1)", async () => { const server = mockServerPool.createServer(); const client = new BrevoClient({ maxRetries: 0, apiKey: "test", environment: server.baseUrl }); diff --git a/tests/wire/balance.test.ts b/tests/wire/balance.test.ts index e7649d2..844e44d 100644 --- a/tests/wire/balance.test.ts +++ b/tests/wire/balance.test.ts @@ -10,16 +10,13 @@ describe("BalanceClient", () => { const client = new BrevoClient({ maxRetries: 0, apiKey: "test", environment: server.baseUrl }); const rawResponseBody = { + count: 1000000, + loyaltyProgramId: "loyaltyProgramId", + contactId: 1000000, balanceDefinitionId: "balanceDefinitionId", - constraintType: "constraintType", - createdAt: "createdAt", - durationUnit: "durationUnit", - durationValue: 1, - id: "id", - slidingSchedule: true, - transactionType: "transactionType", - updatedAt: "updatedAt", - value: 1, + activeBalances: [ + { id: "id", amount: 1.1, createdAt: "2024-01-15T09:30:00Z", expiresAt: "2024-01-15T09:30:00Z" }, + ], }; server @@ -32,8 +29,8 @@ describe("BalanceClient", () => { const response = await client.balance.getActiveBalancesApi({ pid: "pid", - contact_id: 1, - balance_definition_id: "balance_definition_id", + contactId: 1000000, + balanceDefinitionId: "balanceDefinitionId", }); expect(response).toEqual(rawResponseBody); }); @@ -55,8 +52,8 @@ describe("BalanceClient", () => { await expect(async () => { return await client.balance.getActiveBalancesApi({ pid: "pid", - contact_id: 1, - balance_definition_id: "balance_definition_id", + contactId: 1000000, + balanceDefinitionId: "balanceDefinitionId", }); }).rejects.toThrow(Brevo.UnauthorizedError); }); @@ -78,8 +75,8 @@ describe("BalanceClient", () => { await expect(async () => { return await client.balance.getActiveBalancesApi({ pid: "pid", - contact_id: 1, - balance_definition_id: "balance_definition_id", + contactId: 1000000, + balanceDefinitionId: "balanceDefinitionId", }); }).rejects.toThrow(Brevo.ForbiddenError); }); @@ -101,8 +98,8 @@ describe("BalanceClient", () => { await expect(async () => { return await client.balance.getActiveBalancesApi({ pid: "pid", - contact_id: 1, - balance_definition_id: "balance_definition_id", + contactId: 1000000, + balanceDefinitionId: "balanceDefinitionId", }); }).rejects.toThrow(Brevo.NotFoundError); }); @@ -124,8 +121,8 @@ describe("BalanceClient", () => { await expect(async () => { return await client.balance.getActiveBalancesApi({ pid: "pid", - contact_id: 1, - balance_definition_id: "balance_definition_id", + contactId: 1000000, + balanceDefinitionId: "balanceDefinitionId", }); }).rejects.toThrow(Brevo.UnprocessableEntityError); }); @@ -147,8 +144,8 @@ describe("BalanceClient", () => { await expect(async () => { return await client.balance.getActiveBalancesApi({ pid: "pid", - contact_id: 1, - balance_definition_id: "balance_definition_id", + contactId: 1000000, + balanceDefinitionId: "balanceDefinitionId", }); }).rejects.toThrow(Brevo.InternalServerError); }); @@ -160,26 +157,26 @@ describe("BalanceClient", () => { const rawResponseBody = { items: [ { - balanceAvailabilityDurationModifier: "startOfPeriod", - balanceAvailabilityDurationUnit: "balanceAvailabilityDurationUnit", - balanceAvailabilityDurationValue: 1, - balanceExpirationDate: "2024-01-15T09:30:00Z", - balanceOptionAmountOvertakingStrategy: "balanceOptionAmountOvertakingStrategy", - balanceOptionCreditRounding: "balanceOptionCreditRounding", - balanceOptionDebitRounding: "balanceOptionDebitRounding", - createdAt: "2024-01-15T09:30:00Z", - deletedAt: "deletedAt", - description: "description", id: "id", + name: "name", + description: "description", imageRef: "imageRef", + meta: { key: "value" }, + unit: "POINTS", + minAmount: 1.1, maxAmount: 1.1, maxCreditAmountLimit: 1.1, maxDebitAmountLimit: 1.1, - meta: { key: "value" }, - minAmount: 1.1, - name: "name", - unit: "unit", - updatedAt: "updatedAt", + balanceOptionAmountOvertakingStrategy: "strict", + balanceOptionCreditRounding: "lower", + balanceOptionDebitRounding: "lower", + balanceAvailabilityDurationValue: 1, + balanceAvailabilityDurationUnit: "day", + balanceAvailabilityDurationModifier: "noModification", + balanceExpirationDate: "balanceExpirationDate", + createdAt: "2024-01-15T09:30:00Z", + updatedAt: "2024-01-15T09:30:00Z", + deletedAt: "2024-01-15T09:30:00Z", }, ], }; @@ -287,26 +284,26 @@ describe("BalanceClient", () => { const client = new BrevoClient({ maxRetries: 0, apiKey: "test", environment: server.baseUrl }); const rawRequestBody = { name: "name", unit: "POINTS" }; const rawResponseBody = { - balanceAvailabilityDurationModifier: "startOfPeriod", - balanceAvailabilityDurationUnit: "balanceAvailabilityDurationUnit", - balanceAvailabilityDurationValue: 1, - balanceExpirationDate: "2024-01-15T09:30:00Z", - balanceOptionAmountOvertakingStrategy: "balanceOptionAmountOvertakingStrategy", - balanceOptionCreditRounding: "balanceOptionCreditRounding", - balanceOptionDebitRounding: "balanceOptionDebitRounding", - createdAt: "2024-01-15T09:30:00Z", - deletedAt: "deletedAt", - description: "description", id: "id", + name: "name", + description: "description", imageRef: "imageRef", + meta: { key: "value" }, + unit: "POINTS", + minAmount: 1.1, maxAmount: 1.1, maxCreditAmountLimit: 1.1, maxDebitAmountLimit: 1.1, - meta: { key: "value" }, - minAmount: 1.1, - name: "name", - unit: "unit", - updatedAt: "updatedAt", + balanceOptionAmountOvertakingStrategy: "strict", + balanceOptionCreditRounding: "lower", + balanceOptionDebitRounding: "lower", + balanceAvailabilityDurationValue: 1, + balanceAvailabilityDurationUnit: "day", + balanceAvailabilityDurationModifier: "noModification", + balanceExpirationDate: "balanceExpirationDate", + createdAt: "2024-01-15T09:30:00Z", + updatedAt: "2024-01-15T09:30:00Z", + deletedAt: "2024-01-15T09:30:00Z", }; server @@ -451,26 +448,26 @@ describe("BalanceClient", () => { const client = new BrevoClient({ maxRetries: 0, apiKey: "test", environment: server.baseUrl }); const rawResponseBody = { - balanceAvailabilityDurationModifier: "startOfPeriod", - balanceAvailabilityDurationUnit: "balanceAvailabilityDurationUnit", - balanceAvailabilityDurationValue: 1, - balanceExpirationDate: "2024-01-15T09:30:00Z", - balanceOptionAmountOvertakingStrategy: "balanceOptionAmountOvertakingStrategy", - balanceOptionCreditRounding: "balanceOptionCreditRounding", - balanceOptionDebitRounding: "balanceOptionDebitRounding", - createdAt: "2024-01-15T09:30:00Z", - deletedAt: "deletedAt", - description: "description", id: "id", + name: "name", + description: "description", imageRef: "imageRef", + meta: { key: "value" }, + unit: "POINTS", + minAmount: 1.1, maxAmount: 1.1, maxCreditAmountLimit: 1.1, maxDebitAmountLimit: 1.1, - meta: { key: "value" }, - minAmount: 1.1, - name: "name", - unit: "unit", - updatedAt: "updatedAt", + balanceOptionAmountOvertakingStrategy: "strict", + balanceOptionCreditRounding: "lower", + balanceOptionDebitRounding: "lower", + balanceAvailabilityDurationValue: 1, + balanceAvailabilityDurationUnit: "day", + balanceAvailabilityDurationModifier: "noModification", + balanceExpirationDate: "balanceExpirationDate", + createdAt: "2024-01-15T09:30:00Z", + updatedAt: "2024-01-15T09:30:00Z", + deletedAt: "2024-01-15T09:30:00Z", }; server @@ -603,26 +600,26 @@ describe("BalanceClient", () => { const client = new BrevoClient({ maxRetries: 0, apiKey: "test", environment: server.baseUrl }); const rawRequestBody = { name: "name", unit: "POINTS" }; const rawResponseBody = { - balanceAvailabilityDurationModifier: "startOfPeriod", - balanceAvailabilityDurationUnit: "balanceAvailabilityDurationUnit", - balanceAvailabilityDurationValue: 1, - balanceExpirationDate: "2024-01-15T09:30:00Z", - balanceOptionAmountOvertakingStrategy: "balanceOptionAmountOvertakingStrategy", - balanceOptionCreditRounding: "balanceOptionCreditRounding", - balanceOptionDebitRounding: "balanceOptionDebitRounding", - createdAt: "2024-01-15T09:30:00Z", - deletedAt: "deletedAt", - description: "description", id: "id", + name: "name", + description: "description", imageRef: "imageRef", + meta: { key: "value" }, + unit: "POINTS", + minAmount: 1.1, maxAmount: 1.1, maxCreditAmountLimit: 1.1, maxDebitAmountLimit: 1.1, - meta: { key: "value" }, - minAmount: 1.1, - name: "name", - unit: "unit", - updatedAt: "updatedAt", + balanceOptionAmountOvertakingStrategy: "strict", + balanceOptionCreditRounding: "lower", + balanceOptionDebitRounding: "lower", + balanceAvailabilityDurationValue: 1, + balanceAvailabilityDurationUnit: "day", + balanceAvailabilityDurationModifier: "noModification", + balanceExpirationDate: "balanceExpirationDate", + createdAt: "2024-01-15T09:30:00Z", + updatedAt: "2024-01-15T09:30:00Z", + deletedAt: "2024-01-15T09:30:00Z", }; server @@ -932,16 +929,16 @@ describe("BalanceClient", () => { value: 1, }; const rawResponseBody = { + id: "id", balanceDefinitionId: "balanceDefinitionId", - constraintType: "constraintType", - createdAt: "createdAt", - durationUnit: "durationUnit", + transactionType: "credit", + constraintType: "transaction", durationValue: 1, - id: "id", + durationUnit: "hour", + value: 1.1, slidingSchedule: true, - transactionType: "transactionType", - updatedAt: "updatedAt", - value: 1, + createdAt: "2024-01-15T09:30:00Z", + updatedAt: "2024-01-15T09:30:00Z", }; server @@ -1140,16 +1137,16 @@ describe("BalanceClient", () => { const client = new BrevoClient({ maxRetries: 0, apiKey: "test", environment: server.baseUrl }); const rawResponseBody = { + id: "id", balanceDefinitionId: "balanceDefinitionId", - constraintType: "constraintType", - createdAt: "createdAt", - durationUnit: "durationUnit", + transactionType: "credit", + constraintType: "transaction", durationValue: 1, - id: "id", + durationUnit: "hour", + value: 1.1, slidingSchedule: true, - transactionType: "transactionType", - updatedAt: "updatedAt", - value: 1, + createdAt: "2024-01-15T09:30:00Z", + updatedAt: "2024-01-15T09:30:00Z", }; server @@ -1294,16 +1291,16 @@ describe("BalanceClient", () => { value: 1, }; const rawResponseBody = { + id: "id", balanceDefinitionId: "balanceDefinitionId", - constraintType: "constraintType", - createdAt: "createdAt", - durationUnit: "durationUnit", + transactionType: "credit", + constraintType: "transaction", durationValue: 1, - id: "id", + durationUnit: "hour", + value: 1.1, slidingSchedule: true, - transactionType: "transactionType", - updatedAt: "updatedAt", - value: 1, + createdAt: "2024-01-15T09:30:00Z", + updatedAt: "2024-01-15T09:30:00Z", }; server @@ -1660,6 +1657,7 @@ describe("BalanceClient", () => { const response = await client.balance.getContactBalances({ pid: "pid", + balanceDefinitionId: "balanceDefinitionId", }); expect(response).toEqual(rawResponseBody); }); @@ -1681,6 +1679,7 @@ describe("BalanceClient", () => { await expect(async () => { return await client.balance.getContactBalances({ pid: "pid", + balanceDefinitionId: "balanceDefinitionId", }); }).rejects.toThrow(Brevo.UnauthorizedError); }); @@ -1702,6 +1701,7 @@ describe("BalanceClient", () => { await expect(async () => { return await client.balance.getContactBalances({ pid: "pid", + balanceDefinitionId: "balanceDefinitionId", }); }).rejects.toThrow(Brevo.ForbiddenError); }); @@ -1723,6 +1723,7 @@ describe("BalanceClient", () => { await expect(async () => { return await client.balance.getContactBalances({ pid: "pid", + balanceDefinitionId: "balanceDefinitionId", }); }).rejects.toThrow(Brevo.NotFoundError); }); @@ -1744,6 +1745,7 @@ describe("BalanceClient", () => { await expect(async () => { return await client.balance.getContactBalances({ pid: "pid", + balanceDefinitionId: "balanceDefinitionId", }); }).rejects.toThrow(Brevo.UnprocessableEntityError); }); @@ -1765,6 +1767,7 @@ describe("BalanceClient", () => { await expect(async () => { return await client.balance.getContactBalances({ pid: "pid", + balanceDefinitionId: "balanceDefinitionId", }); }).rejects.toThrow(Brevo.InternalServerError); }); @@ -1777,7 +1780,7 @@ describe("BalanceClient", () => { balanceDefinitionId: "balanceDefinitionId", contactId: 1, dueAt: "dueAt", - source: "source", + source: "engine", }; const rawResponseBody = { amount: 1.1, @@ -1809,7 +1812,7 @@ describe("BalanceClient", () => { balanceDefinitionId: "balanceDefinitionId", contactId: 1, dueAt: "dueAt", - source: "source", + source: "engine", }); expect(response).toEqual(rawResponseBody); }); @@ -1822,7 +1825,7 @@ describe("BalanceClient", () => { balanceDefinitionId: "balanceDefinitionId", contactId: 1, dueAt: "dueAt", - source: "source", + source: "engine", }; const rawResponseBody = { key: "value" }; @@ -1842,7 +1845,7 @@ describe("BalanceClient", () => { balanceDefinitionId: "balanceDefinitionId", contactId: 1, dueAt: "dueAt", - source: "source", + source: "engine", }); }).rejects.toThrow(Brevo.UnauthorizedError); }); @@ -1855,7 +1858,7 @@ describe("BalanceClient", () => { balanceDefinitionId: "balanceDefinitionId", contactId: 1, dueAt: "dueAt", - source: "source", + source: "engine", }; const rawResponseBody = { key: "value" }; @@ -1875,7 +1878,7 @@ describe("BalanceClient", () => { balanceDefinitionId: "balanceDefinitionId", contactId: 1, dueAt: "dueAt", - source: "source", + source: "engine", }); }).rejects.toThrow(Brevo.ForbiddenError); }); @@ -1888,7 +1891,7 @@ describe("BalanceClient", () => { balanceDefinitionId: "balanceDefinitionId", contactId: 1, dueAt: "dueAt", - source: "source", + source: "engine", }; const rawResponseBody = { message: "message" }; @@ -1908,7 +1911,7 @@ describe("BalanceClient", () => { balanceDefinitionId: "balanceDefinitionId", contactId: 1, dueAt: "dueAt", - source: "source", + source: "engine", }); }).rejects.toThrow(Brevo.UnprocessableEntityError); }); @@ -1921,7 +1924,7 @@ describe("BalanceClient", () => { balanceDefinitionId: "balanceDefinitionId", contactId: 1, dueAt: "dueAt", - source: "source", + source: "engine", }; const rawResponseBody = { key: "value" }; @@ -1941,7 +1944,7 @@ describe("BalanceClient", () => { balanceDefinitionId: "balanceDefinitionId", contactId: 1, dueAt: "dueAt", - source: "source", + source: "engine", }); }).rejects.toThrow(Brevo.InternalServerError); }); @@ -1950,7 +1953,11 @@ describe("BalanceClient", () => { const server = mockServerPool.createServer(); const client = new BrevoClient({ maxRetries: 0, apiKey: "test", environment: server.baseUrl }); - const rawResponseBody = { balance: [{ balanceDefinitionId: "balanceDefinitionId", value: 1.1 }] }; + const rawResponseBody = { + loyaltyProgramId: "loyaltyProgramId", + contactId: 1000000, + balance: [{ balanceDefinitionId: "balanceDefinitionId", value: 1.1 }], + }; server .mockEndpoint() @@ -2082,15 +2089,15 @@ describe("BalanceClient", () => { const client = new BrevoClient({ maxRetries: 0, apiKey: "test", environment: server.baseUrl }); const rawRequestBody = { balanceDefinitionId: "balanceDefinitionId" }; const rawResponseBody = { - amount: 1.1, - balanceDefinitionId: "balanceDefinitionId", - consumedAt: "consumedAt", - contactId: 1, - createdAt: "createdAt", - expiresAt: "expiresAt", id: "id", + amount: 1.1, loyaltyProgramId: "loyaltyProgramId", - organizationId: 1, + organizationId: 1000000, + contactId: 1000000, + balanceDefinitionId: "balanceDefinitionId", + createdAt: "2024-01-15T09:30:00Z", + expiresAt: "2024-01-15T09:30:00Z", + consumedAt: "2024-01-15T09:30:00Z", }; server @@ -2242,6 +2249,7 @@ describe("BalanceClient", () => { transactionHistory: [ { amount: 1.1, + transactionType: "credit", balanceExpirationDate: "balanceExpirationDate", cancelledAt: "cancelledAt", completedAt: "completedAt", @@ -2265,7 +2273,7 @@ describe("BalanceClient", () => { const response = await client.balance.getTransactionHistoryApi({ pid: "pid", - contactId: 1, + contactId: 1000000, balanceDefinitionId: "balanceDefinitionId", }); expect(response).toEqual(rawResponseBody); @@ -2288,7 +2296,7 @@ describe("BalanceClient", () => { await expect(async () => { return await client.balance.getTransactionHistoryApi({ pid: "pid", - contactId: 1, + contactId: 1000000, balanceDefinitionId: "balanceDefinitionId", }); }).rejects.toThrow(Brevo.UnauthorizedError); @@ -2311,7 +2319,7 @@ describe("BalanceClient", () => { await expect(async () => { return await client.balance.getTransactionHistoryApi({ pid: "pid", - contactId: 1, + contactId: 1000000, balanceDefinitionId: "balanceDefinitionId", }); }).rejects.toThrow(Brevo.ForbiddenError); @@ -2334,7 +2342,7 @@ describe("BalanceClient", () => { await expect(async () => { return await client.balance.getTransactionHistoryApi({ pid: "pid", - contactId: 1, + contactId: 1000000, balanceDefinitionId: "balanceDefinitionId", }); }).rejects.toThrow(Brevo.NotFoundError); @@ -2357,7 +2365,7 @@ describe("BalanceClient", () => { await expect(async () => { return await client.balance.getTransactionHistoryApi({ pid: "pid", - contactId: 1, + contactId: 1000000, balanceDefinitionId: "balanceDefinitionId", }); }).rejects.toThrow(Brevo.UnprocessableEntityError); @@ -2380,7 +2388,7 @@ describe("BalanceClient", () => { await expect(async () => { return await client.balance.getTransactionHistoryApi({ pid: "pid", - contactId: 1, + contactId: 1000000, balanceDefinitionId: "balanceDefinitionId", }); }).rejects.toThrow(Brevo.InternalServerError); @@ -2391,21 +2399,22 @@ describe("BalanceClient", () => { const client = new BrevoClient({ maxRetries: 0, apiKey: "test", environment: server.baseUrl }); const rawRequestBody = { amount: 1.1, balanceDefinitionId: "balanceDefinitionId" }; const rawResponseBody = { - amount: 1.1, - balanceDefinitionId: "balanceDefinitionId", - cancelledAt: "cancelledAt", - completedAt: "completedAt", - contactId: 1, - createdAt: "createdAt", - eventTime: "eventTime", - expirationDate: "expirationDate", id: "id", - loyaltyProgramId: "loyaltyProgramId", + amount: 1.1, + transactionType: "credit", meta: { key: "value" }, + status: "pending", + loyaltyProgramId: "loyaltyProgramId", + balanceDefinitionId: "balanceDefinitionId", + contactId: 1000000, + eventTime: "2024-01-15T09:30:00Z", rejectReason: "rejectReason", - rejectedAt: "rejectedAt", - status: "status", - updatedAt: "updatedAt", + rejectedAt: "2024-01-15T09:30:00Z", + expirationDate: "2024-01-15T09:30:00Z", + completedAt: "2024-01-15T09:30:00Z", + cancelledAt: "2024-01-15T09:30:00Z", + createdAt: "2024-01-15T09:30:00Z", + updatedAt: "2024-01-15T09:30:00Z", }; server @@ -2550,21 +2559,22 @@ describe("BalanceClient", () => { const client = new BrevoClient({ maxRetries: 0, apiKey: "test", environment: server.baseUrl }); const rawResponseBody = { - amount: 1.1, - balanceDefinitionId: "balanceDefinitionId", - cancelledAt: "cancelledAt", - completedAt: "completedAt", - contactId: 1, - createdAt: "createdAt", - eventTime: "eventTime", - expirationDate: "expirationDate", id: "id", - loyaltyProgramId: "loyaltyProgramId", + amount: 1.1, + transactionType: "credit", meta: { key: "value" }, + status: "pending", + loyaltyProgramId: "loyaltyProgramId", + balanceDefinitionId: "balanceDefinitionId", + contactId: 1000000, + eventTime: "2024-01-15T09:30:00Z", rejectReason: "rejectReason", - rejectedAt: "rejectedAt", - status: "status", - updatedAt: "updatedAt", + rejectedAt: "2024-01-15T09:30:00Z", + expirationDate: "2024-01-15T09:30:00Z", + completedAt: "2024-01-15T09:30:00Z", + cancelledAt: "2024-01-15T09:30:00Z", + createdAt: "2024-01-15T09:30:00Z", + updatedAt: "2024-01-15T09:30:00Z", }; server @@ -2697,21 +2707,22 @@ describe("BalanceClient", () => { const client = new BrevoClient({ maxRetries: 0, apiKey: "test", environment: server.baseUrl }); const rawResponseBody = { - amount: 1.1, - balanceDefinitionId: "balanceDefinitionId", - cancelledAt: "cancelledAt", - completedAt: "completedAt", - contactId: 1, - createdAt: "createdAt", - eventTime: "eventTime", - expirationDate: "expirationDate", id: "id", - loyaltyProgramId: "loyaltyProgramId", + amount: 1.1, + transactionType: "credit", meta: { key: "value" }, + status: "pending", + loyaltyProgramId: "loyaltyProgramId", + balanceDefinitionId: "balanceDefinitionId", + contactId: 1000000, + eventTime: "2024-01-15T09:30:00Z", rejectReason: "rejectReason", - rejectedAt: "rejectedAt", - status: "status", - updatedAt: "updatedAt", + rejectedAt: "2024-01-15T09:30:00Z", + expirationDate: "2024-01-15T09:30:00Z", + completedAt: "2024-01-15T09:30:00Z", + cancelledAt: "2024-01-15T09:30:00Z", + createdAt: "2024-01-15T09:30:00Z", + updatedAt: "2024-01-15T09:30:00Z", }; server diff --git a/tests/wire/companies.test.ts b/tests/wire/companies.test.ts index 0913181..f4bf916 100644 --- a/tests/wire/companies.test.ts +++ b/tests/wire/companies.test.ts @@ -482,17 +482,18 @@ describe("CompaniesClient", () => { }).rejects.toThrow(Brevo.NotFoundError); }); - test("getCompanyAttributes", async () => { + test("getCompanyAttributes (1)", async () => { const server = mockServerPool.createServer(); const client = new BrevoClient({ maxRetries: 0, apiKey: "test", environment: server.baseUrl }); const rawResponseBody = [ { - attributeOptions: [{ key: "custom key", value: "custom label" }], - attributeTypeName: "text", internalName: "name", - isRequired: true, + attributeTypeName: "text", label: "Company Name", + attributeOptions: [{ key: "custom key", value: "custom label" }], + isRequired: true, + isValueReadonly: false, }, ]; @@ -507,4 +508,23 @@ describe("CompaniesClient", () => { const response = await client.companies.getCompanyAttributes(); expect(response).toEqual(rawResponseBody); }); + + test("getCompanyAttributes (2)", async () => { + const server = mockServerPool.createServer(); + const client = new BrevoClient({ maxRetries: 0, apiKey: "test", environment: server.baseUrl }); + + const rawResponseBody = { key: "value" }; + + server + .mockEndpoint() + .get("/crm/attributes/companies") + .respondWith() + .statusCode(400) + .jsonBody(rawResponseBody) + .build(); + + await expect(async () => { + return await client.companies.getCompanyAttributes(); + }).rejects.toThrow(Brevo.BadRequestError); + }); }); diff --git a/tests/wire/contacts.test.ts b/tests/wire/contacts.test.ts index 2eb22f7..79b0bb8 100644 --- a/tests/wire/contacts.test.ts +++ b/tests/wire/contacts.test.ts @@ -21,6 +21,7 @@ describe("ContactsClient", () => { listUnsubscribed: [1000000], modifiedAt: "2017-05-01T17:05:03Z", smsBlacklisted: true, + whatsappBlacklisted: false, }, { attributes: {}, @@ -32,6 +33,7 @@ describe("ContactsClient", () => { listUnsubscribed: [1000000], modifiedAt: "2017-05-01T17:05:03Z", smsBlacklisted: false, + whatsappBlacklisted: false, }, ], count: 3, @@ -128,7 +130,7 @@ describe("ContactsClient", () => { }).rejects.toThrow(Brevo.TooEarlyError); }); - test("getAttributes", async () => { + test("getAttributes (1)", async () => { const server = mockServerPool.createServer(); const client = new BrevoClient({ maxRetries: 0, apiKey: "test", environment: server.baseUrl }); @@ -137,7 +139,7 @@ describe("ContactsClient", () => { { calculatedValue: "COUNT[ORDER_ID,ORDER_DATE,==,NOW(-1)]", category: "normal", - enumeration: [{ label: "Women", value: 1 }], + enumeration: [{ label: "Women", value: 1, valueStr: "1" }], multiCategoryOptions: ["USA"], name: "LASTNAME", type: "text", @@ -145,7 +147,7 @@ describe("ContactsClient", () => { { calculatedValue: "COUNT[ORDER_ID,ORDER_DATE,==,NOW(-1)]", category: "normal", - enumeration: [{ label: "Women", value: 1 }], + enumeration: [{ label: "Women", value: 1, valueStr: "1" }], multiCategoryOptions: ["USA"], name: "FIRSTNAME", type: "text", @@ -153,7 +155,7 @@ describe("ContactsClient", () => { { calculatedValue: "COUNT[ORDER_ID,ORDER_DATE,==,NOW(-1)]", category: "normal", - enumeration: [{ label: "Women", value: 1 }], + enumeration: [{ label: "Women", value: 1, valueStr: "1" }], multiCategoryOptions: ["USA"], name: "DOB", type: "date", @@ -162,18 +164,29 @@ describe("ContactsClient", () => { calculatedValue: "COUNT[ORDER_ID,ORDER_DATE,==,NOW(-1)]", category: "category", enumeration: [ - { label: "Men", value: 1 }, - { label: "Women", value: 2 }, - { label: "Kid", value: 3 }, + { label: "Men", value: 1, valueStr: "1" }, + { label: "Women", value: 2, valueStr: "2" }, + { label: "Kid", value: 3, valueStr: "3" }, ], multiCategoryOptions: ["USA"], name: "GENDER", type: "text", }, + { + calculatedValue: "COUNT[ORDER_ID,ORDER_DATE,==,NOW(-1)]", + category: "category", + enumeration: [ + { label: "English", value: 0, valueStr: "en" }, + { label: "French", value: 0, valueStr: "fr" }, + ], + multiCategoryOptions: ["USA"], + name: "LANGUAGE", + type: "text", + }, { calculatedValue: "COUNT[ORDER_ID,ORDER_DATE,==,NOW(-1)]", category: "normal", - enumeration: [{ label: "Women", value: 1 }], + enumeration: [{ label: "Women", value: 1, valueStr: "1" }], multiCategoryOptions: ["USA"], name: "BDO", type: "user", @@ -181,7 +194,7 @@ describe("ContactsClient", () => { { calculatedValue: "COUNT[ORDER_ID,ORDER_DATE,==,NOW(-1)]", category: "normal", - enumeration: [{ label: "Women", value: 1 }], + enumeration: [{ label: "Women", value: 1, valueStr: "1" }], multiCategoryOptions: ["USA", "India", "France"], name: "COUNTRY", type: "multiple-choice", @@ -201,6 +214,25 @@ describe("ContactsClient", () => { expect(response).toEqual(rawResponseBody); }); + test("getAttributes (2)", async () => { + const server = mockServerPool.createServer(); + const client = new BrevoClient({ maxRetries: 0, apiKey: "test", environment: server.baseUrl }); + + const rawResponseBody = { key: "value" }; + + server + .mockEndpoint() + .get("/contacts/attributes") + .respondWith() + .statusCode(400) + .jsonBody(rawResponseBody) + .build(); + + await expect(async () => { + return await client.contacts.getAttributes(); + }).rejects.toThrow(Brevo.BadRequestError); + }); + test("createAttribute (1)", async () => { const server = mockServerPool.createServer(); const client = new BrevoClient({ maxRetries: 0, apiKey: "test", environment: server.baseUrl }); @@ -1293,6 +1325,7 @@ describe("ContactsClient", () => { listUnsubscribed: [1, 2], modifiedAt: "2017-05-12T12:30:00Z", smsBlacklisted: true, + whatsappBlacklisted: false, }, { attributes: {}, @@ -1304,6 +1337,7 @@ describe("ContactsClient", () => { listUnsubscribed: [1], modifiedAt: "2017-05-12T12:30:00Z", smsBlacklisted: false, + whatsappBlacklisted: false, }, { attributes: {}, @@ -1315,6 +1349,7 @@ describe("ContactsClient", () => { listUnsubscribed: [1], modifiedAt: "2017-05-12T12:30:00Z", smsBlacklisted: false, + whatsappBlacklisted: false, }, ], count: 17655, @@ -1376,6 +1411,27 @@ describe("ContactsClient", () => { }).rejects.toThrow(Brevo.NotFoundError); }); + test("getContactsFromList (4)", async () => { + const server = mockServerPool.createServer(); + const client = new BrevoClient({ maxRetries: 0, apiKey: "test", environment: server.baseUrl }); + + const rawResponseBody = { message: "message" }; + + server + .mockEndpoint() + .get("/contacts/lists/1000000/contacts") + .respondWith() + .statusCode(429) + .jsonBody(rawResponseBody) + .build(); + + await expect(async () => { + return await client.contacts.getContactsFromList({ + listId: 1000000, + }); + }).rejects.toThrow(Brevo.TooManyRequestsError); + }); + test("addContactToList (1)", async () => { const server = mockServerPool.createServer(); const client = new BrevoClient({ maxRetries: 0, apiKey: "test", environment: server.baseUrl }); @@ -1947,6 +2003,7 @@ describe("ContactsClient", () => { listUnsubscribed: [1000000], modifiedAt: "2017-05-02T16:40:31Z", smsBlacklisted: false, + whatsappBlacklisted: false, statistics: { clicked: [ { diff --git a/tests/wire/conversations.test.ts b/tests/wire/conversations.test.ts index 964985e..916ed4c 100644 --- a/tests/wire/conversations.test.ts +++ b/tests/wire/conversations.test.ts @@ -83,28 +83,36 @@ describe("ConversationsClient", () => { agentUserpic: "https://www.brevo.com/", attachments: [ { - fileName: "fileName", - inlineId: "inlineId", + name: "name", + link: "link", + mimeType: "mimeType", isImage: true, - isInline: "isInline", + isSticker: true, + isInline: true, + inlineId: "inlineId", size: 1000000, - url: "url", + isAllowedFileType: true, }, ], bcc: [{ email: "email", name: "name" }], cc: [{ email: "email", name: "name" }], createdAt: 1482512803740, file: { - filename: "conversations.png", + name: "conversations.png", + link: "https://ucarecdn.com/cee5c10c-8302-45c1-b1fb-43860ca941a9/", + mimeType: "mimeType", + isImage: true, + isSticker: true, + isInline: true, + inlineId: "inlineId", + size: 15538, imageInfo: { - height: 525, - previewUrl: - "https://ucarecdn.com/03cd56cd-1de9-4f65-996d-08afdf27fa1b/-/preview/800x800/-/quality/lighter/", width: 1129, + height: 525, + previewLink: + "https://ucarecdn.com/03cd56cd-1de9-4f65-996d-08afdf27fa1b/-/preview/800x800/-/quality/better/", }, - isImage: true, - size: 15538, - url: "https://ucarecdn.com/cee5c10c-8302-45c1-b1fb-43860ca941a9/", + isAllowedFileType: true, }, forwardedToSourceStatus: { error: "error", isSuccess: true }, from: { email: "email", name: "name" }, @@ -124,6 +132,10 @@ describe("ConversationsClient", () => { text: "Hello! How can I help you?", to: [{ email: "email", name: "name" }], type: "agent", + isSentViaJsApi: true, + messageType: "messageType", + isForward: true, + source: { key: "value" }, visitorId: "kZMvWhf8npAu3H6qd57w2Hv6nh6rnxvg", }; @@ -160,28 +172,36 @@ describe("ConversationsClient", () => { agentUserpic: "https://www.brevo.com/", attachments: [ { - fileName: "fileName", - inlineId: "inlineId", + name: "name", + link: "link", + mimeType: "mimeType", isImage: true, - isInline: "isInline", + isSticker: true, + isInline: true, + inlineId: "inlineId", size: 1000000, - url: "url", + isAllowedFileType: true, }, ], bcc: [{ email: "email", name: "name" }], cc: [{ email: "email", name: "name" }], createdAt: 1482512803740, file: { - filename: "conversations.png", + name: "conversations.png", + link: "https://ucarecdn.com/cee5c10c-8302-45c1-b1fb-43860ca941a9/", + mimeType: "mimeType", + isImage: true, + isSticker: true, + isInline: true, + inlineId: "inlineId", + size: 15538, imageInfo: { - height: 525, - previewUrl: - "https://ucarecdn.com/03cd56cd-1de9-4f65-996d-08afdf27fa1b/-/preview/800x800/-/quality/lighter/", width: 1129, + height: 525, + previewLink: + "https://ucarecdn.com/03cd56cd-1de9-4f65-996d-08afdf27fa1b/-/preview/800x800/-/quality/better/", }, - isImage: true, - size: 15538, - url: "https://ucarecdn.com/cee5c10c-8302-45c1-b1fb-43860ca941a9/", + isAllowedFileType: true, }, forwardedToSourceStatus: { error: "error", isSuccess: true }, from: { email: "email", name: "name" }, @@ -201,6 +221,10 @@ describe("ConversationsClient", () => { text: "Hello! How can I help you?", to: [{ email: "email", name: "name" }], type: "agent", + isSentViaJsApi: true, + messageType: "messageType", + isForward: true, + source: { key: "value" }, visitorId: "kZMvWhf8npAu3H6qd57w2Hv6nh6rnxvg", }; @@ -238,28 +262,36 @@ describe("ConversationsClient", () => { agentUserpic: "https://www.brevo.com/", attachments: [ { - fileName: "fileName", - inlineId: "inlineId", + name: "name", + link: "link", + mimeType: "mimeType", isImage: true, - isInline: "isInline", + isSticker: true, + isInline: true, + inlineId: "inlineId", size: 1000000, - url: "url", + isAllowedFileType: true, }, ], bcc: [{ email: "email", name: "name" }], cc: [{ email: "email", name: "name" }], createdAt: 1482512803740, file: { - filename: "conversations.png", + name: "conversations.png", + link: "https://ucarecdn.com/cee5c10c-8302-45c1-b1fb-43860ca941a9/", + mimeType: "mimeType", + isImage: true, + isSticker: true, + isInline: true, + inlineId: "inlineId", + size: 15538, imageInfo: { - height: 525, - previewUrl: - "https://ucarecdn.com/03cd56cd-1de9-4f65-996d-08afdf27fa1b/-/preview/800x800/-/quality/lighter/", width: 1129, + height: 525, + previewLink: + "https://ucarecdn.com/03cd56cd-1de9-4f65-996d-08afdf27fa1b/-/preview/800x800/-/quality/better/", }, - isImage: true, - size: 15538, - url: "https://ucarecdn.com/cee5c10c-8302-45c1-b1fb-43860ca941a9/", + isAllowedFileType: true, }, forwardedToSourceStatus: { error: "error", isSuccess: true }, from: { email: "email", name: "name" }, @@ -279,6 +311,10 @@ describe("ConversationsClient", () => { text: "Hello! How can I help you?", to: [{ email: "email", name: "name" }], type: "agent", + isSentViaJsApi: true, + messageType: "messageType", + isForward: true, + source: { key: "value" }, visitorId: "kZMvWhf8npAu3H6qd57w2Hv6nh6rnxvg", }; @@ -303,7 +339,7 @@ describe("ConversationsClient", () => { test("sendAMessageAsAnAgent (4)", async () => { const server = mockServerPool.createServer(); const client = new BrevoClient({ maxRetries: 0, apiKey: "test", environment: server.baseUrl }); - const rawRequestBody = { text: { key: "value" }, visitorId: { key: "value" } }; + const rawRequestBody = { text: "text", visitorId: "visitorId" }; const rawResponseBody = { key: "value" }; server @@ -317,12 +353,8 @@ describe("ConversationsClient", () => { await expect(async () => { return await client.conversations.sendAMessageAsAnAgent({ - text: { - key: "value", - }, - visitorId: { - key: "value", - }, + text: "text", + visitorId: "visitorId", }); }).rejects.toThrow(Brevo.BadRequestError); }); @@ -337,28 +369,36 @@ describe("ConversationsClient", () => { agentUserpic: "https://www.brevo.com/", attachments: [ { - fileName: "fileName", - inlineId: "inlineId", + name: "name", + link: "link", + mimeType: "mimeType", isImage: true, - isInline: "isInline", + isSticker: true, + isInline: true, + inlineId: "inlineId", size: 1000000, - url: "url", + isAllowedFileType: true, }, ], bcc: [{ email: "email", name: "name" }], cc: [{ email: "email", name: "name" }], createdAt: 1482512803740, file: { - filename: "conversations.png", + name: "conversations.png", + link: "https://ucarecdn.com/cee5c10c-8302-45c1-b1fb-43860ca941a9/", + mimeType: "mimeType", + isImage: true, + isSticker: true, + isInline: true, + inlineId: "inlineId", + size: 15538, imageInfo: { - height: 525, - previewUrl: - "https://ucarecdn.com/03cd56cd-1de9-4f65-996d-08afdf27fa1b/-/preview/800x800/-/quality/lighter/", width: 1129, + height: 525, + previewLink: + "https://ucarecdn.com/03cd56cd-1de9-4f65-996d-08afdf27fa1b/-/preview/800x800/-/quality/better/", }, - isImage: true, - size: 15538, - url: "https://ucarecdn.com/cee5c10c-8302-45c1-b1fb-43860ca941a9/", + isAllowedFileType: true, }, forwardedToSourceStatus: { error: "error", isSuccess: true }, from: { email: "email", name: "name" }, @@ -378,6 +418,10 @@ describe("ConversationsClient", () => { text: "Hello! How can I help you?", to: [{ email: "email", name: "name" }], type: "agent", + isSentViaJsApi: true, + messageType: "messageType", + isForward: true, + source: { key: "value" }, visitorId: "kZMvWhf8npAu3H6qd57w2Hv6nh6rnxvg", }; @@ -447,32 +491,40 @@ describe("ConversationsClient", () => { agentUserpic: "https://www.brevo.com/", attachments: [ { - fileName: "fileName", - inlineId: "inlineId", + name: "name", + link: "link", + mimeType: "mimeType", isImage: true, - isInline: "isInline", + isSticker: true, + isInline: true, + inlineId: "inlineId", size: 1000000, - url: "url", + isAllowedFileType: true, }, ], bcc: [{ email: "email", name: "name" }], cc: [{ email: "email", name: "name" }], createdAt: 1482512803740, file: { - filename: "conversations.png", + name: "conversations.png", + link: "https://ucarecdn.com/cee5c10c-8302-45c1-b1fb-43860ca941a9/", + mimeType: "mimeType", + isImage: true, + isSticker: true, + isInline: true, + inlineId: "inlineId", + size: 15538, imageInfo: { - height: 525, - previewUrl: - "https://ucarecdn.com/03cd56cd-1de9-4f65-996d-08afdf27fa1b/-/preview/800x800/-/quality/lighter/", width: 1129, + height: 525, + previewLink: + "https://ucarecdn.com/03cd56cd-1de9-4f65-996d-08afdf27fa1b/-/preview/800x800/-/quality/better/", }, - isImage: true, - size: 15538, - url: "https://ucarecdn.com/cee5c10c-8302-45c1-b1fb-43860ca941a9/", + isAllowedFileType: true, }, forwardedToSourceStatus: { error: "error", isSuccess: true }, from: { email: "email", name: "name" }, - html: "Hello! How can I help you?", + html: "Good morning! How can I help you?", id: "eYBEm3gq3zc5ayE2g", integrations: { key: "value" }, isBot: true, @@ -485,9 +537,13 @@ describe("ConversationsClient", () => { replyTo: { email: "email", name: "name" }, sourceMessageId: "sourceMessageId", subject: "Invitation to a meeting", - text: "Hello! How can I help you?", + text: "Good morning! How can I help you?", to: [{ email: "email", name: "name" }], type: "agent", + isSentViaJsApi: true, + messageType: "messageType", + isForward: true, + source: { key: "value" }, visitorId: "kZMvWhf8npAu3H6qd57w2Hv6nh6rnxvg", }; @@ -612,7 +668,7 @@ describe("ConversationsClient", () => { const client = new BrevoClient({ maxRetries: 0, apiKey: "test", environment: server.baseUrl }); const rawRequestBody = { groupId: "PjRBMhWGen6aRHjif", - text: "Your order has shipped! Here’s your tracking number: 9114 5847 3325 9667 4328 88", + text: "Your order has shipped! Here's your tracking number: 9114 5847 3325 9667 4328 88", visitorId: "kZMvWhf8npAu3H6qd57w2Hv6nh6rnxvg", }; const rawResponseBody = { @@ -621,32 +677,40 @@ describe("ConversationsClient", () => { agentUserpic: "https://www.brevo.com/", attachments: [ { - fileName: "fileName", - inlineId: "inlineId", + name: "name", + link: "link", + mimeType: "mimeType", isImage: true, - isInline: "isInline", + isSticker: true, + isInline: true, + inlineId: "inlineId", size: 1000000, - url: "url", + isAllowedFileType: true, }, ], bcc: [{ email: "email", name: "name" }], cc: [{ email: "email", name: "name" }], createdAt: 1470222622433, file: { - filename: "conversations.png", + name: "conversations.png", + link: "https://ucarecdn.com/cee5c10c-8302-45c1-b1fb-43860ca941a9/", + mimeType: "mimeType", + isImage: true, + isSticker: true, + isInline: true, + inlineId: "inlineId", + size: 15538, imageInfo: { - height: 525, - previewUrl: - "https://ucarecdn.com/03cd56cd-1de9-4f65-996d-08afdf27fa1b/-/preview/800x800/-/quality/lighter/", width: 1129, + height: 525, + previewLink: + "https://ucarecdn.com/03cd56cd-1de9-4f65-996d-08afdf27fa1b/-/preview/800x800/-/quality/better/", }, - isImage: true, - size: 15538, - url: "https://ucarecdn.com/cee5c10c-8302-45c1-b1fb-43860ca941a9/", + isAllowedFileType: true, }, forwardedToSourceStatus: { error: "error", isSuccess: true }, from: { email: "email", name: "name" }, - html: "Your order has shipped! Here’s your tracking number: 9114 5847 3325 9667 4328 88", + html: "Your order has shipped! Here's your tracking number: 9114 5847 3325 9667 4328 88", id: "AXCR3k9bpSY7bpuh7", integrations: { key: "value" }, isBot: true, @@ -659,9 +723,13 @@ describe("ConversationsClient", () => { replyTo: { email: "email", name: "name" }, sourceMessageId: "sourceMessageId", subject: "Invitation to a meeting", - text: "Your order has shipped! Here’s your tracking number: 9114 5847 3325 9667 4328 88", + text: "Your order has shipped! Here's your tracking number: 9114 5847 3325 9667 4328 88", to: [{ email: "email", name: "name" }], type: "agent", + isSentViaJsApi: true, + messageType: "messageType", + isForward: true, + source: { key: "value" }, visitorId: "kZMvWhf8npAu3H6qd57w2Hv6nh6rnxvg", }; @@ -676,7 +744,7 @@ describe("ConversationsClient", () => { const response = await client.conversations.sendAnAutomatedMessageToAVisitor({ groupId: "PjRBMhWGen6aRHjif", - text: "Your order has shipped! Here\u2019s your tracking number: 9114 5847 3325 9667 4328 88", + text: "Your order has shipped! Here's your tracking number: 9114 5847 3325 9667 4328 88", visitorId: "kZMvWhf8npAu3H6qd57w2Hv6nh6rnxvg", }); expect(response).toEqual(rawResponseBody); @@ -686,7 +754,7 @@ describe("ConversationsClient", () => { const server = mockServerPool.createServer(); const client = new BrevoClient({ maxRetries: 0, apiKey: "test", environment: server.baseUrl }); const rawRequestBody = { - text: "Your order has shipped! Here’s your tracking number: 9114 5847 3325 9667 4328 88", + text: "Your order has shipped! Here's your tracking number: 9114 5847 3325 9667 4328 88", visitorId: "kZMvWhf8npAu3H6qd57w2Hv6nh6rnxvg", }; const rawResponseBody = { @@ -695,32 +763,40 @@ describe("ConversationsClient", () => { agentUserpic: "https://www.brevo.com/", attachments: [ { - fileName: "fileName", - inlineId: "inlineId", + name: "name", + link: "link", + mimeType: "mimeType", isImage: true, - isInline: "isInline", + isSticker: true, + isInline: true, + inlineId: "inlineId", size: 1000000, - url: "url", + isAllowedFileType: true, }, ], bcc: [{ email: "email", name: "name" }], cc: [{ email: "email", name: "name" }], createdAt: 1470222622433, file: { - filename: "conversations.png", + name: "conversations.png", + link: "https://ucarecdn.com/cee5c10c-8302-45c1-b1fb-43860ca941a9/", + mimeType: "mimeType", + isImage: true, + isSticker: true, + isInline: true, + inlineId: "inlineId", + size: 15538, imageInfo: { - height: 525, - previewUrl: - "https://ucarecdn.com/03cd56cd-1de9-4f65-996d-08afdf27fa1b/-/preview/800x800/-/quality/lighter/", width: 1129, + height: 525, + previewLink: + "https://ucarecdn.com/03cd56cd-1de9-4f65-996d-08afdf27fa1b/-/preview/800x800/-/quality/better/", }, - isImage: true, - size: 15538, - url: "https://ucarecdn.com/cee5c10c-8302-45c1-b1fb-43860ca941a9/", + isAllowedFileType: true, }, forwardedToSourceStatus: { error: "error", isSuccess: true }, from: { email: "email", name: "name" }, - html: "Your order has shipped! Here’s your tracking number: 9114 5847 3325 9667 4328 88", + html: "Your order has shipped! Here's your tracking number: 9114 5847 3325 9667 4328 88", id: "AXCR3k9bpSY7bpuh7", integrations: { key: "value" }, isBot: true, @@ -733,9 +809,13 @@ describe("ConversationsClient", () => { replyTo: { email: "email", name: "name" }, sourceMessageId: "sourceMessageId", subject: "Invitation to a meeting", - text: "Your order has shipped! Here’s your tracking number: 9114 5847 3325 9667 4328 88", + text: "Your order has shipped! Here's your tracking number: 9114 5847 3325 9667 4328 88", to: [{ email: "email", name: "name" }], type: "agent", + isSentViaJsApi: true, + messageType: "messageType", + isForward: true, + source: { key: "value" }, visitorId: "kZMvWhf8npAu3H6qd57w2Hv6nh6rnxvg", }; @@ -749,7 +829,7 @@ describe("ConversationsClient", () => { .build(); const response = await client.conversations.sendAnAutomatedMessageToAVisitor({ - text: "Your order has shipped! Here\u2019s your tracking number: 9114 5847 3325 9667 4328 88", + text: "Your order has shipped! Here's your tracking number: 9114 5847 3325 9667 4328 88", visitorId: "kZMvWhf8npAu3H6qd57w2Hv6nh6rnxvg", }); expect(response).toEqual(rawResponseBody); @@ -760,7 +840,7 @@ describe("ConversationsClient", () => { const client = new BrevoClient({ maxRetries: 0, apiKey: "test", environment: server.baseUrl }); const rawRequestBody = { agentId: "d9nKoegKSjmCtyK78", - text: "Your order has shipped! Here’s your tracking number: 9114 5847 3325 9667 4328 88", + text: "Your order has shipped! Here's your tracking number: 9114 5847 3325 9667 4328 88", visitorId: "kZMvWhf8npAu3H6qd57w2Hv6nh6rnxvg", }; const rawResponseBody = { @@ -769,32 +849,40 @@ describe("ConversationsClient", () => { agentUserpic: "https://www.brevo.com/", attachments: [ { - fileName: "fileName", - inlineId: "inlineId", + name: "name", + link: "link", + mimeType: "mimeType", isImage: true, - isInline: "isInline", + isSticker: true, + isInline: true, + inlineId: "inlineId", size: 1000000, - url: "url", + isAllowedFileType: true, }, ], bcc: [{ email: "email", name: "name" }], cc: [{ email: "email", name: "name" }], createdAt: 1470222622433, file: { - filename: "conversations.png", + name: "conversations.png", + link: "https://ucarecdn.com/cee5c10c-8302-45c1-b1fb-43860ca941a9/", + mimeType: "mimeType", + isImage: true, + isSticker: true, + isInline: true, + inlineId: "inlineId", + size: 15538, imageInfo: { - height: 525, - previewUrl: - "https://ucarecdn.com/03cd56cd-1de9-4f65-996d-08afdf27fa1b/-/preview/800x800/-/quality/lighter/", width: 1129, + height: 525, + previewLink: + "https://ucarecdn.com/03cd56cd-1de9-4f65-996d-08afdf27fa1b/-/preview/800x800/-/quality/better/", }, - isImage: true, - size: 15538, - url: "https://ucarecdn.com/cee5c10c-8302-45c1-b1fb-43860ca941a9/", + isAllowedFileType: true, }, forwardedToSourceStatus: { error: "error", isSuccess: true }, from: { email: "email", name: "name" }, - html: "Your order has shipped! Here’s your tracking number: 9114 5847 3325 9667 4328 88", + html: "Your order has shipped! Here's your tracking number: 9114 5847 3325 9667 4328 88", id: "AXCR3k9bpSY7bpuh7", integrations: { key: "value" }, isBot: true, @@ -807,9 +895,13 @@ describe("ConversationsClient", () => { replyTo: { email: "email", name: "name" }, sourceMessageId: "sourceMessageId", subject: "Invitation to a meeting", - text: "Your order has shipped! Here’s your tracking number: 9114 5847 3325 9667 4328 88", + text: "Your order has shipped! Here's your tracking number: 9114 5847 3325 9667 4328 88", to: [{ email: "email", name: "name" }], type: "agent", + isSentViaJsApi: true, + messageType: "messageType", + isForward: true, + source: { key: "value" }, visitorId: "kZMvWhf8npAu3H6qd57w2Hv6nh6rnxvg", }; @@ -824,7 +916,7 @@ describe("ConversationsClient", () => { const response = await client.conversations.sendAnAutomatedMessageToAVisitor({ agentId: "d9nKoegKSjmCtyK78", - text: "Your order has shipped! Here\u2019s your tracking number: 9114 5847 3325 9667 4328 88", + text: "Your order has shipped! Here's your tracking number: 9114 5847 3325 9667 4328 88", visitorId: "kZMvWhf8npAu3H6qd57w2Hv6nh6rnxvg", }); expect(response).toEqual(rawResponseBody); @@ -833,7 +925,7 @@ describe("ConversationsClient", () => { test("sendAnAutomatedMessageToAVisitor (4)", async () => { const server = mockServerPool.createServer(); const client = new BrevoClient({ maxRetries: 0, apiKey: "test", environment: server.baseUrl }); - const rawRequestBody = { text: { key: "value" }, visitorId: { key: "value" } }; + const rawRequestBody = { text: "text", visitorId: "visitorId" }; const rawResponseBody = { key: "value" }; server @@ -847,12 +939,8 @@ describe("ConversationsClient", () => { await expect(async () => { return await client.conversations.sendAnAutomatedMessageToAVisitor({ - text: { - key: "value", - }, - visitorId: { - key: "value", - }, + text: "text", + visitorId: "visitorId", }); }).rejects.toThrow(Brevo.BadRequestError); }); @@ -867,32 +955,40 @@ describe("ConversationsClient", () => { agentUserpic: "https://www.brevo.com/", attachments: [ { - fileName: "fileName", - inlineId: "inlineId", + name: "name", + link: "link", + mimeType: "mimeType", isImage: true, - isInline: "isInline", + isSticker: true, + isInline: true, + inlineId: "inlineId", size: 1000000, - url: "url", + isAllowedFileType: true, }, ], bcc: [{ email: "email", name: "name" }], cc: [{ email: "email", name: "name" }], createdAt: 1470222622433, file: { - filename: "conversations.png", + name: "conversations.png", + link: "https://ucarecdn.com/cee5c10c-8302-45c1-b1fb-43860ca941a9/", + mimeType: "mimeType", + isImage: true, + isSticker: true, + isInline: true, + inlineId: "inlineId", + size: 15538, imageInfo: { - height: 525, - previewUrl: - "https://ucarecdn.com/03cd56cd-1de9-4f65-996d-08afdf27fa1b/-/preview/800x800/-/quality/lighter/", width: 1129, + height: 525, + previewLink: + "https://ucarecdn.com/03cd56cd-1de9-4f65-996d-08afdf27fa1b/-/preview/800x800/-/quality/better/", }, - isImage: true, - size: 15538, - url: "https://ucarecdn.com/cee5c10c-8302-45c1-b1fb-43860ca941a9/", + isAllowedFileType: true, }, forwardedToSourceStatus: { error: "error", isSuccess: true }, from: { email: "email", name: "name" }, - html: "Your order has shipped! Here’s your tracking number: 9114 5847 3325 9667 4328 88", + html: "Your order has shipped! Here's your tracking number: 9114 5847 3325 9667 4328 88", id: "AXCR3k9bpSY7bpuh7", integrations: { key: "value" }, isBot: true, @@ -905,9 +1001,13 @@ describe("ConversationsClient", () => { replyTo: { email: "email", name: "name" }, sourceMessageId: "sourceMessageId", subject: "Invitation to a meeting", - text: "Your order has shipped! Here’s your tracking number: 9114 5847 3325 9667 4328 88", + text: "Your order has shipped! Here's your tracking number: 9114 5847 3325 9667 4328 88", to: [{ email: "email", name: "name" }], type: "agent", + isSentViaJsApi: true, + messageType: "messageType", + isForward: true, + source: { key: "value" }, visitorId: "kZMvWhf8npAu3H6qd57w2Hv6nh6rnxvg", }; @@ -971,7 +1071,7 @@ describe("ConversationsClient", () => { const server = mockServerPool.createServer(); const client = new BrevoClient({ maxRetries: 0, apiKey: "test", environment: server.baseUrl }); const rawRequestBody = { - text: "Your order has shipped! Here’s your tracking number: 9114 5847 4668 7775 9233 54", + text: "Your order has shipped! Here's your tracking number: 9114 5847 4668 7775 9233 54", }; const rawResponseBody = { agentId: "d9nKoegKSjmCtyK78", @@ -979,32 +1079,40 @@ describe("ConversationsClient", () => { agentUserpic: "https://www.brevo.com/", attachments: [ { - fileName: "fileName", - inlineId: "inlineId", + name: "name", + link: "link", + mimeType: "mimeType", isImage: true, - isInline: "isInline", + isSticker: true, + isInline: true, + inlineId: "inlineId", size: 1000000, - url: "url", + isAllowedFileType: true, }, ], bcc: [{ email: "email", name: "name" }], cc: [{ email: "email", name: "name" }], createdAt: 1470222622433, file: { - filename: "conversations.png", + name: "conversations.png", + link: "https://ucarecdn.com/cee5c10c-8302-45c1-b1fb-43860ca941a9/", + mimeType: "mimeType", + isImage: true, + isSticker: true, + isInline: true, + inlineId: "inlineId", + size: 15538, imageInfo: { - height: 525, - previewUrl: - "https://ucarecdn.com/03cd56cd-1de9-4f65-996d-08afdf27fa1b/-/preview/800x800/-/quality/lighter/", width: 1129, + height: 525, + previewLink: + "https://ucarecdn.com/03cd56cd-1de9-4f65-996d-08afdf27fa1b/-/preview/800x800/-/quality/better/", }, - isImage: true, - size: 15538, - url: "https://ucarecdn.com/cee5c10c-8302-45c1-b1fb-43860ca941a9/", + isAllowedFileType: true, }, forwardedToSourceStatus: { error: "error", isSuccess: true }, from: { email: "email", name: "name" }, - html: "Your order has shipped! Here’s your tracking number: 9114 5847 4668 7775 9233 54", + html: "Your order has shipped! Here's your tracking number: 9114 5847 4668 7775 9233 54", id: "AXCR3k9bpSY7bpuh7", integrations: { key: "value" }, isBot: true, @@ -1017,9 +1125,13 @@ describe("ConversationsClient", () => { replyTo: { email: "email", name: "name" }, sourceMessageId: "sourceMessageId", subject: "Invitation to a meeting", - text: "Your order has shipped! Here’s your tracking number: 9114 5847 4668 7775 9233 54", + text: "Your order has shipped! Here's your tracking number: 9114 5847 4668 7775 9233 54", to: [{ email: "email", name: "name" }], type: "agent", + isSentViaJsApi: true, + messageType: "messageType", + isForward: true, + source: { key: "value" }, visitorId: "kZMvWhf8npAu3H6qd57w2Hv6nh6rnxvg", }; @@ -1034,7 +1146,7 @@ describe("ConversationsClient", () => { const response = await client.conversations.updateAnAutomatedMessage({ id: "id", - text: "Your order has shipped! Here\u2019s your tracking number: 9114 5847 4668 7775 9233 54", + text: "Your order has shipped! Here's your tracking number: 9114 5847 4668 7775 9233 54", }); expect(response).toEqual(rawResponseBody); }); diff --git a/tests/wire/customObjects.test.ts b/tests/wire/customObjects.test.ts index 6a6779b..a18fdbd 100644 --- a/tests/wire/customObjects.test.ts +++ b/tests/wire/customObjects.test.ts @@ -8,7 +8,22 @@ describe("CustomObjectsClient", () => { test("upsertrecords (1)", async () => { const server = mockServerPool.createServer(); const client = new BrevoClient({ maxRetries: 0, apiKey: "test", environment: server.baseUrl }); - const rawRequestBody = { records: [{}] }; + const rawRequestBody = { + records: [ + { + associations: [ + { object_type: "garage", action: "link", records: [{ identifiers: { id: 435435 } }] }, + { + object_type: "garage", + action: "unlink", + records: [{ identifiers: { ext_id: "old-garage-001" } }], + }, + ], + attributes: { make: "Toyota", model: "Camry", year: 2020, engine_type: "hybrid" }, + identifiers: { ext_id: "VIN123" }, + }, + ], + }; const rawResponseBody = { message: "Batch object records are being processed", processId: 21 }; server @@ -22,12 +37,115 @@ describe("CustomObjectsClient", () => { const response = await client.customObjects.upsertrecords({ object_type: "vehicle", - records: [{}], + records: [ + { + associations: [ + { + object_type: "garage", + action: "link", + records: [ + { + identifiers: { + id: 435435, + }, + }, + ], + }, + { + object_type: "garage", + action: "unlink", + records: [ + { + identifiers: { + ext_id: "old-garage-001", + }, + }, + ], + }, + ], + attributes: { + make: "Toyota", + model: "Camry", + year: 2020, + engine_type: "hybrid", + }, + identifiers: { + ext_id: "VIN123", + }, + }, + ], }); expect(response).toEqual(rawResponseBody); }); test("upsertrecords (2)", async () => { + const server = mockServerPool.createServer(); + const client = new BrevoClient({ maxRetries: 0, apiKey: "test", environment: server.baseUrl }); + const rawRequestBody = { + records: [{ attributes: { make: "Honda", model: "Civic", year: 2023, engine_type: "petrol" } }], + }; + const rawResponseBody = { message: "Batch object records are being processed", processId: 21 }; + + server + .mockEndpoint() + .post("/objects/vehicle/batch/upsert") + .jsonBody(rawRequestBody) + .respondWith() + .statusCode(200) + .jsonBody(rawResponseBody) + .build(); + + const response = await client.customObjects.upsertrecords({ + object_type: "vehicle", + records: [ + { + attributes: { + make: "Honda", + model: "Civic", + year: 2023, + engine_type: "petrol", + }, + }, + ], + }); + expect(response).toEqual(rawResponseBody); + }); + + test("upsertrecords (3)", async () => { + const server = mockServerPool.createServer(); + const client = new BrevoClient({ maxRetries: 0, apiKey: "test", environment: server.baseUrl }); + const rawRequestBody = { + records: [{ attributes: { color: "red", engine_type: "diesel" }, identifiers: { id: 42 } }], + }; + const rawResponseBody = { message: "Batch object records are being processed", processId: 21 }; + + server + .mockEndpoint() + .post("/objects/vehicle/batch/upsert") + .jsonBody(rawRequestBody) + .respondWith() + .statusCode(200) + .jsonBody(rawResponseBody) + .build(); + + const response = await client.customObjects.upsertrecords({ + object_type: "vehicle", + records: [ + { + attributes: { + color: "red", + engine_type: "diesel", + }, + identifiers: { + id: 42, + }, + }, + ], + }); + expect(response).toEqual(rawResponseBody); + }); + + test("upsertrecords (4)", async () => { const server = mockServerPool.createServer(); const client = new BrevoClient({ maxRetries: 0, apiKey: "test", environment: server.baseUrl }); const rawRequestBody = { records: [{}, {}] }; @@ -50,7 +168,7 @@ describe("CustomObjectsClient", () => { }).rejects.toThrow(Brevo.BadRequestError); }); - test("upsertrecords (3)", async () => { + test("upsertrecords (5)", async () => { const server = mockServerPool.createServer(); const client = new BrevoClient({ maxRetries: 0, apiKey: "test", environment: server.baseUrl }); const rawRequestBody = { records: [{}, {}] }; @@ -73,7 +191,7 @@ describe("CustomObjectsClient", () => { }).rejects.toThrow(Brevo.ForbiddenError); }); - test("upsertrecords (4)", async () => { + test("upsertrecords (6)", async () => { const server = mockServerPool.createServer(); const client = new BrevoClient({ maxRetries: 0, apiKey: "test", environment: server.baseUrl }); const rawRequestBody = { records: [{}, {}] }; @@ -96,7 +214,7 @@ describe("CustomObjectsClient", () => { }).rejects.toThrow(Brevo.NotFoundError); }); - test("upsertrecords (5)", async () => { + test("upsertrecords (7)", async () => { const server = mockServerPool.createServer(); const client = new BrevoClient({ maxRetries: 0, apiKey: "test", environment: server.baseUrl }); const rawRequestBody = { records: [{}, {}] }; @@ -128,7 +246,7 @@ describe("CustomObjectsClient", () => { records: [ { associations: [{ object_type: "garage", records: [{ identifiers: { id: 12345 } }] }], - attributes: { color: "Black", engine_type: "Hybrid", make: "Toyoto", model: "Corolla", year: 2020 }, + attributes: { make: "Toyota", model: "Corolla", color: "Black", year: 2020, engine_type: "hybrid" }, createdAt: "2025-07-22T10:20:30Z", identifiers: { ext_id: "507f1f77bc", id: 16789 }, updatedAt: "2025-07-22T10:20:30Z", @@ -248,7 +366,7 @@ describe("CustomObjectsClient", () => { const server = mockServerPool.createServer(); const client = new BrevoClient({ maxRetries: 0, apiKey: "test", environment: server.baseUrl }); const rawRequestBody = { identifiers: { ext_ids: ["ext-001", "ext-002"] } }; - const rawResponseBody = { processId: 21, message: "Batch object records are being processed for deletion." }; + const rawResponseBody = { processId: 21, message: "Batch object records are being processed for deletion" }; server .mockEndpoint() @@ -318,28 +436,6 @@ describe("CustomObjectsClient", () => { const rawRequestBody = {}; const rawResponseBody = { key: "value" }; - server - .mockEndpoint() - .post("/objects/object_type/batch/delete") - .jsonBody(rawRequestBody) - .respondWith() - .statusCode(404) - .jsonBody(rawResponseBody) - .build(); - - await expect(async () => { - return await client.customObjects.batchDeleteObjectRecords({ - object_type: "object_type", - }); - }).rejects.toThrow(Brevo.NotFoundError); - }); - - test("batchDeleteObjectRecords (5)", async () => { - const server = mockServerPool.createServer(); - const client = new BrevoClient({ maxRetries: 0, apiKey: "test", environment: server.baseUrl }); - const rawRequestBody = {}; - const rawResponseBody = { key: "value" }; - server .mockEndpoint() .post("/objects/object_type/batch/delete") diff --git a/tests/wire/deals.test.ts b/tests/wire/deals.test.ts index a22f7fb..2966168 100644 --- a/tests/wire/deals.test.ts +++ b/tests/wire/deals.test.ts @@ -5,17 +5,18 @@ import { BrevoClient } from "../../src/Client"; import { mockServerPool } from "../mock-server/MockServerPool"; describe("DealsClient", () => { - test("getDealAttributes", async () => { + test("getDealAttributes (1)", async () => { const server = mockServerPool.createServer(); const client = new BrevoClient({ maxRetries: 0, apiKey: "test", environment: server.baseUrl }); const rawResponseBody = [ { - attributeOptions: [{ key: "custom key", value: "custom label" }], - attributeTypeName: "text", internalName: "deal_name", - isRequired: true, + attributeTypeName: "text", label: "Deal Name", + attributeOptions: [{ key: "custom key", value: "custom label" }], + isRequired: true, + isValueReadonly: false, }, ]; @@ -31,6 +32,25 @@ describe("DealsClient", () => { expect(response).toEqual(rawResponseBody); }); + test("getDealAttributes (2)", async () => { + const server = mockServerPool.createServer(); + const client = new BrevoClient({ maxRetries: 0, apiKey: "test", environment: server.baseUrl }); + + const rawResponseBody = { key: "value" }; + + server + .mockEndpoint() + .get("/crm/attributes/deals") + .respondWith() + .statusCode(400) + .jsonBody(rawResponseBody) + .build(); + + await expect(async () => { + return await client.deals.getDealAttributes(); + }).rejects.toThrow(Brevo.BadRequestError); + }); + test("getAllDeals (1)", async () => { const server = mockServerPool.createServer(); const client = new BrevoClient({ maxRetries: 0, apiKey: "test", environment: server.baseUrl }); @@ -38,6 +58,7 @@ describe("DealsClient", () => { const rawResponseBody = { items: [ { + id: "629475917295261d9b1f4403", attributes: { amount: 12, created_at: "2022-05-30T07:42:05.671Z", @@ -51,13 +72,12 @@ describe("DealsClient", () => { pipeline: "6093d296ad1e9c5cf2140a58", stage_updated_at: "2022-05-30T07:42:05.671Z", }, - id: "629475917295261d9b1f4403", + linkedContactsIds: [1, 2, 3], linkedCompaniesIds: [ "61a5ce58c5d4795761045990", "61a5ce58c5d4795761045991", "61a5ce58c5d4795761045992", ], - linkedContactsIds: [1, 2, 3], }, ], }; @@ -170,6 +190,7 @@ describe("DealsClient", () => { const client = new BrevoClient({ maxRetries: 0, apiKey: "test", environment: server.baseUrl }); const rawResponseBody = { + id: "629475917295261d9b1f4403", attributes: { amount: 12, created_at: "2022-05-30T07:42:05.671Z", @@ -178,15 +199,13 @@ describe("DealsClient", () => { deal_stage: "9e577ff7-8e42-4ab3-be26-2b5e01b42518", last_activity_date: "2022-06-06T08:38:36.000Z", last_updated_date: "2022-06-06T08:38:36.761Z", - next_activity_date: { key: "value" }, number_of_activities: 0, number_of_contacts: 1, pipeline: "6093d296ad1e9c5cf2140a58", stage_updated_at: "2022-05-30T07:42:05.671Z", }, - id: "629475917295261d9b1f4403", - linkedCompaniesIds: ["61a5ce58c5d4795761045990", "61a5ce58c5d4795761045991", "61a5ce58c5d4795761045992"], linkedContactsIds: [1, 2, 3], + linkedCompaniesIds: ["61a5ce58c5d4795761045990", "61a5ce58c5d4795761045991", "61a5ce58c5d4795761045992"], }; server.mockEndpoint().get("/crm/deals/id").respondWith().statusCode(200).jsonBody(rawResponseBody).build(); @@ -326,7 +345,7 @@ describe("DealsClient", () => { }).rejects.toThrow(Brevo.NotFoundError); }); - test("getPipelineStages", async () => { + test("getPipelineStages (1)", async () => { const server = mockServerPool.createServer(); const client = new BrevoClient({ maxRetries: 0, apiKey: "test", environment: server.baseUrl }); @@ -348,6 +367,25 @@ describe("DealsClient", () => { expect(response).toEqual(rawResponseBody); }); + test("getPipelineStages (2)", async () => { + const server = mockServerPool.createServer(); + const client = new BrevoClient({ maxRetries: 0, apiKey: "test", environment: server.baseUrl }); + + const rawResponseBody = { key: "value" }; + + server + .mockEndpoint() + .get("/crm/pipeline/details") + .respondWith() + .statusCode(400) + .jsonBody(rawResponseBody) + .build(); + + await expect(async () => { + return await client.deals.getPipelineStages(); + }).rejects.toThrow(Brevo.BadRequestError); + }); + test("getAllPipelines (1)", async () => { const server = mockServerPool.createServer(); const client = new BrevoClient({ maxRetries: 0, apiKey: "test", environment: server.baseUrl }); diff --git a/tests/wire/ecommerce.test.ts b/tests/wire/ecommerce.test.ts index 0235741..78769f7 100644 --- a/tests/wire/ecommerce.test.ts +++ b/tests/wire/ecommerce.test.ts @@ -54,7 +54,7 @@ describe("EcommerceClient", () => { const server = mockServerPool.createServer(); const client = new BrevoClient({ maxRetries: 0, apiKey: "test", environment: server.baseUrl }); const rawRequestBody = { id: "CAT123" }; - const rawResponseBody = { id: 21 }; + const rawResponseBody = { id: "CAT123" }; server .mockEndpoint() @@ -269,6 +269,7 @@ describe("EcommerceClient", () => { const response = await client.ecommerce.getAttributionMetricsForOneOrMoreBrevoCampaignsOrWorkflows({ periodFrom: "2022-01-02T00:00:00Z", periodTo: "2022-01-03T00:00:00Z", + "emailCampaignId[]": ["sale"], }); expect(response).toEqual(rawResponseBody); }); @@ -861,6 +862,7 @@ describe("EcommerceClient", () => { name: "Alpina Panoma Classic", parentId: "parentId", price: 49.95, + alternativePrice: 39.95, s3Original: "https://img-ecom.mailinblue.com/path-to-original/img.jpg", s3ThumbAnalytics: "https://img-ecom.mailinblue.com/path-to-analytics/img.jpg", s3ThumbEditor: "https://img-ecom.mailinblue.com/path-to-editor/img.jpg", @@ -881,6 +883,7 @@ describe("EcommerceClient", () => { name: "Alpina Panoma Classic2", parentId: "parentId", price: 49.95, + alternativePrice: 44.95, s3Original: "https://img-ecom.mailinblue.com/path-to-original/img.jpg", s3ThumbAnalytics: "https://img-ecom.mailinblue.com/path-to-analytics/img.jpg", s3ThumbEditor: "https://img-ecom.mailinblue.com/path-to-editor/img.jpg", @@ -914,7 +917,7 @@ describe("EcommerceClient", () => { const server = mockServerPool.createServer(); const client = new BrevoClient({ maxRetries: 0, apiKey: "test", environment: server.baseUrl }); const rawRequestBody = { id: "P11", name: "Iphone 11" }; - const rawResponseBody = { id: 21 }; + const rawResponseBody = { id: "P11" }; server .mockEndpoint() @@ -1034,6 +1037,7 @@ describe("EcommerceClient", () => { name: "Iphone 11", parentId: "parentId", price: 1.1, + alternativePrice: 1.1, s3Original: "s3Original", s3ThumbAnalytics: "s3ThumbAnalytics", s3ThumbEditor: "s3ThumbEditor", diff --git a/tests/wire/emailCampaigns.test.ts b/tests/wire/emailCampaigns.test.ts index 2571a78..0a6b8e2 100644 --- a/tests/wire/emailCampaigns.test.ts +++ b/tests/wire/emailCampaigns.test.ts @@ -27,7 +27,9 @@ describe("EmailCampaignsClient", () => { type: "classic", winnerCriteria: "open", winnerDelay: 50, + attachmentUrl: "https://attachment.domain.com/file.pdf", createdAt: "2017-05-01T12:30:00Z", + emailExpirationDate: { duration: 30 }, footer: "[DEFAULT_FOOTER]", header: "[DEFAULT_HEADER]", htmlContent: "This is my HTML Content", @@ -45,10 +47,10 @@ describe("EmailCampaignsClient", () => { testSent: true, toField: "{FNAME} {LNAME}", utmCampaignValue: "myutm", - utmIDActive: true, + utmID: 12, utmMedium: "EMAIL", utmSource: "Brevo", - recipients: { exclusionLists: [13], lists: [5] }, + recipients: { excludedSegments: [14], exclusionLists: [13], lists: [5], segments: [23] }, statistics: { campaignStats: [ { @@ -92,13 +94,9 @@ describe("EmailCampaignsClient", () => { unsubscriptions: 2, viewed: 8999, }, - linksStats: {}, + linksStats: { "http://myUrl1.domain.com": 80 }, mirrorClick: 120, remaining: 1000, - statsByBrowser: { - key: { clickers: 2665, uniqueClicks: 2300, uniqueViews: 7779, viewed: 8999 }, - }, - statsByDevice: {}, statsByDomain: { "hotmail.co.uk": { appleMppOpens: 10, @@ -159,7 +157,9 @@ describe("EmailCampaignsClient", () => { type: "classic", winnerCriteria: "open", winnerDelay: 50, + attachmentUrl: "https://attachment.domain.com/file.pdf", createdAt: "2017-05-01T12:30:00Z", + emailExpirationDate: { duration: 30 }, footer: "[DEFAULT_FOOTER]", header: "[DEFAULT_HEADER]", htmlContent: "This is my HTML Content", @@ -177,10 +177,10 @@ describe("EmailCampaignsClient", () => { testSent: false, toField: "{FNAME} {LNAME}", utmCampaignValue: "myutm", - utmIDActive: true, + utmID: 12, utmMedium: "EMAIL", utmSource: "Brevo", - recipients: { exclusionLists: [45], lists: [10] }, + recipients: { excludedSegments: [14], exclusionLists: [45], lists: [10], segments: [23] }, statistics: { campaignStats: [ { @@ -224,13 +224,13 @@ describe("EmailCampaignsClient", () => { unsubscriptions: 2, viewed: 8999, }, - linksStats: {}, + linksStats: { + "http://myUrl1.domain.com": 1000000, + "http://myUrl2.domain.com": 1000000, + "http://myUrl3.domain.com": 1000000, + }, mirrorClick: 120, remaining: 1000, - statsByBrowser: { - key: { clickers: 2665, uniqueClicks: 2300, uniqueViews: 7779, viewed: 8999 }, - }, - statsByDevice: {}, statsByDomain: { aol: { appleMppOpens: 10, @@ -343,6 +343,29 @@ describe("EmailCampaignsClient", () => { }).rejects.toThrow(Brevo.BadRequestError); }); + test("createEmailCampaign (3)", async () => { + const server = mockServerPool.createServer(); + const client = new BrevoClient({ maxRetries: 0, apiKey: "test", environment: server.baseUrl }); + const rawRequestBody = { name: "name", sender: {} }; + const rawResponseBody = { message: "message" }; + + server + .mockEndpoint() + .post("/emailCampaigns") + .jsonBody(rawRequestBody) + .respondWith() + .statusCode(405) + .jsonBody(rawResponseBody) + .build(); + + await expect(async () => { + return await client.emailCampaigns.createEmailCampaign({ + name: "name", + sender: {}, + }); + }).rejects.toThrow(Brevo.MethodNotAllowedError); + }); + test("uploadImageToGallery (1)", async () => { const server = mockServerPool.createServer(); const client = new BrevoClient({ maxRetries: 0, apiKey: "test", environment: server.baseUrl }); @@ -408,7 +431,9 @@ describe("EmailCampaignsClient", () => { type: "classic", winnerCriteria: "open", winnerDelay: 50, + attachmentUrl: "https://attachment.domain.com/file.pdf", createdAt: "2017-05-01T12:30:00Z", + emailExpirationDate: { duration: 30, unit: "days" }, footer: "[DEFAULT_FOOTER]", header: "[DEFAULT_HEADER]", htmlContent: "This is my HTML Content", @@ -426,10 +451,10 @@ describe("EmailCampaignsClient", () => { testSent: false, toField: "{FNAME} {LNAME}", utmCampaignValue: "myutm", - utmIDActive: true, + utmID: 12, utmMedium: "EMAIL", utmSource: "Brevo", - recipients: { exclusionLists: [45], lists: [22] }, + recipients: { excludedSegments: [14], exclusionLists: [45], lists: [22], segments: [23] }, statistics: { campaignStats: [ { @@ -473,7 +498,11 @@ describe("EmailCampaignsClient", () => { unsubscriptions: 2, viewed: 8999, }, - linksStats: {}, + linksStats: { + "http://myUrl1.domain.com": 1000000, + "http://myUrl2.domain.com": 1000000, + "http://myUrl3.domain.com": 1000000, + }, mirrorClick: 120, remaining: 1000, statsByBrowser: { @@ -634,6 +663,28 @@ describe("EmailCampaignsClient", () => { }).rejects.toThrow(Brevo.NotFoundError); }); + test("updateEmailCampaign (4)", async () => { + const server = mockServerPool.createServer(); + const client = new BrevoClient({ maxRetries: 0, apiKey: "test", environment: server.baseUrl }); + const rawRequestBody = {}; + const rawResponseBody = { message: "message" }; + + server + .mockEndpoint() + .put("/emailCampaigns/1000000") + .jsonBody(rawRequestBody) + .respondWith() + .statusCode(405) + .jsonBody(rawResponseBody) + .build(); + + await expect(async () => { + return await client.emailCampaigns.updateEmailCampaign({ + campaignId: 1000000, + }); + }).rejects.toThrow(Brevo.MethodNotAllowedError); + }); + test("deleteEmailCampaign (1)", async () => { const server = mockServerPool.createServer(); const client = new BrevoClient({ maxRetries: 0, apiKey: "test", environment: server.baseUrl }); @@ -673,6 +724,27 @@ describe("EmailCampaignsClient", () => { const rawResponseBody = { key: "value" }; + server + .mockEndpoint() + .delete("/emailCampaigns/1000000") + .respondWith() + .statusCode(403) + .jsonBody(rawResponseBody) + .build(); + + await expect(async () => { + return await client.emailCampaigns.deleteEmailCampaign({ + campaignId: 1000000, + }); + }).rejects.toThrow(Brevo.ForbiddenError); + }); + + test("deleteEmailCampaign (4)", async () => { + const server = mockServerPool.createServer(); + const client = new BrevoClient({ maxRetries: 0, apiKey: "test", environment: server.baseUrl }); + + const rawResponseBody = { key: "value" }; + server .mockEndpoint() .delete("/emailCampaigns/1000000") diff --git a/tests/wire/event.test.ts b/tests/wire/event.test.ts index 7718d19..4b0c398 100644 --- a/tests/wire/event.test.ts +++ b/tests/wire/event.test.ts @@ -16,7 +16,6 @@ describe("EventClient", () => { event_date: "2024-02-06T20:59:23Z", event_name: "order_created", event_filter_id: "abc123", - source: "api", object_type: "subscription", event_properties: { duration: 142, video_title: "Brevo — The most approachable CRM suite" }, contact_properties: { AGE: 32, GENDER: "FEMALE" }, @@ -133,7 +132,7 @@ describe("EventClient", () => { test("createBatchEvents (1)", async () => { const server = mockServerPool.createServer(); const client = new BrevoClient({ maxRetries: 0, apiKey: "test", environment: server.baseUrl }); - const rawRequestBody = [{ event_name: "order_created", identifiers: {} }]; + const rawRequestBody = { events: [{ event_name: "order_created", identifiers: {} }] }; const rawResponseBody = { message: "Batch accepted. Valid events have been added to the processing queue.", count: 7, @@ -148,22 +147,26 @@ describe("EventClient", () => { .jsonBody(rawResponseBody) .build(); - const response = await client.event.createBatchEvents([ - { - event_name: "order_created", - identifiers: {}, - }, - ]); + const response = await client.event.createBatchEvents({ + events: [ + { + event_name: "order_created", + identifiers: {}, + }, + ], + }); expect(response).toEqual(rawResponseBody); }); test("createBatchEvents (2)", async () => { const server = mockServerPool.createServer(); const client = new BrevoClient({ maxRetries: 0, apiKey: "test", environment: server.baseUrl }); - const rawRequestBody = [ - { event_name: "event_name", identifiers: {} }, - { event_name: "event_name", identifiers: {} }, - ]; + const rawRequestBody = { + events: [ + { event_name: "event_name", identifiers: {} }, + { event_name: "event_name", identifiers: {} }, + ], + }; const rawResponseBody = { key: "value" }; server @@ -176,26 +179,30 @@ describe("EventClient", () => { .build(); await expect(async () => { - return await client.event.createBatchEvents([ - { - event_name: "event_name", - identifiers: {}, - }, - { - event_name: "event_name", - identifiers: {}, - }, - ]); + return await client.event.createBatchEvents({ + events: [ + { + event_name: "event_name", + identifiers: {}, + }, + { + event_name: "event_name", + identifiers: {}, + }, + ], + }); }).rejects.toThrow(Brevo.BadRequestError); }); test("createBatchEvents (3)", async () => { const server = mockServerPool.createServer(); const client = new BrevoClient({ maxRetries: 0, apiKey: "test", environment: server.baseUrl }); - const rawRequestBody = [ - { event_name: "event_name", identifiers: {} }, - { event_name: "event_name", identifiers: {} }, - ]; + const rawRequestBody = { + events: [ + { event_name: "event_name", identifiers: {} }, + { event_name: "event_name", identifiers: {} }, + ], + }; const rawResponseBody = { key: "value" }; server @@ -208,16 +215,18 @@ describe("EventClient", () => { .build(); await expect(async () => { - return await client.event.createBatchEvents([ - { - event_name: "event_name", - identifiers: {}, - }, - { - event_name: "event_name", - identifiers: {}, - }, - ]); + return await client.event.createBatchEvents({ + events: [ + { + event_name: "event_name", + identifiers: {}, + }, + { + event_name: "event_name", + identifiers: {}, + }, + ], + }); }).rejects.toThrow(Brevo.UnauthorizedError); }); }); diff --git a/tests/wire/externalFeeds.test.ts b/tests/wire/externalFeeds.test.ts index b89e271..a26bdd5 100644 --- a/tests/wire/externalFeeds.test.ts +++ b/tests/wire/externalFeeds.test.ts @@ -15,7 +15,6 @@ describe("ExternalFeedsClient", () => { { id: "b1c2d3e4-f5a6-47b8-89c0-d1e2f3a4b5c6", name: "Product Catalog Feed", - alias: "product_catalog_feed", url: "https://api.example.com/products", authType: "noAuth", username: "apiuser", @@ -23,7 +22,6 @@ describe("ExternalFeedsClient", () => { token: "abc123token456", maxRetries: 3, cache: true, - isInternal: false, headers: [{ name: "Authorization", value: "Bearer xyz789" }], createdAt: "2025-09-18T13:29:27Z", modifiedAt: "2025-09-18T13:29:27Z", @@ -31,15 +29,13 @@ describe("ExternalFeedsClient", () => { { id: "c2d3e4f5-a6b7-48c9-90d1-e2f3a4b5c6d7", name: "Blog News Feed", - alias: "blog_news_feed", url: "https://blog.example.com/api/posts", - authType: "noAuth", + authType: "token", username: "apiuser", password: "apipass", token: "abc123token456", maxRetries: 3, cache: true, - isInternal: true, headers: [{ name: "Authorization", value: "Bearer xyz789" }], createdAt: "2025-09-17T16:03:25Z", modifiedAt: "2025-09-17T16:03:25Z", @@ -47,15 +43,13 @@ describe("ExternalFeedsClient", () => { { id: "d3e4f5a6-b7c8-49d0-91e2-f3a4b5c6d7e8", name: "Public Data Feed", - alias: "public_data_feed", url: "https://jsonplaceholder.typicode.com/posts", - authType: "noAuth", + authType: "basic", username: "apiuser", password: "apipass", token: "abc123token456", maxRetries: 3, cache: true, - isInternal: true, headers: [{ name: "Authorization", value: "Bearer xyz789" }], createdAt: "2025-09-05T09:06:42Z", modifiedAt: "2025-09-05T09:06:42Z", @@ -223,12 +217,12 @@ describe("ExternalFeedsClient", () => { id: "b1c2d3e4-f5a6-47b8-89c0-d1e2f3a4b5c6", name: "Product Catalog Feed", url: "https://api.example.com/products", - authType: "noAuth", - personalization: false, - defaultAttr: "", - defaultContact: "", - maxRetries: 0, - cache: false, + authType: "token", + username: "api_user", + password: "secure_pass123", + token: "abc123token456", + maxRetries: 3, + cache: true, createdAt: "2025-09-18T13:29:27Z", modifiedAt: "2025-09-18T13:29:27Z", }; @@ -255,12 +249,12 @@ describe("ExternalFeedsClient", () => { id: "c2d3e4f5-a6b7-48c9-90d1-e2f3a4b5c6d7", name: "Internal Blog Feed", url: "https://blog.example.com/api/posts", - authType: "noAuth", - personalization: false, - defaultAttr: "", - defaultContact: "", - maxRetries: 0, - cache: false, + authType: "basic", + username: "apiuser", + password: "apipass", + token: "token_abc123", + maxRetries: 5, + cache: true, createdAt: "2025-09-17T16:03:25Z", modifiedAt: "2025-09-17T16:03:25Z", }; @@ -288,11 +282,11 @@ describe("ExternalFeedsClient", () => { name: "Public Data Feed", url: "https://jsonplaceholder.typicode.com/posts", authType: "noAuth", - personalization: false, - defaultAttr: "", - defaultContact: "", - maxRetries: 0, - cache: false, + username: "api_user", + password: "secure_pass123", + token: "token_abc123", + maxRetries: 5, + cache: true, createdAt: "2025-09-05T09:06:42Z", modifiedAt: "2025-09-05T09:06:42Z", }; diff --git a/tests/wire/files.test.ts b/tests/wire/files.test.ts index 36bdc74..b2bd983 100644 --- a/tests/wire/files.test.ts +++ b/tests/wire/files.test.ts @@ -11,13 +11,14 @@ describe("FilesClient", () => { const rawResponseBody = [ { - authorId: "61a5ce58y5d4795761045991", - companyId: "61a5ce58c5d4795761045991", + id: "61a5ce58c5d4795761045991", + name: "example.png", + authorId: "61a5ce58c5d4795761045991", contactId: 1, - createdAt: "2017-05-01T17:05:03Z", dealId: "61a5ce58c5d4795761045991", - name: "example.png", + companyId: "61a5ce58c5d4795761045991", size: 10, + createdAt: "2017-05-01T17:05:03Z", }, ]; @@ -131,13 +132,14 @@ describe("FilesClient", () => { const client = new BrevoClient({ maxRetries: 0, apiKey: "test", environment: server.baseUrl }); const rawResponseBody = { - authorId: "61a5ce58y5d4795761045991", - companyId: "61a5ce58c5d4795761045991", + id: "61a5ce58c5d4795761045991", + name: "example.png", + authorId: "61a5ce58c5d4795761045991", contactId: 1, - createdAt: "2017-05-01T17:05:03Z", dealId: "61a5ce58c5d4795761045991", - name: "example.png", + companyId: "61a5ce58c5d4795761045991", size: 10, + createdAt: "2017-05-01T17:05:03Z", }; server.mockEndpoint().get("/crm/files/id/data").respondWith().statusCode(200).jsonBody(rawResponseBody).build(); diff --git a/tests/wire/inboundParsing.test.ts b/tests/wire/inboundParsing.test.ts index 71a3e14..ba38b8f 100644 --- a/tests/wire/inboundParsing.test.ts +++ b/tests/wire/inboundParsing.test.ts @@ -98,4 +98,25 @@ describe("InboundParsingClient", () => { }); }).rejects.toThrow(Brevo.BadRequestError); }); + + test("getInboundEmailEventsByUuid (3)", async () => { + const server = mockServerPool.createServer(); + const client = new BrevoClient({ maxRetries: 0, apiKey: "test", environment: server.baseUrl }); + + const rawResponseBody = { key: "value" }; + + server + .mockEndpoint() + .get("/inbound/events/uuid") + .respondWith() + .statusCode(404) + .jsonBody(rawResponseBody) + .build(); + + await expect(async () => { + return await client.inboundParsing.getInboundEmailEventsByUuid({ + uuid: "uuid", + }); + }).rejects.toThrow(Brevo.NotFoundError); + }); }); diff --git a/tests/wire/masterAccount.test.ts b/tests/wire/masterAccount.test.ts index 799cec6..cedc79b 100644 --- a/tests/wire/masterAccount.test.ts +++ b/tests/wire/masterAccount.test.ts @@ -91,7 +91,7 @@ describe("MasterAccountClient", () => { }).rejects.toThrow(Brevo.BadRequestError); }); - test("getAGroupDetails", async () => { + test("getAGroupDetails (1)", async () => { const server = mockServerPool.createServer(); const client = new BrevoClient({ maxRetries: 0, apiKey: "test", environment: server.baseUrl }); @@ -121,6 +121,27 @@ describe("MasterAccountClient", () => { expect(response).toEqual(rawResponseBody); }); + test("getAGroupDetails (2)", async () => { + const server = mockServerPool.createServer(); + const client = new BrevoClient({ maxRetries: 0, apiKey: "test", environment: server.baseUrl }); + + const rawResponseBody = { key: "value" }; + + server + .mockEndpoint() + .get("/corporate/group/id") + .respondWith() + .statusCode(400) + .jsonBody(rawResponseBody) + .build(); + + await expect(async () => { + return await client.masterAccount.getAGroupDetails({ + id: "id", + }); + }).rejects.toThrow(Brevo.BadRequestError); + }); + test("updateAGroupOfSubAccounts (1)", async () => { const server = mockServerPool.createServer(); const client = new BrevoClient({ maxRetries: 0, apiKey: "test", environment: server.baseUrl }); @@ -189,7 +210,7 @@ describe("MasterAccountClient", () => { }).rejects.toThrow(Brevo.BadRequestError); }); - test("getSubAccountGroups", async () => { + test("getSubAccountGroups (1)", async () => { const server = mockServerPool.createServer(); const client = new BrevoClient({ maxRetries: 0, apiKey: "test", environment: server.baseUrl }); @@ -205,7 +226,20 @@ describe("MasterAccountClient", () => { expect(response).toEqual(rawResponseBody); }); - test("getCorporateInvitedUsersList", async () => { + test("getSubAccountGroups (2)", async () => { + const server = mockServerPool.createServer(); + const client = new BrevoClient({ maxRetries: 0, apiKey: "test", environment: server.baseUrl }); + + const rawResponseBody = { key: "value" }; + + server.mockEndpoint().get("/corporate/groups").respondWith().statusCode(400).jsonBody(rawResponseBody).build(); + + await expect(async () => { + return await client.masterAccount.getSubAccountGroups(); + }).rejects.toThrow(Brevo.BadRequestError); + }); + + test("getCorporateInvitedUsersList (1)", async () => { const server = mockServerPool.createServer(); const client = new BrevoClient({ maxRetries: 0, apiKey: "test", environment: server.baseUrl }); @@ -258,7 +292,26 @@ describe("MasterAccountClient", () => { expect(response).toEqual(rawResponseBody); }); - test("listOfAllIPs", async () => { + test("getCorporateInvitedUsersList (2)", async () => { + const server = mockServerPool.createServer(); + const client = new BrevoClient({ maxRetries: 0, apiKey: "test", environment: server.baseUrl }); + + const rawResponseBody = { key: "value" }; + + server + .mockEndpoint() + .get("/corporate/invited/users") + .respondWith() + .statusCode(400) + .jsonBody(rawResponseBody) + .build(); + + await expect(async () => { + return await client.masterAccount.getCorporateInvitedUsersList(); + }).rejects.toThrow(Brevo.BadRequestError); + }); + + test("listOfAllIPs (1)", async () => { const server = mockServerPool.createServer(); const client = new BrevoClient({ maxRetries: 0, apiKey: "test", environment: server.baseUrl }); @@ -273,6 +326,19 @@ describe("MasterAccountClient", () => { expect(response).toEqual(rawResponseBody); }); + test("listOfAllIPs (2)", async () => { + const server = mockServerPool.createServer(); + const client = new BrevoClient({ maxRetries: 0, apiKey: "test", environment: server.baseUrl }); + + const rawResponseBody = { key: "value" }; + + server.mockEndpoint().get("/corporate/ip").respondWith().statusCode(400).jsonBody(rawResponseBody).build(); + + await expect(async () => { + return await client.masterAccount.listOfAllIPs(); + }).rejects.toThrow(Brevo.BadRequestError); + }); + test("getTheDetailsOfRequestedMasterAccount (1)", async () => { const server = mockServerPool.createServer(); const client = new BrevoClient({ maxRetries: 0, apiKey: "test", environment: server.baseUrl }); diff --git a/tests/wire/notes.test.ts b/tests/wire/notes.test.ts index a6c59fb..010c7c9 100644 --- a/tests/wire/notes.test.ts +++ b/tests/wire/notes.test.ts @@ -11,6 +11,11 @@ describe("NotesClient", () => { const rawResponseBody = [ { + id: "61a5cd07ca1347c82306ad09", + text: '

Meeting notes: Action item - visit Brevo for details.

', + contactIds: [247, 1, 2], + companyIds: ["61a5ce58c5d4795761045990", "61a5ce58c5d4795761045991"], + dealIds: ["61a5ce58c5d4795761045990", "61a5ce58c5d4795761045991"], authorId: { email: "johndoe@example.com", id: "61a5ce58y5d4795761045991", @@ -18,11 +23,7 @@ describe("NotesClient", () => { name: { fullName: "John Doe" }, timezone: "Asia/Kolkata", }, - contactIds: [247, 1, 2], createdAt: "2017-05-01T17:05:03Z", - dealIds: ["61a5ce58c5d4795761045990", "61a5ce58c5d4795761045991"], - id: "61a5cd07ca1347c82306ad09", - text: "In communication with client_dev for resolution of queries.", updatedAt: "2017-05-01T17:05:03Z", }, ]; @@ -49,7 +50,9 @@ describe("NotesClient", () => { test("createANote (1)", async () => { const server = mockServerPool.createServer(); const client = new BrevoClient({ maxRetries: 0, apiKey: "test", environment: server.baseUrl }); - const rawRequestBody = { text: "In communication with client_dev for resolution of queries." }; + const rawRequestBody = { + text: '

Meeting notes: Action item - visit Brevo for details.

', + }; const rawResponseBody = { id: "61a5cd07ca1347c82306ad09" }; server @@ -62,7 +65,7 @@ describe("NotesClient", () => { .build(); const response = await client.notes.createANote({ - text: "In communication with client_dev for resolution of queries.", + text: '

Meeting notes: Action item - visit Brevo for details.

', }); expect(response).toEqual(rawResponseBody); }); @@ -116,6 +119,11 @@ describe("NotesClient", () => { const client = new BrevoClient({ maxRetries: 0, apiKey: "test", environment: server.baseUrl }); const rawResponseBody = { + id: "61a5cd07ca1347c82306ad09", + text: '

Meeting notes: Action item - visit Brevo for details.

', + contactIds: [247, 1, 2], + companyIds: ["61a5ce58c5d4795761045990", "61a5ce58c5d4795761045991"], + dealIds: ["61a5ce58c5d4795761045990", "61a5ce58c5d4795761045991"], authorId: { email: "johndoe@example.com", id: "61a5ce58y5d4795761045991", @@ -123,11 +131,7 @@ describe("NotesClient", () => { name: { fullName: "John Doe" }, timezone: "Asia/Kolkata", }, - contactIds: [247, 1, 2], createdAt: "2017-05-01T17:05:03Z", - dealIds: ["61a5ce58c5d4795761045990", "61a5ce58c5d4795761045991"], - id: "61a5cd07ca1347c82306ad09", - text: "In communication with client_dev for resolution of queries.", updatedAt: "2017-05-01T17:05:03Z", }; @@ -214,14 +218,16 @@ describe("NotesClient", () => { test("updateANote (1)", async () => { const server = mockServerPool.createServer(); const client = new BrevoClient({ maxRetries: 0, apiKey: "test", environment: server.baseUrl }); - const rawRequestBody = { text: "In communication with client_dev for resolution of queries." }; + const rawRequestBody = { + text: '

Meeting notes: Action item - visit Brevo for details.

', + }; server.mockEndpoint().patch("/crm/notes/id").jsonBody(rawRequestBody).respondWith().statusCode(200).build(); const response = await client.notes.updateANote({ id: "id", body: { - text: "In communication with client_dev for resolution of queries.", + text: '

Meeting notes: Action item - visit Brevo for details.

', }, }); expect(response).toEqual(undefined); diff --git a/tests/wire/process.test.ts b/tests/wire/process.test.ts index 24a7ae6..30a6b00 100644 --- a/tests/wire/process.test.ts +++ b/tests/wire/process.test.ts @@ -17,27 +17,18 @@ describe("ProcessClient", () => { name: "IMPORTUSER", status: "completed", export_url: "https://s3.eu-west-1.amazonaws.com/api-export.example.com/upload/contacts_export.csv", - error: "Processing timeout exceeded", - created_at: "2024-01-15T10:30:00Z", - completed_at: "2024-01-15T10:35:00Z", }, { id: 213, name: "SEARCH_EXPORT_USERS", status: "completed", export_url: "https://s3.eu-west-1.amazonaws.com/api-export.example.com/upload/contacts_export.csv", - error: "Processing timeout exceeded", - created_at: "2024-01-15T10:30:00Z", - completed_at: "2024-01-15T10:35:00Z", }, { id: 212, name: "IMPORTUSER", status: "queued", export_url: "https://s3.eu-west-1.amazonaws.com/api-export.example.com/upload/contacts_export.csv", - error: "Processing timeout exceeded", - created_at: "2024-01-15T10:30:00Z", - completed_at: "2024-01-15T10:35:00Z", }, ], }; @@ -71,20 +62,16 @@ describe("ProcessClient", () => { status: "queued", info: { import: { - invalid_emails: 2, - duplicate_contact_id: 0, - duplicate_ext_id: 1, + invalid_emails: "invalid_emails", + duplicate_contact_id: "duplicate_contact_id", + duplicate_ext_id: "duplicate_ext_id", duplicate_email_id: "duplicate_email_id", - duplicate_phone_id: 1, - duplicate_whatsapp_id: 1, - duplicate_landline_number_id: 1, + duplicate_phone_id: "duplicate_phone_id", + duplicate_whatsapp_id: "duplicate_whatsapp_id", + duplicate_landline_number_id: "duplicate_landline_number_id", }, - export: { total_records: 1250, file_size: 102400 }, }, export_url: "https://s3.eu-west-1.amazonaws.com/api-export.example.com/upload/contacts_export.csv", - error: "Processing timeout exceeded after 30 minutes", - created_at: "2024-01-15T10:30:00Z", - completed_at: "2024-01-15T10:32:15Z", }; server.mockEndpoint().get("/processes/1000000").respondWith().statusCode(200).jsonBody(rawResponseBody).build(); @@ -103,11 +90,7 @@ describe("ProcessClient", () => { id: 217, name: "IMPORTUSER", status: "completed", - info: { export: { total_records: 1250, file_size: 102400 } }, export_url: "https://s3.eu-west-1.amazonaws.com/api-export.example.com/upload/contacts_export.csv", - error: "Processing timeout exceeded after 30 minutes", - created_at: "2024-01-15T10:30:00Z", - completed_at: "2024-01-15T10:32:15Z", }; server.mockEndpoint().get("/processes/1000000").respondWith().statusCode(200).jsonBody(rawResponseBody).build(); @@ -128,20 +111,16 @@ describe("ProcessClient", () => { status: "completed", info: { import: { - invalid_emails: 2, - duplicate_contact_id: 0, - duplicate_ext_id: 1, + invalid_emails: "invalid_emails", + duplicate_contact_id: "duplicate_contact_id", + duplicate_ext_id: "duplicate_ext_id", duplicate_email_id: "duplicate_email_id", - duplicate_phone_id: 1, - duplicate_whatsapp_id: 1, - duplicate_landline_number_id: 1, + duplicate_phone_id: "duplicate_phone_id", + duplicate_whatsapp_id: "duplicate_whatsapp_id", + duplicate_landline_number_id: "duplicate_landline_number_id", }, - export: { total_records: 1250, file_size: 102400 }, }, export_url: "https://s3.eu-west-1.amazonaws.com/api-export.example.com/upload/contacts_export.csv", - error: "Processing timeout exceeded after 30 minutes", - created_at: "2024-01-15T10:30:00Z", - completed_at: "2024-01-15T10:32:15Z", }; server.mockEndpoint().get("/processes/1000000").respondWith().statusCode(200).jsonBody(rawResponseBody).build(); @@ -156,40 +135,6 @@ describe("ProcessClient", () => { const server = mockServerPool.createServer(); const client = new BrevoClient({ maxRetries: 0, apiKey: "test", environment: server.baseUrl }); - const rawResponseBody = { - id: 189, - name: "TRANS-GLOBAL-CALC", - status: "failed", - info: { - import: { - invalid_emails: 2, - duplicate_contact_id: 0, - duplicate_ext_id: 1, - duplicate_email_id: "duplicate_email_id", - duplicate_phone_id: 1, - duplicate_whatsapp_id: 1, - duplicate_landline_number_id: 1, - }, - export: { total_records: 1250, file_size: 102400 }, - }, - export_url: "https://s3.eu-west-1.amazonaws.com/api-export.example.com/upload/contacts_export.csv", - error: "Processing timeout exceeded after 30 minutes", - created_at: "2024-01-15T10:30:00Z", - completed_at: "2024-01-15T10:32:15Z", - }; - - server.mockEndpoint().get("/processes/1000000").respondWith().statusCode(200).jsonBody(rawResponseBody).build(); - - const response = await client.process.getProcess({ - processId: 1000000, - }); - expect(response).toEqual(rawResponseBody); - }); - - test("getProcess (5)", async () => { - const server = mockServerPool.createServer(); - const client = new BrevoClient({ maxRetries: 0, apiKey: "test", environment: server.baseUrl }); - const rawResponseBody = { key: "value" }; server.mockEndpoint().get("/processes/1000000").respondWith().statusCode(400).jsonBody(rawResponseBody).build(); @@ -201,7 +146,7 @@ describe("ProcessClient", () => { }).rejects.toThrow(Brevo.BadRequestError); }); - test("getProcess (6)", async () => { + test("getProcess (5)", async () => { const server = mockServerPool.createServer(); const client = new BrevoClient({ maxRetries: 0, apiKey: "test", environment: server.baseUrl }); diff --git a/tests/wire/program.test.ts b/tests/wire/program.test.ts index 0f222d5..2e9497a 100644 --- a/tests/wire/program.test.ts +++ b/tests/wire/program.test.ts @@ -12,18 +12,19 @@ describe("ProgramClient", () => { const rawResponseBody = { items: [ { - codeCount: 1, - createdAt: "createdAt", - description: "description", - documentId: "documentId", id: "id", - meta: { key: "value" }, name: "name", - pattern: "pattern", + description: "description", + meta: { key: "value" }, state: "inactive", - subscriptionGeneratorId: "subscriptionGeneratorId", subscriptionPoolId: "subscriptionPoolId", - updatedAt: "updatedAt", + subscriptionGeneratorId: "subscriptionGeneratorId", + pattern: "pattern", + codeCount: 1000000, + documentId: "documentId", + birthdayAttribute: "birthdayAttribute", + createdAt: "2024-01-15T09:30:00Z", + updatedAt: "2024-01-15T09:30:00Z", }, ], }; @@ -159,18 +160,19 @@ describe("ProgramClient", () => { const client = new BrevoClient({ maxRetries: 0, apiKey: "test", environment: server.baseUrl }); const rawRequestBody = { name: "name" }; const rawResponseBody = { - codeCount: 1, - createdAt: "createdAt", - description: "description", - documentId: "documentId", id: "id", - meta: { key: "value" }, name: "name", - pattern: "pattern", + description: "description", + meta: { key: "value" }, state: "inactive", - subscriptionGeneratorId: "subscriptionGeneratorId", subscriptionPoolId: "subscriptionPoolId", - updatedAt: "updatedAt", + subscriptionGeneratorId: "subscriptionGeneratorId", + pattern: "pattern", + codeCount: 1000000, + documentId: "documentId", + birthdayAttribute: "birthdayAttribute", + createdAt: "2024-01-15T09:30:00Z", + updatedAt: "2024-01-15T09:30:00Z", }; server @@ -303,18 +305,19 @@ describe("ProgramClient", () => { const client = new BrevoClient({ maxRetries: 0, apiKey: "test", environment: server.baseUrl }); const rawResponseBody = { - codeCount: 1, - createdAt: "createdAt", - description: "description", - documentId: "documentId", id: "id", - meta: { key: "value" }, name: "name", - pattern: "pattern", + description: "description", + meta: { key: "value" }, state: "inactive", - subscriptionGeneratorId: "subscriptionGeneratorId", subscriptionPoolId: "subscriptionPoolId", - updatedAt: "updatedAt", + subscriptionGeneratorId: "subscriptionGeneratorId", + pattern: "pattern", + codeCount: 1000000, + documentId: "documentId", + birthdayAttribute: "birthdayAttribute", + createdAt: "2024-01-15T09:30:00Z", + updatedAt: "2024-01-15T09:30:00Z", }; server @@ -441,18 +444,19 @@ describe("ProgramClient", () => { const client = new BrevoClient({ maxRetries: 0, apiKey: "test", environment: server.baseUrl }); const rawRequestBody = { name: "name" }; const rawResponseBody = { - codeCount: 1, - createdAt: "createdAt", - description: "description", - documentId: "documentId", id: "id", - meta: { key: "value" }, name: "name", - pattern: "pattern", + description: "description", + meta: { key: "value" }, state: "inactive", - subscriptionGeneratorId: "subscriptionGeneratorId", subscriptionPoolId: "subscriptionPoolId", - updatedAt: "updatedAt", + subscriptionGeneratorId: "subscriptionGeneratorId", + pattern: "pattern", + codeCount: 1000000, + documentId: "documentId", + birthdayAttribute: "birthdayAttribute", + createdAt: "2024-01-15T09:30:00Z", + updatedAt: "2024-01-15T09:30:00Z", }; server @@ -731,18 +735,19 @@ describe("ProgramClient", () => { const client = new BrevoClient({ maxRetries: 0, apiKey: "test", environment: server.baseUrl }); const rawRequestBody = {}; const rawResponseBody = { - codeCount: 1, - createdAt: "createdAt", - description: "description", - documentId: "documentId", id: "id", - meta: { key: "value" }, name: "name", - pattern: "pattern", + description: "description", + meta: { key: "value" }, state: "inactive", - subscriptionGeneratorId: "subscriptionGeneratorId", subscriptionPoolId: "subscriptionPoolId", - updatedAt: "updatedAt", + subscriptionGeneratorId: "subscriptionGeneratorId", + pattern: "pattern", + codeCount: 1000000, + documentId: "documentId", + birthdayAttribute: "birthdayAttribute", + createdAt: "2024-01-15T09:30:00Z", + updatedAt: "2024-01-15T09:30:00Z", }; server @@ -909,7 +914,8 @@ describe("ProgramClient", () => { loyaltyProgramId: "loyaltyProgramId", meta: { key: "value" }, rewardId: "rewardId", - updatedAt: "updatedAt", + updatedAt: "2024-01-15T09:30:00Z", + validFrom: "2024-01-15T09:30:00Z", }, ], tier: [ @@ -1311,11 +1317,11 @@ describe("ProgramClient", () => { const client = new BrevoClient({ maxRetries: 0, apiKey: "test", environment: server.baseUrl }); const rawRequestBody = { memberContactIds: [1] }; const rawResponseBody = { - createdAt: "createdAt", - memberContactIds: [1], - organizationId: 1, - ownerContactId: 1, - updatedAt: "updatedAt", + organizationId: 1000000, + ownerContactId: 1000000, + memberContactIds: [1000000], + createdAt: "2024-01-15T09:30:00Z", + updatedAt: "2024-01-15T09:30:00Z", }; server @@ -1625,15 +1631,16 @@ describe("ProgramClient", () => { test("subscribeToLoyaltyProgram (1)", async () => { const server = mockServerPool.createServer(); const client = new BrevoClient({ maxRetries: 0, apiKey: "test", environment: server.baseUrl }); - const rawRequestBody = { contactId: 1 }; + const rawRequestBody = { contactId: 1000000 }; const rawResponseBody = { - contactId: 1, - createdAt: "createdAt", + organizationId: 1000000, loyaltyProgramId: "loyaltyProgramId", - loyaltySubscriptionId: "loyaltySubscriptionId", - organizationId: 1, - updatedAt: "updatedAt", versionId: 1, + contactId: 1000000, + loyaltySubscriptionId: "loyaltySubscriptionId", + meta: { key: "value" }, + createdAt: "2024-01-15T09:30:00Z", + updatedAt: "2024-01-15T09:30:00Z", }; server @@ -1647,7 +1654,7 @@ describe("ProgramClient", () => { const response = await client.program.subscribeToLoyaltyProgram({ pid: "pid", - contactId: 1, + contactId: 1000000, }); expect(response).toEqual(rawResponseBody); }); @@ -1655,7 +1662,7 @@ describe("ProgramClient", () => { test("subscribeToLoyaltyProgram (2)", async () => { const server = mockServerPool.createServer(); const client = new BrevoClient({ maxRetries: 0, apiKey: "test", environment: server.baseUrl }); - const rawRequestBody = { contactId: 1 }; + const rawRequestBody = { contactId: 1000000 }; const rawResponseBody = { key: "value" }; server @@ -1670,7 +1677,7 @@ describe("ProgramClient", () => { await expect(async () => { return await client.program.subscribeToLoyaltyProgram({ pid: "pid", - contactId: 1, + contactId: 1000000, }); }).rejects.toThrow(Brevo.BadRequestError); }); @@ -1678,7 +1685,7 @@ describe("ProgramClient", () => { test("subscribeToLoyaltyProgram (3)", async () => { const server = mockServerPool.createServer(); const client = new BrevoClient({ maxRetries: 0, apiKey: "test", environment: server.baseUrl }); - const rawRequestBody = { contactId: 1 }; + const rawRequestBody = { contactId: 1000000 }; const rawResponseBody = { key: "value" }; server @@ -1693,7 +1700,7 @@ describe("ProgramClient", () => { await expect(async () => { return await client.program.subscribeToLoyaltyProgram({ pid: "pid", - contactId: 1, + contactId: 1000000, }); }).rejects.toThrow(Brevo.UnauthorizedError); }); @@ -1701,7 +1708,7 @@ describe("ProgramClient", () => { test("subscribeToLoyaltyProgram (4)", async () => { const server = mockServerPool.createServer(); const client = new BrevoClient({ maxRetries: 0, apiKey: "test", environment: server.baseUrl }); - const rawRequestBody = { contactId: 1 }; + const rawRequestBody = { contactId: 1000000 }; const rawResponseBody = { key: "value" }; server @@ -1716,7 +1723,7 @@ describe("ProgramClient", () => { await expect(async () => { return await client.program.subscribeToLoyaltyProgram({ pid: "pid", - contactId: 1, + contactId: 1000000, }); }).rejects.toThrow(Brevo.ForbiddenError); }); @@ -1724,7 +1731,7 @@ describe("ProgramClient", () => { test("subscribeToLoyaltyProgram (5)", async () => { const server = mockServerPool.createServer(); const client = new BrevoClient({ maxRetries: 0, apiKey: "test", environment: server.baseUrl }); - const rawRequestBody = { contactId: 1 }; + const rawRequestBody = { contactId: 1000000 }; const rawResponseBody = { key: "value" }; server @@ -1739,7 +1746,7 @@ describe("ProgramClient", () => { await expect(async () => { return await client.program.subscribeToLoyaltyProgram({ pid: "pid", - contactId: 1, + contactId: 1000000, }); }).rejects.toThrow(Brevo.NotFoundError); }); @@ -1747,7 +1754,7 @@ describe("ProgramClient", () => { test("subscribeToLoyaltyProgram (6)", async () => { const server = mockServerPool.createServer(); const client = new BrevoClient({ maxRetries: 0, apiKey: "test", environment: server.baseUrl }); - const rawRequestBody = { contactId: 1 }; + const rawRequestBody = { contactId: 1000000 }; const rawResponseBody = { message: "message" }; server @@ -1762,7 +1769,7 @@ describe("ProgramClient", () => { await expect(async () => { return await client.program.subscribeToLoyaltyProgram({ pid: "pid", - contactId: 1, + contactId: 1000000, }); }).rejects.toThrow(Brevo.UnprocessableEntityError); }); @@ -1770,7 +1777,7 @@ describe("ProgramClient", () => { test("subscribeToLoyaltyProgram (7)", async () => { const server = mockServerPool.createServer(); const client = new BrevoClient({ maxRetries: 0, apiKey: "test", environment: server.baseUrl }); - const rawRequestBody = { contactId: 1 }; + const rawRequestBody = { contactId: 1000000 }; const rawResponseBody = { key: "value" }; server @@ -1785,7 +1792,7 @@ describe("ProgramClient", () => { await expect(async () => { return await client.program.subscribeToLoyaltyProgram({ pid: "pid", - contactId: 1, + contactId: 1000000, }); }).rejects.toThrow(Brevo.InternalServerError); }); diff --git a/tests/wire/reward.test.ts b/tests/wire/reward.test.ts index 053a4f1..fa1d7a6 100644 --- a/tests/wire/reward.test.ts +++ b/tests/wire/reward.test.ts @@ -302,14 +302,14 @@ describe("RewardClient", () => { const client = new BrevoClient({ maxRetries: 0, apiKey: "test", environment: server.baseUrl }); const rawRequestBody = { name: "name" }; const rawResponseBody = { - createdAt: "2024-01-15T09:30:00Z", id: "id", loyaltyProgramId: "loyaltyProgramId", name: "name", publicDescription: "publicDescription", publicImage: "publicImage", publicName: "publicName", - updatedAt: "updatedAt", + createdAt: "2024-01-15T09:30:00Z", + updatedAt: "2024-01-15T09:30:00Z", }; server @@ -436,6 +436,7 @@ describe("RewardClient", () => { rewardId: "rewardId", updatedAt: "2024-01-15T09:30:00Z", value: 1.1, + validFrom: "2024-01-15T09:30:00Z", }; server @@ -1472,6 +1473,7 @@ describe("RewardClient", () => { unit: "unit", updatedAt: "updatedAt", value: 1.1, + validFrom: "2024-01-15T09:30:00Z", }, ], count: 1, diff --git a/tests/wire/senders.test.ts b/tests/wire/senders.test.ts index cb39ccd..91ebe04 100644 --- a/tests/wire/senders.test.ts +++ b/tests/wire/senders.test.ts @@ -254,7 +254,7 @@ describe("SendersClient", () => { const client = new BrevoClient({ maxRetries: 0, apiKey: "test", environment: server.baseUrl }); const rawResponseBody = { - ips: [{ active: true, domain: "mailing.enterprise.com", id: 3, ip: "192.168.1.100" }], + ips: [{ id: 1, active: true, domain: "mailing.enterprise.com", ip: "192.168.1.100" }], }; server.mockEndpoint().get("/senders/ips").respondWith().statusCode(200).jsonBody(rawResponseBody).build(); @@ -269,9 +269,9 @@ describe("SendersClient", () => { const rawResponseBody = { ips: [ - { active: true, domain: "mailing.enterprise.com", id: 3, ip: "192.168.1.100" }, - { active: true, domain: "newsletter.enterprise.com", id: 5, ip: "192.168.1.101" }, - { active: false, domain: "notifications.enterprise.com", id: 6, ip: "192.168.1.102" }, + { id: 1, active: true, domain: "mailing.enterprise.com", ip: "192.168.1.100" }, + { id: 1, active: true, domain: "newsletter.enterprise.com", ip: "192.168.1.101" }, + { id: 1, active: false, domain: "notifications.enterprise.com", ip: "192.168.1.102" }, ], }; diff --git a/tests/wire/smsCampaigns.test.ts b/tests/wire/smsCampaigns.test.ts index 6d6a40c..479aded 100644 --- a/tests/wire/smsCampaigns.test.ts +++ b/tests/wire/smsCampaigns.test.ts @@ -17,10 +17,13 @@ describe("SmsCampaignsClient", () => { id: 2, modifiedAt: "2017-05-01T12:30:00Z", name: "PROMO CODE", + organisationPrefix: "MyCompany", scheduledAt: "2017-06-01T12:30:00Z", sender: "MyCompany", + sentDate: "2017-06-01T12:30:00Z", status: "sent", - recipients: { exclusionLists: [13], lists: [21] }, + unsubscribeInstruction: "send Stop if you want to unsubscribe.", + recipients: { excludedSegments: [14], exclusionLists: [13], lists: [21], segments: [23] }, statistics: { answered: 2, delivered: 2987, @@ -37,10 +40,13 @@ describe("SmsCampaignsClient", () => { id: 10, modifiedAt: "2017-05-01T12:30:00Z", name: "SUMMER SALE", + organisationPrefix: "", scheduledAt: "2017-08-04T12:30:00Z", sender: "MyCompany", + sentDate: "2017-06-01T12:30:00Z", status: "draft", - recipients: { exclusionLists: [13], lists: [21] }, + unsubscribeInstruction: "", + recipients: { excludedSegments: [14], exclusionLists: [13], lists: [21], segments: [23] }, statistics: { answered: 2, delivered: 2987, @@ -135,10 +141,16 @@ describe("SmsCampaignsClient", () => { id: 2, modifiedAt: "2017-05-01T12:30:00Z", name: "PROMO CODE", + organisationPrefix: "MyCompany", scheduledAt: "2017-06-01T12:30:00Z", sender: "MyCompany", + sentDate: "2017-06-01T12:30:00Z", status: "sent", - recipients: { exclusionLists: [13], lists: [21] }, + unsubscribeInstruction: "send Stop if you want to unsubscribe.", + recipients: { + exclusionLists: [{ id: 13, name: "Exclusion List" }], + lists: [{ id: 21, name: "Main List" }], + }, statistics: { answered: 2, delivered: 2987, @@ -148,6 +160,7 @@ describe("SmsCampaignsClient", () => { softBounces: 3, unsubscriptions: 3, }, + tags: ["promo"], }; server diff --git a/tests/wire/tasks.test.ts b/tests/wire/tasks.test.ts index 9c2f9e8..ae99a5d 100644 --- a/tests/wire/tasks.test.ts +++ b/tests/wire/tasks.test.ts @@ -12,12 +12,18 @@ describe("TasksClient", () => { const rawResponseBody = { items: [ { - companiesIds: ["61a5ce58c5d4795761045990", "61a5ce58c5d4795761045991", "61a5ce58c5d4795761045992"], - contactsIds: [1, 2, 3], - dealsIds: ["61a5ce58c5d4795761045990", "61a5ce58c5d4795761045991", "61a5ce58c5d4795761045992"], id: "61a5cd07ca1347c82306ad06", - name: "Task: Connect with client_dev", taskTypeId: "61a5cd07ca1347c82306ad09", + name: "Task: Connect with client", + companiesIds: ["61a5ce58c5d4795761045990", "61a5ce58c5d4795761045991", "61a5ce58c5d4795761045992"], + dealsIds: ["61a5ce58c5d4795761045990", "61a5ce58c5d4795761045991", "61a5ce58c5d4795761045992"], + contactsIds: [1, 2, 3], + assignToId: "5faab4b7f195bb3c4c31e62a", + date: "2021-11-01T17:44:54Z", + notes: "In communication with client for resolution of queries.", + done: false, + createdAt: "2021-11-01T17:44:54Z", + updatedAt: "2021-11-01T17:44:54Z", }, ], }; @@ -48,7 +54,7 @@ describe("TasksClient", () => { const client = new BrevoClient({ maxRetries: 0, apiKey: "test", environment: server.baseUrl }); const rawRequestBody = { date: "2021-11-01T17:44:54Z", - name: "Task: Connect with client_dev", + name: "Task: Connect with client", taskTypeId: "61a5cd07ca1347c82306ad09", }; const rawResponseBody = { id: "61a5cd07ca1347c82306ad06" }; @@ -64,7 +70,7 @@ describe("TasksClient", () => { const response = await client.tasks.createATask({ date: "2021-11-01T17:44:54Z", - name: "Task: Connect with client_dev", + name: "Task: Connect with client", taskTypeId: "61a5cd07ca1347c82306ad09", }); expect(response).toEqual(rawResponseBody); @@ -99,12 +105,18 @@ describe("TasksClient", () => { const client = new BrevoClient({ maxRetries: 0, apiKey: "test", environment: server.baseUrl }); const rawResponseBody = { - companiesIds: ["61a5ce58c5d4795761045990", "61a5ce58c5d4795761045991", "61a5ce58c5d4795761045992"], - contactsIds: [1, 2, 3], - dealsIds: ["61a5ce58c5d4795761045990", "61a5ce58c5d4795761045991", "61a5ce58c5d4795761045992"], id: "61a5cd07ca1347c82306ad06", - name: "Task: Connect with client_dev", taskTypeId: "61a5cd07ca1347c82306ad09", + name: "Task: Connect with client", + companiesIds: ["61a5ce58c5d4795761045990", "61a5ce58c5d4795761045991", "61a5ce58c5d4795761045992"], + dealsIds: ["61a5ce58c5d4795761045990", "61a5ce58c5d4795761045991", "61a5ce58c5d4795761045992"], + contactsIds: [1, 2, 3], + assignToId: "5faab4b7f195bb3c4c31e62a", + date: "2021-11-01T17:44:54Z", + notes: "In communication with client for resolution of queries.", + done: false, + createdAt: "2021-11-01T17:44:54Z", + updatedAt: "2021-11-01T17:44:54Z", }; server.mockEndpoint().get("/crm/tasks/id").respondWith().statusCode(200).jsonBody(rawResponseBody).build(); @@ -244,15 +256,28 @@ describe("TasksClient", () => { }).rejects.toThrow(Brevo.NotFoundError); }); - test("getAllTaskTypes", async () => { + test("getAllTaskTypes (1)", async () => { const server = mockServerPool.createServer(); const client = new BrevoClient({ maxRetries: 0, apiKey: "test", environment: server.baseUrl }); - const rawResponseBody = { id: "61a88a2eb7a574180261234", title: "Email" }; + const rawResponseBody = [{ id: "61a88a2eb7a574180261234", title: "Email" }]; server.mockEndpoint().get("/crm/tasktypes").respondWith().statusCode(200).jsonBody(rawResponseBody).build(); const response = await client.tasks.getAllTaskTypes(); expect(response).toEqual(rawResponseBody); }); + + test("getAllTaskTypes (2)", async () => { + const server = mockServerPool.createServer(); + const client = new BrevoClient({ maxRetries: 0, apiKey: "test", environment: server.baseUrl }); + + const rawResponseBody = { key: "value" }; + + server.mockEndpoint().get("/crm/tasktypes").respondWith().statusCode(400).jsonBody(rawResponseBody).build(); + + await expect(async () => { + return await client.tasks.getAllTaskTypes(); + }).rejects.toThrow(Brevo.BadRequestError); + }); }); diff --git a/tests/wire/tier.test.ts b/tests/wire/tier.test.ts index 0bca4c0..0cd7b61 100644 --- a/tests/wire/tier.test.ts +++ b/tests/wire/tier.test.ts @@ -347,6 +347,20 @@ describe("TierClient", () => { tierOrder: ["tierOrder"], updatedAt: "2024-01-15T09:30:00Z", upgradeStrategy: "real_time", + upgradeSchedule: { + strategy: "strategy", + durationValue: 1, + durationUnit: "day", + durationModifier: "start_of_period", + scheduledDate: "scheduledDate", + }, + downgradeSchedule: { + strategy: "strategy", + durationValue: 1, + durationUnit: "day", + durationModifier: "start_of_period", + scheduledDate: "scheduledDate", + }, }; server @@ -516,6 +530,20 @@ describe("TierClient", () => { tierOrder: ["tierOrder"], updatedAt: "2024-01-15T09:30:00Z", upgradeStrategy: "real_time", + upgradeSchedule: { + strategy: "strategy", + durationValue: 1, + durationUnit: "day", + durationModifier: "start_of_period", + scheduledDate: "scheduledDate", + }, + downgradeSchedule: { + strategy: "strategy", + durationValue: 1, + durationUnit: "day", + durationModifier: "start_of_period", + scheduledDate: "scheduledDate", + }, }; server @@ -661,6 +689,20 @@ describe("TierClient", () => { tierOrder: ["tierOrder"], updatedAt: "2024-01-15T09:30:00Z", upgradeStrategy: "real_time", + upgradeSchedule: { + strategy: "strategy", + durationValue: 1, + durationUnit: "day", + durationModifier: "start_of_period", + scheduledDate: "scheduledDate", + }, + downgradeSchedule: { + strategy: "strategy", + durationValue: 1, + durationUnit: "day", + durationModifier: "start_of_period", + scheduledDate: "scheduledDate", + }, }; server diff --git a/tests/wire/transactionalEmails.test.ts b/tests/wire/transactionalEmails.test.ts index 682b720..e8c92b9 100644 --- a/tests/wire/transactionalEmails.test.ts +++ b/tests/wire/transactionalEmails.test.ts @@ -106,7 +106,7 @@ describe("TransactionalEmailsClient", () => { }).rejects.toThrow(Brevo.NotFoundError); }); - test("getBlockedDomains", async () => { + test("getBlockedDomains (1)", async () => { const server = mockServerPool.createServer(); const client = new BrevoClient({ maxRetries: 0, apiKey: "test", environment: server.baseUrl }); @@ -124,6 +124,25 @@ describe("TransactionalEmailsClient", () => { expect(response).toEqual(rawResponseBody); }); + test("getBlockedDomains (2)", async () => { + const server = mockServerPool.createServer(); + const client = new BrevoClient({ maxRetries: 0, apiKey: "test", environment: server.baseUrl }); + + const rawResponseBody = { key: "value" }; + + server + .mockEndpoint() + .get("/smtp/blockedDomains") + .respondWith() + .statusCode(400) + .jsonBody(rawResponseBody) + .build(); + + await expect(async () => { + return await client.transactionalEmails.getBlockedDomains(); + }).rejects.toThrow(Brevo.BadRequestError); + }); + test("blockNewDomain (1)", async () => { const server = mockServerPool.createServer(); const client = new BrevoClient({ maxRetries: 0, apiKey: "test", environment: server.baseUrl }); @@ -564,7 +583,7 @@ describe("TransactionalEmailsClient", () => { }).rejects.toThrow(Brevo.BadRequestError); }); - test("getTransacEmailContent", async () => { + test("getTransacEmailContent (1)", async () => { const server = mockServerPool.createServer(); const client = new BrevoClient({ maxRetries: 0, apiKey: "test", environment: server.baseUrl }); @@ -590,6 +609,36 @@ describe("TransactionalEmailsClient", () => { expect(response).toEqual(rawResponseBody); }); + test("getTransacEmailContent (2)", async () => { + const server = mockServerPool.createServer(); + const client = new BrevoClient({ maxRetries: 0, apiKey: "test", environment: server.baseUrl }); + + const rawResponseBody = { key: "value" }; + + server.mockEndpoint().get("/smtp/emails/uuid").respondWith().statusCode(400).jsonBody(rawResponseBody).build(); + + await expect(async () => { + return await client.transactionalEmails.getTransacEmailContent({ + uuid: "uuid", + }); + }).rejects.toThrow(Brevo.BadRequestError); + }); + + test("getTransacEmailContent (3)", async () => { + const server = mockServerPool.createServer(); + const client = new BrevoClient({ maxRetries: 0, apiKey: "test", environment: server.baseUrl }); + + const rawResponseBody = { key: "value" }; + + server.mockEndpoint().get("/smtp/emails/uuid").respondWith().statusCode(404).jsonBody(rawResponseBody).build(); + + await expect(async () => { + return await client.transactionalEmails.getTransacEmailContent({ + uuid: "uuid", + }); + }).rejects.toThrow(Brevo.NotFoundError); + }); + test("deleteAnSmtpTransactionalLog (1)", async () => { const server = mockServerPool.createServer(); const client = new BrevoClient({ maxRetries: 0, apiKey: "test", environment: server.baseUrl }); @@ -710,7 +759,7 @@ describe("TransactionalEmailsClient", () => { link: "https://www.someexamplelink.com", messageId: "<201798300811.5787683@example.domain.com>", reason: "Error connection timeout", - subject: "Sib client_dev test", + subject: "Sib client test", tag: "OrderConfirmation", templateId: 4, }, @@ -723,7 +772,7 @@ describe("TransactionalEmailsClient", () => { link: "https://www.someexamplelink.com", messageId: "<201798300811.5787683@example.domain.com>", reason: "Error connection timeout", - subject: "Sib client_dev test", + subject: "Sib client test", tag: "OrderConfirmation", templateId: 5, }, @@ -897,11 +946,12 @@ describe("TransactionalEmailsClient", () => { modifiedAt: "2016-02-24T15:37:11Z", name: "ChristomasTimeTemplate", replyTo: "replyto@domain.com", - sender: { email: "john.smith@example.com", id: "43", name: "John" }, + sender: { email: "john.smith@example.com", id: "id", name: "John" }, subject: "Merry Christmas", tag: "Festival", testSent: false, toField: "", + customTemplateId: "my-custom-template-001", }, { createdAt: "2016-02-25T11:53:26Z", @@ -912,11 +962,12 @@ describe("TransactionalEmailsClient", () => { modifiedAt: "2016-02-25T11:53:26Z", name: "SummerSales2017Template", replyTo: "replyto@domain.com", - sender: { email: "john.smith@example.com", id: "43", name: "John" }, + sender: { email: "john.smith@example.com", id: "id", name: "John" }, subject: "Enjoy our summer Sales !", tag: "Summer", testSent: false, toField: "", + customTemplateId: "my-custom-template-001", }, ], }; @@ -1004,11 +1055,12 @@ describe("TransactionalEmailsClient", () => { modifiedAt: "2016-02-25T11:53:26Z", name: "OrderConfirmation", replyTo: "replyto@domain.com", - sender: { email: "john.smith@example.com", id: "43", name: "John" }, + sender: { email: "john.smith@example.com", id: "id", name: "John" }, subject: "Order Confirmation : Thanks for your Purchase !", tag: "", testSent: false, toField: "", + customTemplateId: "my-custom-template-001", }; server diff --git a/tests/wire/transactionalSms.test.ts b/tests/wire/transactionalSms.test.ts index 5d6adfe..5d019af 100644 --- a/tests/wire/transactionalSms.test.ts +++ b/tests/wire/transactionalSms.test.ts @@ -124,6 +124,29 @@ describe("TransactionalSmsClient", () => { }).rejects.toThrow(Brevo.PaymentRequiredError); }); + test("sendTransacSms (4)", async () => { + const server = mockServerPool.createServer(); + const client = new BrevoClient({ maxRetries: 0, apiKey: "test", environment: server.baseUrl }); + const rawRequestBody = { recipient: "recipient", sender: "sender" }; + const rawResponseBody = { message: "message" }; + + server + .mockEndpoint() + .post("/transactionalSMS/sms") + .jsonBody(rawRequestBody) + .respondWith() + .statusCode(429) + .jsonBody(rawResponseBody) + .build(); + + await expect(async () => { + return await client.transactionalSms.sendTransacSms({ + recipient: "recipient", + sender: "sender", + }); + }).rejects.toThrow(Brevo.TooManyRequestsError); + }); + test("getTransacAggregatedSmsReport (1)", async () => { const server = mockServerPool.createServer(); const client = new BrevoClient({ maxRetries: 0, apiKey: "test", environment: server.baseUrl }); diff --git a/tests/wire/webhooks.test.ts b/tests/wire/webhooks.test.ts index 9d3e4ec..57bcbb2 100644 --- a/tests/wire/webhooks.test.ts +++ b/tests/wire/webhooks.test.ts @@ -14,7 +14,6 @@ describe("WebhooksClient", () => { { auth: { token: "test-auth-token1234", type: "bearer" }, batched: true, - channel: "email", createdAt: "2016-07-18T12:30:09Z", description: "Webhook triggered on campaign openings", events: ["opened"], @@ -22,19 +21,20 @@ describe("WebhooksClient", () => { id: 9864, modifiedAt: "2016-07-18T16:00:50Z", type: "transactional", + domain: "example.com", url: "https://example.domain.com/webhook/events/kzfxxxxxxxx0uyo1", }, { auth: { token: "test-auth-token1234", type: "bearer" }, batched: true, - channel: "sms", createdAt: "2017-02-20T14:30:00Z", description: "Webhook triggered on campaign hard bounces", - events: ["hardBounces"], + events: ["hardBounce"], headers: [{ key: "cf-secret", value: "test-header-value" }], id: 22770, modifiedAt: "2017-02-20T19:00:00Z", type: "marketing", + domain: "example.com", url: "http://exmaple.domain.com/15kxxxxxn1", }, ], @@ -62,7 +62,7 @@ describe("WebhooksClient", () => { test("createWebhook (1)", async () => { const server = mockServerPool.createServer(); const client = new BrevoClient({ maxRetries: 0, apiKey: "test", environment: server.baseUrl }); - const rawRequestBody = { events: ["sent"], url: "http://requestb.in/173lyyx1" }; + const rawRequestBody = { url: "http://requestb.in/173lyyx1" }; const rawResponseBody = { id: 5 }; server @@ -75,7 +75,6 @@ describe("WebhooksClient", () => { .build(); const response = await client.webhooks.createWebhook({ - events: ["sent"], url: "http://requestb.in/173lyyx1", }); expect(response).toEqual(rawResponseBody); @@ -84,7 +83,7 @@ describe("WebhooksClient", () => { test("createWebhook (2)", async () => { const server = mockServerPool.createServer(); const client = new BrevoClient({ maxRetries: 0, apiKey: "test", environment: server.baseUrl }); - const rawRequestBody = { events: ["sent", "sent"], url: "url" }; + const rawRequestBody = { url: "url" }; const rawResponseBody = { key: "value" }; server @@ -98,7 +97,6 @@ describe("WebhooksClient", () => { await expect(async () => { return await client.webhooks.createWebhook({ - events: ["sent", "sent"], url: "url", }); }).rejects.toThrow(Brevo.BadRequestError); @@ -158,14 +156,14 @@ describe("WebhooksClient", () => { const rawResponseBody = { auth: { token: "test-auth-token1234", type: "bearer" }, batched: true, - channel: "sms", createdAt: "2016-06-07T09:10:10Z", description: "Webhook triggered on campaign openings and addition of lists", - events: ["listAdditions", "opened"], + events: ["listAddition", "opened"], headers: [{ key: "cf-secret", value: "test-header-value" }], id: 7287, modifiedAt: "2016-06-08T11:30:00Z", type: "marketing", + domain: "example.com", url: "http://example.domain.com/1brxxxxxx5p1", }; diff --git a/tests/wire/whatsAppCampaigns.test.ts b/tests/wire/whatsAppCampaigns.test.ts index bf2f877..9f365dd 100644 --- a/tests/wire/whatsAppCampaigns.test.ts +++ b/tests/wire/whatsAppCampaigns.test.ts @@ -215,6 +215,7 @@ describe("WhatsAppCampaignsClient", () => { modifiedAt: "2017-05-01T12:30:00Z", name: "campaign_22", status: "approved", + type: "whatsapp", }, { category: "MARKETING", @@ -225,6 +226,7 @@ describe("WhatsAppCampaignsClient", () => { modifiedAt: "2017-05-01T12:30:00Z", name: "test-template", status: "draft", + type: "whatsapp", }, ], }; @@ -309,6 +311,7 @@ describe("WhatsAppCampaignsClient", () => { id: 1672035851100690, modifiedAt: "2022-12-26T08:50:00Z", scheduledAt: "2022-12-27T09:50:00Z", + recipients: { excludedLists: [45], includedLists: [22], segments: [23], type: "list" }, senderNumber: "senderNumber", stats: { delivered: 3, notSent: 4, read: 2, sent: 3, unsubscribe: 0 }, template: {