mailgun.js 4.1.6 → 4.2.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.
@@ -4,4 +4,4 @@
4
4
 
5
5
  /*! https://mths.be/punycode v1.3.2 by @mathias */
6
6
 
7
- /*! mailgun.js v4.1.5 */
7
+ /*! mailgun.js v4.1.6 */
package/lib/client.ts CHANGED
@@ -19,6 +19,7 @@ import { InputFormData } from './interfaces/IFormData';
19
19
  import DomainCredentialsClient from './domainsCredentials';
20
20
  import MultipleValidationClient from './multipleValidation';
21
21
  import DomainTemplatesClient from './domainsTemplates';
22
+ import DomainTagsClient from './domainsTags';
22
23
 
23
24
  export default class Client {
24
25
  private request;
@@ -55,9 +56,15 @@ export default class Client {
55
56
  const mailListsMembers = new MailListsMembers(this.request);
56
57
  const domainCredentialsClient = new DomainCredentialsClient(this.request);
57
58
  const domainTemplatesClient = new DomainTemplatesClient(this.request);
59
+ const domainTagsClient = new DomainTagsClient(this.request);
58
60
  const multipleValidationClient = new MultipleValidationClient(this.request);
59
61
 
60
- this.domains = new DomainClient(this.request, domainCredentialsClient, domainTemplatesClient);
62
+ this.domains = new DomainClient(
63
+ this.request,
64
+ domainCredentialsClient,
65
+ domainTemplatesClient,
66
+ domainTagsClient
67
+ );
61
68
  this.webhooks = new WebhookClient(this.request);
62
69
  this.events = new EventClient(this.request);
63
70
  this.stats = new StatsClient(this.request);
package/lib/domains.ts CHANGED
@@ -41,6 +41,8 @@ import { IDomainCredentials } from './interfaces/DomainCredentials';
41
41
  import { IDomainTemplatesClient } from './interfaces/DomainTemplates';
42
42
  import DomainCredentialsClient from './domainsCredentials';
43
43
  import DomainTemplatesClient from './domainsTemplates';
44
+ import { IDomainTagsClient } from './interfaces/DomainTags';
45
+ import DomainTagsClient from './domainsTags';
44
46
 
45
47
  export class Domain {
46
48
  name: string;
@@ -76,16 +78,19 @@ export class Domain {
76
78
  export default class DomainClient {
77
79
  request: Request;
78
80
  public domainCredentials: IDomainCredentials;
79
- public domainTemplates: IDomainTemplatesClient
81
+ public domainTemplates: IDomainTemplatesClient;
82
+ public domainTags: IDomainTagsClient;
80
83
 
81
84
  constructor(
82
85
  request: Request,
83
86
  domainCredentialsClient: DomainCredentialsClient,
84
- domainTemplatesClient: DomainTemplatesClient
87
+ domainTemplatesClient: DomainTemplatesClient,
88
+ domainTagsClient: DomainTagsClient
85
89
  ) {
86
90
  this.request = request;
87
91
  this.domainCredentials = domainCredentialsClient;
88
92
  this.domainTemplates = domainTemplatesClient;
93
+ this.domainTags = domainTagsClient;
89
94
  }
90
95
 
91
96
  private _parseMessage(response: DestroyedDomainResponse) : MessageResponse {
@@ -0,0 +1,165 @@
1
+ import urljoin from 'url-join';
2
+ import APIResponse from './interfaces/ApiResponse';
3
+ import Request from './request';
4
+
5
+ import {
6
+ DomainTagAPIResponseStatsItem,
7
+ DomainTagCountriesAggregation,
8
+ DomainTagCountriesAPIResponse,
9
+ DomainTagDevicesAggregation,
10
+ DomainTagDevicesAPIResponse,
11
+ DomainTagProvidersAggregation,
12
+ DomainTagProvidersAPIResponse,
13
+ DomainTagsItem,
14
+ DomainTagsItemInfo,
15
+ DomainTagsList,
16
+ DomainTagsMessageRes,
17
+ DomainTagsQuery,
18
+ DomainTagsResponseData,
19
+ DomainTagsStatisticQuery,
20
+ DomainTagStatAPIResponse,
21
+ DomainTagStatisticItem,
22
+ DomainTagStatisticResult,
23
+ IDomainTagsClient,
24
+ PagesList,
25
+ PagesListAccumulator,
26
+ ParsedPagesList,
27
+ Resolution
28
+ } from './interfaces/DomainTags';
29
+
30
+ export class DomainTag implements DomainTagsItem {
31
+ tag: string;
32
+ description: string;
33
+ 'first-seen': Date;
34
+ 'last-seen': Date;
35
+
36
+ constructor(tagInfo: DomainTagsItemInfo) {
37
+ this.tag = tagInfo.tag;
38
+ this.description = tagInfo.description;
39
+ this['first-seen'] = new Date(tagInfo['first-seen']);
40
+ this['last-seen'] = new Date(tagInfo['last-seen']);
41
+ }
42
+ }
43
+
44
+ export class DomainTagStatistic implements DomainTagStatisticResult {
45
+ tag: string;
46
+ description: string;
47
+ start: Date;
48
+ end: Date;
49
+ resolution: Resolution;
50
+ stats: DomainTagStatisticItem[];
51
+
52
+ constructor(tagStatisticInfo: DomainTagStatAPIResponse) {
53
+ this.tag = tagStatisticInfo.body.tag;
54
+ this.description = tagStatisticInfo.body.description;
55
+ this.start = new Date(tagStatisticInfo.body.start);
56
+ this.end = new Date(tagStatisticInfo.body.end);
57
+ this.resolution = tagStatisticInfo.body.resolution;
58
+ this.stats = tagStatisticInfo.body.stats.map(function (stat: DomainTagAPIResponseStatsItem) {
59
+ const res = { ...stat, time: new Date(stat.time) };
60
+ return res;
61
+ });
62
+ }
63
+ }
64
+
65
+ export default class DomainTagsClient implements IDomainTagsClient {
66
+ baseRoute: string;
67
+ request: Request;
68
+
69
+ constructor(request: Request) {
70
+ this.request = request;
71
+ this.baseRoute = '/v3/';
72
+ }
73
+
74
+ private _parsePageLinks(response: DomainTagsResponseData): ParsedPagesList {
75
+ const pages = Object.entries(response.body.paging as PagesList);
76
+ return pages.reduce(
77
+ (acc: PagesListAccumulator, entrie: [url: string, id: string]) => {
78
+ const id = entrie[0];
79
+ const url = entrie[1];
80
+ acc[id] = {
81
+ id,
82
+ url
83
+ };
84
+ return acc;
85
+ }, {}
86
+ ) as unknown as ParsedPagesList;
87
+ }
88
+
89
+ private _parseDomainTagsList(
90
+ response: DomainTagsResponseData
91
+ ): DomainTagsList {
92
+ return {
93
+ items: response.body.items.map((tagInfo) => new DomainTag(tagInfo)),
94
+ pages: this._parsePageLinks(response)
95
+ };
96
+ }
97
+
98
+ private _parseTagStatistic(
99
+ response: DomainTagStatAPIResponse
100
+ ): DomainTagStatistic {
101
+ return new DomainTagStatistic(response);
102
+ }
103
+
104
+ list(domain: string, query?: DomainTagsQuery): Promise<DomainTagsList> {
105
+ return this.request.get(urljoin(this.baseRoute, domain, '/tags'), query)
106
+ .then(
107
+ (res: APIResponse) => this._parseDomainTagsList(res as DomainTagsResponseData)
108
+ );
109
+ }
110
+
111
+ get(domain: string, tag: string): Promise<DomainTagsItem> {
112
+ return this.request.get(urljoin(this.baseRoute, domain, '/tags', tag))
113
+ .then(
114
+ (res: APIResponse) => new DomainTag(res.body)
115
+ );
116
+ }
117
+
118
+ update(domain: string, tag: string, description: string): Promise<DomainTagsMessageRes> {
119
+ return this.request.put(urljoin(this.baseRoute, domain, '/tags', tag), description)
120
+ .then(
121
+ (res: APIResponse) => res.body as DomainTagsMessageRes
122
+ );
123
+ }
124
+
125
+ destroy(
126
+ domain: string,
127
+ tag: string
128
+ ): Promise<DomainTagsMessageRes> {
129
+ return this.request.delete(`${this.baseRoute}${domain}/tags/${tag}`)
130
+ .then((res: APIResponse) => (
131
+ {
132
+ message: res.body.message,
133
+ status: res.status
134
+ } as DomainTagsMessageRes));
135
+ }
136
+
137
+ statistic(domain: string, tag: string, query: DomainTagsStatisticQuery)
138
+ : Promise<DomainTagStatistic> {
139
+ return this.request.get(urljoin(this.baseRoute, domain, '/tags', tag, 'stats'), query)
140
+ .then(
141
+ (res: APIResponse) => this._parseTagStatistic(res)
142
+ );
143
+ }
144
+
145
+ countries(domain: string, tag: string): Promise<DomainTagCountriesAggregation> {
146
+ return this.request.get(urljoin(this.baseRoute, domain, '/tags', tag, 'stats/aggregates/countries'))
147
+ .then(
148
+ (res: DomainTagCountriesAPIResponse) => res.body as DomainTagCountriesAggregation
149
+ );
150
+ }
151
+
152
+ providers(domain: string, tag: string): Promise<DomainTagProvidersAggregation> {
153
+ return this.request.get(urljoin(this.baseRoute, domain, '/tags', tag, 'stats/aggregates/providers'))
154
+ .then(
155
+ (res: DomainTagProvidersAPIResponse) => res.body as DomainTagProvidersAggregation
156
+ );
157
+ }
158
+
159
+ devices(domain: string, tag: string): Promise<DomainTagDevicesAggregation> {
160
+ return this.request.get(urljoin(this.baseRoute, domain, '/tags', tag, 'stats/aggregates/devices'))
161
+ .then(
162
+ (res: DomainTagDevicesAPIResponse) => res.body as DomainTagDevicesAggregation
163
+ );
164
+ }
165
+ }
@@ -0,0 +1,262 @@
1
+ /* eslint-disable camelcase */
2
+ import { DomainTagStatistic } from '../domainsTags';
3
+
4
+ export enum Resolution {
5
+ HOUR = 'hour',
6
+ DAY = 'day',
7
+ MONTH = 'month'
8
+ }
9
+ export interface DomainTagsQuery {
10
+ limit: number;
11
+ }
12
+
13
+ export interface DomainTagsStatisticQuery {
14
+ event: string;
15
+ start?: number;
16
+ end?: number;
17
+ resolution?: Resolution;
18
+ duration?: string;
19
+ }
20
+
21
+ export interface DomainTagsItemInfo {
22
+ tag: string,
23
+ description: string,
24
+ 'first-seen': string,
25
+ 'last-seen': string
26
+ }
27
+
28
+ export interface DomainTagsItem {
29
+ tag: string,
30
+ description: string,
31
+ 'first-seen': Date,
32
+ 'last-seen': Date
33
+ }
34
+
35
+ export interface PagesList {
36
+ previous: string;
37
+ first: string;
38
+ last: string;
39
+ next: string;
40
+ }
41
+
42
+ export interface ParsedPage{
43
+ id: string;
44
+ url: string
45
+ }
46
+ export interface ParsedPagesList {
47
+ previous: ParsedPage;
48
+ first: ParsedPage;
49
+ last: ParsedPage;
50
+ next: ParsedPage;
51
+ }
52
+
53
+ export interface TagsPage {
54
+ id: string;
55
+ url: string;
56
+ }
57
+
58
+ export interface PagesListAccumulator {
59
+ [index: string]: TagsPage
60
+ }
61
+ export interface DomainTagsResponseData {
62
+ status: number;
63
+ body: {
64
+ items: DomainTagsItemInfo[];
65
+ paging: PagesList
66
+ }
67
+ }
68
+
69
+ export interface DomainTagsList {
70
+ items: DomainTagsItem[];
71
+ pages: ParsedPagesList;
72
+ }
73
+
74
+ export interface DomainTagsMessageRes {
75
+ message: string;
76
+ status?: number;
77
+ }
78
+
79
+ export interface DomainTagAPIResponseStatsItem {
80
+ time:string
81
+ accepted?: {
82
+ incoming: number;
83
+ outgoing: number;
84
+ total: number
85
+ }
86
+ delivered?: {
87
+ smtp: number;
88
+ http: number;
89
+ optimized: number;
90
+ total: number;
91
+ };
92
+ opened?: {
93
+ total: number;
94
+ };
95
+ failed?: {
96
+ temporary:{
97
+ espblock: number;
98
+ total: number;
99
+ };
100
+ permanent: {
101
+ 'suppress-bounce': number;
102
+ 'suppress-unsubscribe': number;
103
+ 'suppress-complaint': number;
104
+ bounce: number;
105
+ 'delayed-bounce': number;
106
+ webhook: number;
107
+ optimized: number;
108
+ total: number;
109
+ };
110
+ },
111
+ clicked?: {
112
+ total: number;
113
+ };
114
+ unsubscribed?: {
115
+ total: number;
116
+ };
117
+ complained?: {
118
+ total: number;
119
+ };
120
+ stored?: {
121
+ total: number;
122
+ }
123
+ }
124
+ export interface DomainTagStatAPIResponse {
125
+ body:{
126
+ tag: string;
127
+ description: string;
128
+ start: string;
129
+ end: string;
130
+ resolution: Resolution;
131
+ stats: DomainTagAPIResponseStatsItem[];
132
+ }
133
+ }
134
+ export interface DomainTagStatisticItem extends Omit <DomainTagAPIResponseStatsItem, 'time'>{
135
+ time: Date
136
+ }
137
+
138
+ export interface DomainTagStatisticResult {
139
+ tag: string;
140
+ description: string;
141
+ start: Date;
142
+ end: Date;
143
+ resolution: Resolution;
144
+ stats: DomainTagStatisticItem[];
145
+ }
146
+
147
+ export interface DomainTagCountriesAPIResponse {
148
+ body: {
149
+ tag:string;
150
+ country: {
151
+ [key:string]: {
152
+ clicked: number;
153
+ complained: number;
154
+ opened: number;
155
+ unique_clicked: number;
156
+ unique_opened: number;
157
+ unsubscribed: number;
158
+ }
159
+ };
160
+ }
161
+ }
162
+
163
+ export interface DomainTagCountriesAggregation {
164
+ tag:string;
165
+ country: {
166
+ [key: string]: {
167
+ clicked: number;
168
+ complained: number;
169
+ opened: number;
170
+ unique_clicked: number;
171
+ unique_opened: number;
172
+ unsubscribed: number;
173
+ }
174
+ }
175
+ }
176
+
177
+ export interface DomainTagProvidersAPIResponse {
178
+ body: {
179
+ tag:string;
180
+ provider: {
181
+ [key:string]: {
182
+ accepted: number;
183
+ clicked: number;
184
+ complained: number;
185
+ delivered: number;
186
+ opened: number;
187
+ unique_clicked: number;
188
+ unique_opened: number;
189
+ unsubscribed: number;
190
+ }
191
+ };
192
+ }
193
+ status: number;
194
+ }
195
+
196
+ export interface DomainTagProvidersAggregation {
197
+ tag: string;
198
+ provider: {
199
+ [key: string]: {
200
+ accepted: number;
201
+ clicked: number;
202
+ complained: number;
203
+ delivered: number;
204
+ opened: number;
205
+ unique_clicked: number;
206
+ unique_opened: number;
207
+ unsubscribed: number;
208
+ }
209
+ };
210
+ }
211
+
212
+ export interface DeviceStatistic {
213
+ clicked: number;
214
+ complained: number;
215
+ opened: number;
216
+ unique_clicked: number;
217
+ unique_opened: number;
218
+ unsubscribed: number;
219
+ }
220
+
221
+ export interface DevicesTypes {
222
+ desktop: DeviceStatistic;
223
+ mobile: DeviceStatistic;
224
+ tablet: DeviceStatistic;
225
+ unknown: DeviceStatistic;
226
+ }
227
+
228
+ export interface DomainTagDevicesAPIResponse {
229
+ body: {
230
+ tag:string;
231
+ device: DevicesTypes;
232
+ }
233
+ status: number;
234
+ }
235
+
236
+ export interface DomainTagDevicesAggregation {
237
+ tag: string;
238
+ device: DevicesTypes;
239
+ }
240
+
241
+
242
+ export interface IDomainTagsClient {
243
+ list(domain: string): Promise<DomainTagsList>
244
+ get(domain: string, tag: string): Promise<DomainTagsItem>
245
+ update(
246
+ domain: string,
247
+ tag: string,
248
+ description: string
249
+ ): Promise<DomainTagsMessageRes>
250
+ destroy(
251
+ domain: string,
252
+ tag: string
253
+ ): Promise<DomainTagsMessageRes>
254
+ statistic(
255
+ domain: string,
256
+ tag: string,
257
+ query: DomainTagsStatisticQuery
258
+ ): Promise<DomainTagStatistic>
259
+ countries(domain: string, tag: string): Promise<DomainTagCountriesAggregation>
260
+ providers(domain: string, tag: string): Promise<DomainTagProvidersAggregation>
261
+ devices(domain: string, tag: string): Promise<DomainTagDevicesAggregation>
262
+ }
package/lib/request.ts CHANGED
@@ -83,7 +83,9 @@ class Request {
83
83
  params.searchParams = options.query;
84
84
  delete params.query;
85
85
  }
86
-
86
+ console.log('url --------->', urljoin(this.url, url));
87
+ console.log('method --------->', method);
88
+ console.log('params --------->', params);
87
89
  const response = await ky(
88
90
  urljoin(this.url, url),
89
91
  {
@@ -111,7 +113,7 @@ class Request {
111
113
  body: await response?.json(),
112
114
  status: response?.status
113
115
  };
114
-
116
+ console.log('res ------------->', res);
115
117
  return res;
116
118
  }
117
119
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mailgun.js",
3
- "version": "4.1.6",
3
+ "version": "4.2.0",
4
4
  "main": "dist/mailgun.node.js",
5
5
  "browser": "dist/mailgun.web.js",
6
6
  "types": "dist/index.d.ts",
@@ -15,6 +15,7 @@ import {
15
15
  UpdatedDKIMSelectorResponse, UpdatedWebPrefixResponse
16
16
  } from '../lib/interfaces/Domains';
17
17
  import DomainTemplatesClient from '../lib/domainsTemplates';
18
+ import DomainTagsClient from '../lib/domainsTags';
18
19
 
19
20
  // TODO: fix types
20
21
  describe('DomainClient', function () {
@@ -25,7 +26,13 @@ describe('DomainClient', function () {
25
26
  const reqObject = new Request({ url: 'https://api.mailgun.net' } as RequestOptions, formData as InputFormData);
26
27
  const domainCredentialsClient = new DomainCredentialsClient(reqObject);
27
28
  const domainTemplatesClient = new DomainTemplatesClient(reqObject);
28
- client = new DomainClient(reqObject, domainCredentialsClient, domainTemplatesClient);
29
+ const domainTagsClient = new DomainTagsClient(reqObject);
30
+ client = new DomainClient(
31
+ reqObject,
32
+ domainCredentialsClient,
33
+ domainTemplatesClient,
34
+ domainTagsClient
35
+ );
29
36
  api = nock('https://api.mailgun.net');
30
37
  });
31
38