mailgun.js 12.0.3 → 12.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -10,11 +10,14 @@ __Table of Contents__
10
10
  - [Install](#install)
11
11
  - [Setup Client](#setup-client)
12
12
  - [Available Imports](#imports)
13
- - [Using Subaccounts](#using-subaccounts)
14
13
  - [Types imports](#types-imports)
15
14
  - [Interfaces and Enums imports](#interfaces-and-enums-imports)
15
+ - [Fetch API usage](#fetch-api-usage)
16
+ - [Proxy configuration](proxy-configuration)
17
+ - [SubAccounts](#using-subaccounts)
16
18
  - [Generated docs](#generated-docs)
17
19
  - [Methods](#methods)
20
+ - [Pagination](#pagination)
18
21
  - [Browser Demo](#browser-demo)
19
22
  - [Examples](https://github.com/mailgun/mailgun-js/tree/master/examples)
20
23
  - [Development](#development)
@@ -48,16 +51,14 @@ NOTE: starting from version 3.0 you need to pass FormData (we need this to keep
48
51
  Once the package is installed, you can import the library using `import` or `require` approach:
49
52
 
50
53
  ```js
51
- const formData = require('form-data'); // or built-in FormData
52
54
  const Mailgun = require('mailgun.js');
53
- const mailgun = new Mailgun(formData);
54
- const mg = mailgun.client({username: 'api', key: process.env.MAILGUN_API_KEY || 'key-yourkeyhere'});
55
+ const mailgun = new Mailgun(FormData); // or const formData = require('form-data');
56
+ const mg = mailgun.client({username: 'api', key: process.env.MAILGUN_API_KEY || 'key-{yourkeyhere}'});
55
57
  ```
56
58
  ```js
57
- import FormData from 'form-data'; // or built-in FormData
58
59
  import Mailgun from 'mailgun.js';
59
- const mailgun = new Mailgun(FormData);
60
- const mg = mailgun.client({username: 'api', key: process.env.MAILGUN_API_KEY || 'key-yourkeyhere'});
60
+ const mailgun = new Mailgun(FormData); // or import formData from 'form-data';
61
+ const mg = mailgun.client({username: 'api', key: process.env.MAILGUN_API_KEY || 'key-{yourkeyhere}'});
61
62
  ```
62
63
 
63
64
  Be aware that there are four bundles available for usage. All of them are conditionally exported by package.json and separated by environment (Browser/Node.js):
@@ -122,25 +123,50 @@ Be aware that there are four bundles available for usage. All of them are condit
122
123
  })
123
124
  </script>
124
125
  ```
125
- ### Using Subaccounts
126
- Primary accounts can make API calls on behalf of their subaccounts. [API documentation](https://documentation.mailgun.com/en/latest/subaccounts.html#subaccounts)
127
- ```js
128
- import FormData from 'form-data'; // or built-in FormData
129
- import Mailgun from 'mailgun.js';
130
- const mailgun = new Mailgun(FormData);
131
- const mg = mailgun.client({username: 'api', key: process.env.MAILGUN_API_KEY || 'key-yourkeyhere'});
132
- mg.setSubaccount('subaccount-id');
133
- // then, if you need to reset it back to the primary account:
134
- mg.resetSubaccount();
126
+
127
+ ### Types imports
128
+ Types defined by SDK can be imported from 'definitions' submodule:
129
+ ```TS
130
+ import { MailgunClientOptions, MessagesSendResult } from 'mailgun.js/definitions';
131
+ ```
132
+
133
+ ### Interfaces and Enums imports
134
+ Interfaces and Enums defined by SDK can be imported from 'definitions' submodule:
135
+ ```TS
136
+ import { Interfaces, Enums } from 'mailgun.js/definitions';
137
+ ...
138
+ const mailgunClient: Interfaces.IMailgunClient = mailgun.client(clientOptions);
139
+ const yes = Enums.YesNo.YES;
140
+ ...
141
+ ```
142
+ ### Fetch API usage
143
+
144
+ Starting from version `12.1.0`, the [Fetch API](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API) is available for use in environments that do not support `XMLHttpRequest`.
145
+
146
+ The new `useFetch` configuration parameter is responsible for this.
147
+
148
+ ***Note that proxy configuration and the `form-data` NPM package are not supported in this case.***
149
+
150
+ Example:
151
+
152
+ ```TS
153
+ import Mailgun from 'mailgun.js';
154
+ const mailgun = new Mailgun(FormData);
155
+
156
+ const mg = mailgun.client({
157
+ username: 'api',
158
+ key: process.env.MAILGUN_API_KEY || 'key-yourkeyhere',
159
+ useFetch: true,
160
+ });
135
161
  ```
136
162
 
163
+
137
164
  ### Proxy configuration
138
165
  By leveraging client configuration options, users can effortlessly establish proxy connections that align with their network requirements.
139
- Ex:
166
+ Example:
140
167
  ```js
141
- import FormData from 'form-data'; // or built-in FormData
142
168
  import Mailgun from 'mailgun.js';
143
- const mailgun = new Mailgun(FormData);
169
+ const mailgun = new Mailgun(FormData);// or import FormData from 'form-data';
144
170
 
145
171
  const mg = mailgun.client({
146
172
  username: 'api',
@@ -156,22 +182,21 @@ Ex:
156
182
  },
157
183
  });
158
184
  ```
159
- ### Types imports
160
- Types defined by SDK can be imported from 'definitions' submodule:
161
- ```TS
162
- import { MailgunClientOptions, MessagesSendResult } from 'mailgun.js/definitions';
163
- ```
164
185
 
165
- ### Interfaces and Enums imports
166
- Interfaces and Enums defined by SDK can be imported from 'definitions' submodule:
167
- ```TS
168
- import { Interfaces, Enums } from 'mailgun.js/definitions';
169
- ...
170
- const mailgunClient: Interfaces.IMailgunClient = mailgun.client(clientOptions);
171
- const yes = Enums.YesNo.YES;
172
- ...
186
+
187
+
188
+ ### SubAccounts Usage
189
+ Primary accounts can make API calls on behalf of their subaccounts. [API documentation](https://documentation.mailgun.com/en/latest/subaccounts.html#subaccounts)
190
+ ```js
191
+ import Mailgun from 'mailgun.js';
192
+ const mailgun = new Mailgun(FormData); // or import FormData from 'form-data'
193
+ const mg = mailgun.client({username: 'api', key: process.env.MAILGUN_API_KEY || 'key-yourkeyhere'});
194
+ mg.setSubaccount('subaccount-id');
195
+ // then, if you need to reset it back to the primary account:
196
+ mg.resetSubaccount();
173
197
  ```
174
198
 
199
+
175
200
  ### Generated docs
176
201
  The list of all available Types, Interfaces and Enums is auto-generated and located in the [docs](./docs/modules.md) folder.
177
202
 
@@ -4131,21 +4156,21 @@ A client to manage members within a specific mailing list.
4131
4156
  }
4132
4157
  }
4133
4158
 
4134
- ## Navigation thru lists
4159
+ ## Pagination
4135
4160
  Most of the methods that return items in a list support pagination.
4136
4161
  There are two ways to receive part of the list:
4137
- 1. Provide properties 'limit' and 'page' in the query.
4162
+ 1. Provide properties `limit` and `page` in the query.
4138
4163
  This way uses more frequently in the SDK and works for the next methods:
4139
- - mg.domains.domainTags.list()
4140
- - mg.domains.domainTemplates.list()
4141
- - mg.domains.domainTemplates.listVersions()
4142
- - mg.events.get()
4143
- - mg.lists.list()
4144
- - mg.lists.members.listMembers()
4145
- - mg.validate.list()
4146
- - mg.suppressions.list()
4164
+ - `mg.domains.domainTags.list()`
4165
+ - `mg.domains.domainTemplates.list()`
4166
+ - `mg.domains.domainTemplates.listVersions()`
4167
+ - `mg.events.get()`
4168
+ - `mg.lists.list()`
4169
+ - `mg.lists.members.listMembers()`
4170
+ - `mg.validate.list()`
4171
+ - `mg.suppressions.list()`
4147
4172
 
4148
- The general idea is that after you made the first call with a limit property in the query you will receive a response with a property called pages in it. This property implements the next interface:
4173
+ The general idea is that after you made the first call with a limit property in the query you will receive a response with `pages` property in it. This property implements the next interface:
4149
4174
 
4150
4175
  ```TS
4151
4176
  {
@@ -4175,7 +4200,7 @@ A client to manage members within a specific mailing list.
4175
4200
  };
4176
4201
  }
4177
4202
  ```
4178
- To receive the next page you need to add the page property to the query argument. This property should contain a string value from 'page' property in response.pages.(previous/first/last/next).
4203
+ To receive the next page you need to add the `page` property to the query argument. This property should contain a string value from `page` property in response.pages.(previous/first/last/next).
4179
4204
 
4180
4205
  Example:
4181
4206
  ```Js
@@ -4280,12 +4305,13 @@ A client to manage members within a specific mailing list.
4280
4305
  }
4281
4306
  */
4282
4307
  ```
4283
- 2. The second option of navigation is to provide properties 'limit' and 'skip' in the query. This way uses only in a few places for now:
4284
- - mg.domains.list()
4285
- - mg.domains.domainCredentials.list()
4286
- - mg.routes.list()
4287
- - mg.webhooks.list()
4288
- The main idea here is quite simple you just need to provide how many records from the start of a list you want to skip and how many to receive. You can do it using the query parameter in each method.
4308
+ 2. The second option of navigation is to provide properties `limit` and `skip` in the query. Currently this way is being used only in a few places:
4309
+ - `mg.domains.list()`
4310
+ - `mg.domains.domainCredentials.list()`
4311
+ - `mg.routes.list()`
4312
+ - `mg.webhooks.list()`
4313
+
4314
+ The main idea here is quite simple, you just need to provide how many records from the start of a list you want to skip and how many to receive. You can do it with the query parameter in each method.
4289
4315
  Example:
4290
4316
  ```js
4291
4317
  const listDomainCredentials = await client.domains.domainCredentials.list(
@@ -4,6 +4,7 @@ export default class APIError extends Error implements APIErrorType {
4
4
  stack: string;
5
5
  details: string;
6
6
  type: string;
7
+ static isApiError(err: unknown): err is APIError;
7
8
  static getUserDataError(statusText: string, message: string): APIError;
8
9
  constructor({ status, statusText, message, body }: APIErrorOptions);
9
10
  }
@@ -1,12 +1,12 @@
1
- import * as NodeFormData from 'form-data';
2
- import { FormDataInput, InputFormData } from '../../Types/Common/index.js';
1
+ import { FormDataInput, InputFormData, FormDataBuilderConfig, CreatedFormData } from '../../Types/Common/index.js';
3
2
  import { MimeMessage } from '../../Types/index.js';
4
3
  declare class FormDataBuilder {
5
4
  private FormDataConstructor;
6
5
  private fileKeys;
7
6
  private attachmentsHandler;
8
- constructor(FormDataConstructor: InputFormData);
9
- createFormData(data: FormDataInput): NodeFormData | FormData;
7
+ private useFetch?;
8
+ constructor(FormDataConstructor: InputFormData, config: FormDataBuilderConfig);
9
+ createFormData(data: FormDataInput): Promise<CreatedFormData>;
10
10
  private addMimeDataToFD;
11
11
  isMIME(data: unknown): data is MimeMessage;
12
12
  private isFormDataPackage;
@@ -1,29 +1,24 @@
1
- import * as NodeFormData from 'form-data';
2
- import { RequestOptions, InputFormData, APIResponse, IpPoolDeleteData, FormDataInput } from '../../Types/index.js';
1
+ import { RequestOptions, InputFormData, APIResponse, IpPoolDeleteData, FormDataInput, RequestData, GetQueryTypes, PostDataTypes, PutDataTypes, CommandQuery, PutOptionsType, PutQueryTypes, onCallReqConfig } from '../../Types/index.js';
2
+ import { IRequestProvider } from '../../Interfaces/index.js';
3
3
  declare class Request {
4
- private username;
5
- private key;
6
4
  private url;
7
- private timeout;
8
- private headers;
9
5
  private formDataBuilder;
10
- private maxBodyLength;
11
- private proxy;
6
+ requestProvider: IRequestProvider;
12
7
  constructor(options: RequestOptions, formData: InputFormData);
13
- request(method: string, url: string, onCallOptions?: Record<string, unknown | Record<string, unknown>>): Promise<APIResponse>;
14
- private getResponseBody;
15
- private joinAndTransformHeaders;
16
- private makeHeadersFromObject;
17
- setSubaccountHeader(subaccountId: string): void;
8
+ request(method: string, url: string, onCallOptions?: {
9
+ body?: RequestData;
10
+ query?: GetQueryTypes | PutQueryTypes;
11
+ }, config?: onCallReqConfig): Promise<APIResponse>;
12
+ setSubaccountHeader(subAccountId: string): void;
18
13
  resetSubaccountHeader(): void;
19
- query(method: string, url: string, query?: Record<string, unknown> | Array<Array<string>>, options?: Record<string, unknown>): Promise<APIResponse>;
20
- command(method: string, url: string, data?: Record<string, unknown> | Record<string, unknown>[] | string | NodeFormData | FormData, options?: Record<string, unknown>, addDefaultHeaders?: boolean): Promise<APIResponse>;
21
- get(url: string, query?: Record<string, unknown> | Array<Array<string>>, options?: Record<string, unknown>): Promise<APIResponse>;
22
- post(url: string, data?: Record<string, unknown> | string, options?: Record<string, unknown>): Promise<APIResponse>;
14
+ query(method: string, url: string, query?: GetQueryTypes): Promise<APIResponse>;
15
+ command(method: string, url: string, data?: RequestData, config?: onCallReqConfig, queryObject?: CommandQuery): Promise<APIResponse>;
16
+ get(url: string, query?: GetQueryTypes): Promise<APIResponse>;
17
+ post(url: string, data?: PostDataTypes, config?: Omit<onCallReqConfig, 'isFormURLEncoded' | 'isMultipartFormData'>): Promise<APIResponse>;
23
18
  postWithFD(url: string, data: FormDataInput): Promise<APIResponse>;
24
19
  putWithFD(url: string, data: FormDataInput): Promise<APIResponse>;
25
20
  patchWithFD(url: string, data: FormDataInput): Promise<APIResponse>;
26
- put(url: string, data?: FormDataInput | string, options?: Record<string, unknown>): Promise<APIResponse>;
21
+ put(url: string, data?: PutDataTypes, queryObject?: PutOptionsType): Promise<APIResponse>;
27
22
  delete(url: string, data?: IpPoolDeleteData): Promise<APIResponse>;
28
23
  }
29
24
  export default Request;
@@ -0,0 +1,20 @@
1
+ import { APIResponse, onCallReqConfig, RequestProviderConfig, RequestProviderData } from '../../../Types/index.js';
2
+ import { IRequestProvider } from '../../../Interfaces/index.js';
3
+ declare class AxiosProvider implements IRequestProvider {
4
+ private timeout;
5
+ private maxBodyLength;
6
+ private proxy;
7
+ private username;
8
+ private key;
9
+ private headers;
10
+ private useFetch;
11
+ constructor({ username, key, timeout, maxBodyLength, proxy, configHeaders, useFetch }: RequestProviderConfig);
12
+ private getResponseBody;
13
+ private getDataRelatedHeaders;
14
+ private addRequestLevelHeaders;
15
+ private makeHeadersFromObject;
16
+ setSubAccountHeader(subAccountId: string): void;
17
+ resetSubAccountHeader(): void;
18
+ makeRequest(url: string, method: string, data: RequestProviderData, config?: onCallReqConfig): Promise<APIResponse>;
19
+ }
20
+ export default AxiosProvider;
@@ -0,0 +1,6 @@
1
+ import { APIResponse, onCallReqConfig, RequestData } from '../../../Types/index.js';
2
+ export interface IRequestProvider {
3
+ makeRequest(url: string, method: string, data: RequestData, config?: onCallReqConfig): Promise<APIResponse>;
4
+ setSubAccountHeader(subAccountId: string): void;
5
+ resetSubAccountHeader(): void;
6
+ }
@@ -1 +1,2 @@
1
1
  export * from './Logger.js';
2
+ export * from './RequestProviders/RequestProvider.js';
@@ -1,4 +1,4 @@
1
- import type { CreateDomainTemplateVersionResult, DomainTemplateData, DomainTemplatesQuery, DomainTemplateUpdateData, DomainTemplateUpdateVersionData, DomainTemplateVersionData, ListDomainTemplatesResult, ListDomainTemplateVersionsResult, MutateDomainTemplateVersionResult, NotificationResult, ShortTemplateVersion, TemplateQuery, TemplateVersion, UpdateOrDeleteDomainTemplateResult } from '../../Types/Domains/index.js';
1
+ import type { CreateDomainTemplateVersionResult, DomainTemplateData, DomainTemplatesQuery, DomainTemplateUpdateData, DomainTemplateUpdateVersionData, DomainTemplateVersionData, ListDomainTemplatesResult, ListDomainTemplateVersionsResult, MutateDomainTemplateVersionResult, NotificationResult, ShortTemplateVersion, TemplateQuery, TemplateVersion, UpdateOrDeleteDomainTemplateResult } from '../../Types/Domains/DomainTemplates.js';
2
2
  export interface IDomainTemplate {
3
3
  name: string;
4
4
  description: string;
@@ -11,3 +11,10 @@ export type InputFormData = {
11
11
  export type FormDataInput = {
12
12
  [key: string]: FormDataInputValue;
13
13
  };
14
+ export type FormDataBuilderConfig = {
15
+ useFetch?: boolean;
16
+ };
17
+ export type CreatedFormData = {
18
+ dataSize?: number;
19
+ formData: NodeFormData | FormData;
20
+ };
@@ -1,15 +1,59 @@
1
- import { AxiosRequestHeaders, RawAxiosRequestHeaders } from 'axios';
2
- import { MailgunClientOptions } from '../MailgunClient/index.js';
1
+ import * as NodeFormData from 'form-data';
2
+ import type { MailgunClientOptions } from '../MailgunClient/index.js';
3
+ import type { IPsListQuery } from '../IPs/index.js';
4
+ import type { RoutesListQuery } from '../Routes/index.js';
5
+ import type { SubaccountsQuery } from '../Subaccounts/index.js';
6
+ import type { WebhooksQuery } from '../Webhooks/index.js';
7
+ import type { ConnectionSettings, DomainCredentialsQuery, DomainGetAPIQuery, DomainsQuery, DomainTagsStatisticQuery, DomainTemplatesQuery, TemplateQuery } from '../Domains/index.js';
8
+ import type { InboxPlacementsData, InboxPlacementsResultsApiQuery, SeedsListsAPIQuery, SeedsListsUpdatingData } from '../InboxPlacements/index.js';
9
+ import type { ValidationQuery } from '../Validations/index.js';
10
+ import type { IpPoolDeleteData } from '../IPPools/index.js';
11
+ import type { MetricsQuery } from '../Metrics/index.js';
12
+ import type { FormDataInput } from './FormData.js';
3
13
  export type OnCallEmptyHeaders = {
4
14
  [key: string]: undefined;
5
15
  };
16
+ type HeaderValue = string | string[] | number | boolean | null;
17
+ type CommonRequestHeadersList = 'Accept' | 'Content-Length' | 'User-Agent' | 'Content-Encoding' | 'Authorization';
18
+ type ContentType = HeaderValue | 'text/html' | 'text/plain' | 'multipart/form-data' | 'application/json' | 'application/x-www-form-urlencoded' | 'application/octet-stream';
19
+ export type RequestHeaders = Partial<{
20
+ [key: string]: HeaderValue;
21
+ } & {
22
+ [Key in CommonRequestHeadersList]: HeaderValue;
23
+ } & {
24
+ 'Content-Type': ContentType;
25
+ }>;
6
26
  export type RequestOptions = MailgunClientOptions & {
7
- headers: AxiosRequestHeaders | RawAxiosRequestHeaders;
8
- timeout: number;
27
+ headers?: RequestHeaders;
28
+ timeout?: number;
9
29
  };
10
30
  export type OnCallRequestOptions = {
11
31
  timeout?: number;
12
- headers?: AxiosRequestHeaders | RawAxiosRequestHeaders;
13
32
  query?: any;
14
33
  [key: string]: unknown | undefined;
15
34
  };
35
+ export type GetQueryTypes = IPsListQuery | RoutesListQuery | SubaccountsQuery | WebhooksQuery | DomainsQuery | DomainGetAPIQuery | DomainCredentialsQuery | DomainTagsStatisticQuery | TemplateQuery | DomainTemplatesQuery | InboxPlacementsResultsApiQuery | SeedsListsAPIQuery | {
36
+ searchParams?: Array<Array<string>>;
37
+ } | ValidationQuery;
38
+ export type PostDataTypes = InboxPlacementsData | MetricsQuery | string;
39
+ export type PutDataTypes = SeedsListsUpdatingData | object | FormDataInput | ConnectionSettings;
40
+ export type RequestData = IpPoolDeleteData | PostDataTypes | PutDataTypes | NodeFormData | FormData;
41
+ export type ContainsPrefix<T extends string> = `${T}${string}`;
42
+ type EnableQuery = ContainsPrefix<'enabled='>;
43
+ type DkimSelectorQuery = ContainsPrefix<'dkim_selector='>;
44
+ type SelfQuery = ContainsPrefix<'self='>;
45
+ type WebPrefixQuery = ContainsPrefix<'web_prefix='>;
46
+ export type PutQueryTypes = EnableQuery | DkimSelectorQuery | SelfQuery | WebPrefixQuery;
47
+ export type PutOptionsType = {
48
+ query?: PutQueryTypes;
49
+ };
50
+ export type CommandQuery = {
51
+ query?: PutQueryTypes;
52
+ };
53
+ export type onCallReqConfig = {
54
+ isFormURLEncoded?: boolean;
55
+ isMultipartFormData?: boolean;
56
+ isApplicationJSON?: boolean;
57
+ dataSize?: number;
58
+ };
59
+ export {};
@@ -0,0 +1,30 @@
1
+ import type { RequestData, RequestHeaders } from './index.js';
2
+ export type ClientProxyConfig = {
3
+ host: string;
4
+ port: number;
5
+ auth?: {
6
+ username: string;
7
+ password: string;
8
+ };
9
+ protocol?: string;
10
+ };
11
+ export type RequestProviderConfig = {
12
+ username: string;
13
+ key: string;
14
+ timeout?: number;
15
+ maxBodyLength: number;
16
+ proxy?: ClientProxyConfig;
17
+ configHeaders?: RequestHeaders;
18
+ useFetch?: boolean;
19
+ };
20
+ export type RequestProviderData = {
21
+ params?: URLSearchParams;
22
+ data?: RequestData;
23
+ };
24
+ export type FetchSupportedData = Blob | BufferSource | FormData | URLSearchParams | string;
25
+ export type KeysWithToArray = {
26
+ toArray: () => string[];
27
+ };
28
+ export type HeadersWithKeysMethod = Headers & {
29
+ keys: () => KeysWithToArray;
30
+ };
@@ -4,3 +4,4 @@ export * from './Error.js';
4
4
  export * from './FormData.js';
5
5
  export * from './NavigationThruPages.js';
6
6
  export * from './RequestOptions.js';
7
+ export * from './RequestProvider.js';
@@ -175,3 +175,7 @@ export type DomainGetQuery = {
175
175
  extended?: boolean;
176
176
  with_dns?: boolean;
177
177
  };
178
+ export type DomainGetAPIQuery = {
179
+ 'h:extended'?: boolean;
180
+ 'h:with_dns'?: boolean;
181
+ };
@@ -1,9 +1,10 @@
1
- import { AxiosProxyConfig } from 'axios';
1
+ import type { ClientProxyConfig } from '../Common/index.js';
2
2
  export type MailgunClientOptions = {
3
3
  username: string;
4
4
  key: string;
5
5
  url?: string;
6
6
  public_key?: string;
7
7
  timeout?: number;
8
- proxy?: AxiosProxyConfig;
8
+ proxy?: ClientProxyConfig;
9
+ useFetch?: boolean;
9
10
  };