@salespark/mailerlite-api 1.0.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 ADDED
@@ -0,0 +1,208 @@
1
+ # @salespark/mailerlite-api
2
+
3
+ [MailerLite API v2](https://developers.mailerlite.com/docs/getting-started-with-mailerlite-api) [Node.js](https://nodejs.org/en/) SDK. It is mostly a thin wrapper on [axios](https://github.com/axios/axios) that provides [authentication](https://developers.mailerlite.com/docs/authentication), response/request camelCase transformations, Typescript type definitions and some handy shorthand methods.
4
+
5
+ ## Install
6
+
7
+ Using npm:
8
+
9
+ ```
10
+ npm install @salespark/mailerlite-api
11
+ ```
12
+
13
+ Using yarn:
14
+
15
+ ```
16
+ yarn add @salespark/mailerlite-api
17
+ ```
18
+
19
+ ## Usage
20
+
21
+ In node:
22
+
23
+ ```javascript
24
+ const MailerLite = require('@salespark/mailerlite-api').default;
25
+
26
+ const mailerLite = MailerLite('YOUR_API_KEY');
27
+
28
+ // with Promises
29
+ mailerLite.getAccount().then((account) => {
30
+ // ...
31
+ });
32
+
33
+ // with async await
34
+ async function getAccountEmail() {
35
+ const { email } = await mailerLite.getAccount();
36
+ return email;
37
+ }
38
+ ```
39
+
40
+ It is important to note that the request is resolved to response body - it does not return the full axios response object.
41
+
42
+ ## Options
43
+
44
+ `axiosOptions`: `object` - additional [axios config](https://github.com/axios/axios#request-config). This config does not overwrite the explicit `baseURL` and `headers` options below.
45
+
46
+ `baseURL`: `string` - API endpoint. Defaults to `https://api.mailerlite.com/api/v2/`. Timezones endpoint has a different hardcoded baseURL.
47
+
48
+ `headers`: `object` - additional request headers. Library already includes all the necessary headers to perform requests. But these can be overwritten with this option. Defaults to `{}`.
49
+
50
+ `useCaseConverter`: `boolean` - should the library convert all query params, request body and response body to camelCase. Defaults to `true`.
51
+
52
+ ## Method reference
53
+
54
+ For complete reference, visit the [official MailerLite API reference](https://developers.mailerlite.com/reference).
55
+
56
+ ### Account
57
+
58
+ #### `getAccount()`
59
+
60
+ Returns your current account details. To get the raw response use `getAccountRaw()`
61
+
62
+ Alias: `getMe()`
63
+
64
+ ### Batch
65
+
66
+ #### `batch(requests)`
67
+
68
+ ### Campaigns
69
+
70
+ #### `actOnCampaign(campaignId, action, data)`
71
+
72
+ #### `getCampaigns(status?, params?)`
73
+
74
+ #### `getCampaignCount(status?)`
75
+
76
+ #### `createCampaign(campaign)`
77
+
78
+ #### `removeCampaign(campaignId)`
79
+
80
+ #### `setCampaignContent(campaignId, content)`
81
+
82
+ ### Fields
83
+
84
+ #### `getFields()`
85
+
86
+ #### `createField(field)`
87
+
88
+ #### `updateField(fieldId, fieldUpdate)`
89
+
90
+ #### `removeField(fieldId)`
91
+
92
+ ### Groups
93
+
94
+ #### `getGroups(params?)`
95
+
96
+ #### `searchGroups(groupName)`
97
+
98
+ #### `getGroup(groupId)`
99
+
100
+ #### `createGroup(group)`
101
+
102
+ #### `updateGroup(groupId, group)`
103
+
104
+ #### `removeGroup(groupId)`
105
+
106
+ #### `addSubscriberToGroup(groupId, subscriber)`
107
+
108
+ #### `addSubscribersToGroup(groupId, subscribers, importOptions)`
109
+
110
+ #### `getSubscribersGroupImport(groupId, importId)`
111
+
112
+ #### `getGroupSubscriber(groupId, subscriberId)`
113
+
114
+ #### `getGroupSubscribers(groupId, params?)`
115
+
116
+ #### `getGroupSubscriberCount(groupId)`
117
+
118
+ #### `getGroupSubscribersByType(groupId, subscriberType, params?)`
119
+
120
+ #### `getGroupSubscribersCountByType(groupId, subscriberType)`
121
+
122
+ #### `removeGroupSubscriber(groupId, subscriberIdentifier)`
123
+
124
+ ### Segments
125
+
126
+ #### `getSegments(params?)`
127
+
128
+ #### `getSegmentsCount(params?)`
129
+
130
+ #### `getSegmentsRaw(params?)`
131
+
132
+ ### Settings
133
+
134
+ #### `getDoubleOptinStatus()`
135
+
136
+ Resolves to raw response object that contains `enabled` key
137
+
138
+ #### `hasEnabledDoubleOptin()`: resolve to Promise<boolean>
139
+
140
+ Shorthand that resolves to a Promise<boolean>.
141
+
142
+ #### `enableDoubleOptin()`
143
+
144
+ #### `disableDoubleOptin()`
145
+
146
+ ### Stats
147
+
148
+ #### `getStats()`
149
+
150
+ ### Subscribers
151
+
152
+ #### `getSubscribers(params?)`
153
+
154
+ #### `addSubscriber(subscriber)`
155
+
156
+ #### `getSubscriber(identifier)`
157
+
158
+ #### `updateSubscriber(identifier, subscriber)`
159
+
160
+ #### `searchSubscribers(params?)`
161
+
162
+ #### `getSubscriberActivity(identifier)`
163
+
164
+ #### `getSubscriberActivityByType(identifier, activityType)`
165
+
166
+ #### `getSubscriberGroups(identifier)`
167
+
168
+ #### `removeSubscriber(identifier)`
169
+
170
+ ### Timezones
171
+
172
+ #### `getTimezones()`
173
+
174
+ #### `getTimezone(timezoneId)`
175
+
176
+ ### Webhooks
177
+
178
+ #### `getWebhooks()`
179
+
180
+ #### `getWebhooksCount()`
181
+
182
+ #### `getWebhooksRaw()`
183
+
184
+ #### `getWebhook(webhookId)`
185
+
186
+ #### `createWebhook(webhook)`
187
+
188
+ #### `updateWebhook(webhookId, webhook)`
189
+
190
+ #### `removeWebhook(webhookId)`
191
+
192
+ ## Tests
193
+
194
+ Tests right now are quite limited, mostly concerned with reading data. To run them, you'll need to create a `config.ts` file and enter your API key in it (as per `config.example.ts`).
195
+
196
+ ```
197
+ npm install
198
+ npm test
199
+ ```
200
+
201
+ ---
202
+
203
+ ###Fixed: CWE-918
204
+ [Server-Side Request Forgery (SSRF)](https://cwe.mitre.org/data/definitions/918.html)
205
+ [Axios Bug](https://github.com/axios/axios/issues/6463)
206
+
207
+ Forked from:
208
+ https://github.com/zygos/mailerlite-v2-node
@@ -0,0 +1,2 @@
1
+ [0628/072108.594:ERROR:registration_protocol_win.cc(108)] CreateFile: O sistema não conseguiu localizar o ficheiro especificado. (0x2)
2
+ [0628/080129.873:ERROR:registration_protocol_win.cc(108)] CreateFile: O sistema não conseguiu localizar o ficheiro especificado. (0x2)
@@ -0,0 +1,275 @@
1
+ import { AxiosRequestConfig } from 'axios';
2
+
3
+ export interface Options {
4
+ axiosOptions?: AxiosRequestConfig;
5
+ baseURL?: string;
6
+ useCaseConverter?: boolean;
7
+ headers?: { [key: string]: string };
8
+ }
9
+
10
+ export type CampaignAction = 'send' | 'cancel';
11
+ export type CampaignStatus = 'sent' | 'draft' | 'outbox';
12
+
13
+ export interface CampaignQuery {
14
+ limit?: number;
15
+ offset?: number;
16
+ order?: 'ASC' | 'DESC';
17
+ }
18
+
19
+ export interface CampaignData {
20
+ type: 'regular' | 'ab';
21
+ groups?: number[];
22
+ segments?: number[];
23
+ subject?: string;
24
+ from?: string;
25
+ fromName?: string;
26
+ language?: LanguageCode;
27
+ abSettings?: AbSettings;
28
+ }
29
+
30
+ export interface AbSettings {
31
+ values: any[];
32
+ sendType: string;
33
+ abWinType: string;
34
+ winnerAfter: number;
35
+ winnerAfterType: string;
36
+ splitPart: number;
37
+ }
38
+
39
+ export interface CampaignContent {
40
+ html: string;
41
+ plain: string;
42
+ autoInline?: boolean;
43
+ }
44
+
45
+ export interface Count {
46
+ count: number;
47
+ }
48
+
49
+ export interface CampaignSendData {
50
+ type?: 1 | 2;
51
+ followupSchedule?: '24h' | 'specific';
52
+ analytics?: 0 | 1;
53
+ date?: string;
54
+ timezoneId?: number;
55
+ folowupDate?: string;
56
+ followupTimezoneId?: number;
57
+ }
58
+
59
+ export interface SegmentQuery {
60
+ limit?: number;
61
+ offset?: number;
62
+ order?: 'ASC' | 'DESC';
63
+ }
64
+
65
+ export type SubscriberType =
66
+ | 'active'
67
+ | 'unsubscribed'
68
+ | 'bounced'
69
+ | 'junk'
70
+ | 'unconfirmed';
71
+
72
+ export interface SubscriberQuery {
73
+ limit?: number;
74
+ offset?: number;
75
+ type?: SubscriberType;
76
+ }
77
+
78
+ // TODO: consider adding optional key hints for city, company, etc.
79
+ export interface SubscriberFields {
80
+ [key: string]: string | number | Date;
81
+ }
82
+
83
+ // TODO: remove in next major version
84
+ export interface SubsriberFields extends SubscriberFields {}
85
+
86
+ export interface SubscriberData {
87
+ email: string;
88
+ name?: string;
89
+ fields?: SubscriberFields;
90
+ resubscribe?: boolean;
91
+ type?: 'unsubscribed' | 'active' | 'unconfirmed';
92
+ signupIp?: string;
93
+ signupTimestamp?: string;
94
+ confirmationIp?: string;
95
+ confirmationTimestamp?: string;
96
+ }
97
+
98
+ export interface SubscriberDataUpdate {
99
+ name?: string;
100
+ type?: 'unsubscribed' | 'active';
101
+ fields?: SubscriberFields;
102
+ resendAutoresponders?: boolean;
103
+ }
104
+
105
+ export interface SubscriberSearchQuery {
106
+ query?: string;
107
+ offset?: number;
108
+ limit?: number;
109
+ minimized?: boolean;
110
+ }
111
+
112
+ export type SubscriberActivityType =
113
+ | 'opens'
114
+ | 'clicks'
115
+ | 'junks'
116
+ | 'bounces'
117
+ | 'unsubscribes'
118
+ | 'forwards'
119
+ | 'sendings'
120
+ | null;
121
+
122
+ export interface GroupQuery {
123
+ limit?: number;
124
+ offset?: number;
125
+ filters?: string;
126
+ }
127
+
128
+ export interface GroupSearchQuery {
129
+ group_name: string;
130
+ }
131
+
132
+ export interface GroupData {
133
+ name?: string;
134
+ }
135
+
136
+ export interface GroupSubscriberData {
137
+ email: string;
138
+ name?: string;
139
+ fields?: SubscriberFields;
140
+ resubscribe?: boolean;
141
+ type?: 'unsubscribed' | 'active' | 'unconfirmed';
142
+ autoresponders?: boolean;
143
+ }
144
+
145
+ export interface GroupSubscriberFlags {
146
+ resubscribe?: boolean;
147
+ autoresponders?: boolean;
148
+ returnStatus?: boolean;
149
+ }
150
+
151
+ export interface SubscriberGroupQuery extends GroupQuery {
152
+ type?: SubscriberType;
153
+ }
154
+
155
+ export interface FieldData {
156
+ title?: string;
157
+ type?: 'TEXT' | 'NUMBER' | 'DATE';
158
+ }
159
+
160
+ export interface FieldUpdate {
161
+ title?: string;
162
+ }
163
+
164
+ export interface WebhookData {
165
+ event: string;
166
+ url: string;
167
+ }
168
+
169
+ export interface Stats {
170
+ subscribed: number;
171
+ unsubscribed: number;
172
+ campaigns: number;
173
+ sentEmails: number;
174
+ openRate: number;
175
+ clickRate: number;
176
+ bounceRate: number;
177
+ }
178
+
179
+ export interface DoubleOptinStatus {
180
+ enabled: boolean;
181
+ previewPaths: {
182
+ pagePath: string;
183
+ emailPath: string;
184
+ };
185
+ }
186
+
187
+ export interface Timezone {
188
+ id: number;
189
+ time: number;
190
+ gmt: string;
191
+ title: string;
192
+ timezone?: string;
193
+ }
194
+
195
+ export interface Account {
196
+ id: number;
197
+ email: string;
198
+ from: string;
199
+ name: string;
200
+ subdomain: string;
201
+ timezone: Timezone;
202
+ }
203
+
204
+ export interface AccountWrap {
205
+ account: Account;
206
+ }
207
+
208
+ export interface Batch {
209
+ method: 'GET' | 'POST' | 'PUT' | 'DELETE';
210
+ path: string;
211
+ body?: {
212
+ [key: string]: any;
213
+ };
214
+ }
215
+
216
+ export interface SegmentsResponse {
217
+ data: any[];
218
+ meta: {
219
+ pagination: {
220
+ count: number;
221
+ current_page: number;
222
+ links: any[];
223
+ per_page: number;
224
+ total: number;
225
+ total_pages: number;
226
+ };
227
+ };
228
+ }
229
+
230
+ export interface WebhooksResponse {
231
+ count: number;
232
+ limit: number;
233
+ start: number;
234
+ webhooks: any[];
235
+ }
236
+
237
+ export type LanguageCode =
238
+ | 'ar'
239
+ | 'bg'
240
+ | 'ca'
241
+ | 'ch'
242
+ | 'cz'
243
+ | 'de'
244
+ | 'dk'
245
+ | 'ee'
246
+ | 'en'
247
+ | 'es'
248
+ | 'fi'
249
+ | 'fr'
250
+ | 'frq'
251
+ | 'gr'
252
+ | 'he'
253
+ | 'hr'
254
+ | 'hu'
255
+ | 'it'
256
+ | 'lt'
257
+ | 'lv'
258
+ | 'mk'
259
+ | 'mx'
260
+ | 'nl'
261
+ | 'no'
262
+ | 'pl'
263
+ | 'pr'
264
+ | 'pt'
265
+ | 'ptbr'
266
+ | 'ro'
267
+ | 'ru'
268
+ | 'se'
269
+ | 'sk'
270
+ | 'sl'
271
+ | 'sr'
272
+ | 'tr'
273
+ | 'ua'
274
+ | string
275
+ | null;
@@ -0,0 +1,7 @@
1
+ import { AxiosInstance } from 'axios';
2
+ import { AccountWrap } from '../@types';
3
+ export default function (client: AxiosInstance): {
4
+ getAccountRaw(): Promise<AccountWrap>;
5
+ getAccount(): Promise<import("../@types").Account>;
6
+ getMe(): Promise<import("../@types").Account>;
7
+ };
@@ -0,0 +1,76 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ var __generator = (this && this.__generator) || function (thisArg, body) {
12
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
13
+ return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
14
+ function verb(n) { return function (v) { return step([n, v]); }; }
15
+ function step(op) {
16
+ if (f) throw new TypeError("Generator is already executing.");
17
+ while (g && (g = 0, op[0] && (_ = 0)), _) try {
18
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
19
+ if (y = 0, t) op = [op[0] & 2, t.value];
20
+ switch (op[0]) {
21
+ case 0: case 1: t = op; break;
22
+ case 4: _.label++; return { value: op[1], done: false };
23
+ case 5: _.label++; y = op[1]; op = [0]; continue;
24
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
25
+ default:
26
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
27
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
28
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
29
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
30
+ if (t[2]) _.ops.pop();
31
+ _.trys.pop(); continue;
32
+ }
33
+ op = body.call(thisArg, _);
34
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
35
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
36
+ }
37
+ };
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ exports.default = default_1;
40
+ function default_1(client) {
41
+ return {
42
+ getAccountRaw: function () {
43
+ return __awaiter(this, void 0, void 0, function () {
44
+ return __generator(this, function (_a) {
45
+ switch (_a.label) {
46
+ case 0: return [4 /*yield*/, client.get('me')];
47
+ case 1: return [2 /*return*/, _a.sent()];
48
+ }
49
+ });
50
+ });
51
+ },
52
+ getAccount: function () {
53
+ return __awaiter(this, void 0, void 0, function () {
54
+ var account;
55
+ return __generator(this, function (_a) {
56
+ switch (_a.label) {
57
+ case 0: return [4 /*yield*/, this.getAccountRaw()];
58
+ case 1:
59
+ account = (_a.sent()).account;
60
+ return [2 /*return*/, account];
61
+ }
62
+ });
63
+ });
64
+ },
65
+ getMe: function () {
66
+ return __awaiter(this, void 0, void 0, function () {
67
+ return __generator(this, function (_a) {
68
+ switch (_a.label) {
69
+ case 0: return [4 /*yield*/, this.getAccount()];
70
+ case 1: return [2 /*return*/, _a.sent()];
71
+ }
72
+ });
73
+ });
74
+ },
75
+ };
76
+ }
@@ -0,0 +1,5 @@
1
+ import { AxiosInstance } from 'axios';
2
+ import { Batch } from '../@types';
3
+ export default function (client: AxiosInstance): {
4
+ batch(requests: Batch[]): Promise<any[]>;
5
+ };
@@ -0,0 +1,55 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ var __generator = (this && this.__generator) || function (thisArg, body) {
12
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
13
+ return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
14
+ function verb(n) { return function (v) { return step([n, v]); }; }
15
+ function step(op) {
16
+ if (f) throw new TypeError("Generator is already executing.");
17
+ while (g && (g = 0, op[0] && (_ = 0)), _) try {
18
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
19
+ if (y = 0, t) op = [op[0] & 2, t.value];
20
+ switch (op[0]) {
21
+ case 0: case 1: t = op; break;
22
+ case 4: _.label++; return { value: op[1], done: false };
23
+ case 5: _.label++; y = op[1]; op = [0]; continue;
24
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
25
+ default:
26
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
27
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
28
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
29
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
30
+ if (t[2]) _.ops.pop();
31
+ _.trys.pop(); continue;
32
+ }
33
+ op = body.call(thisArg, _);
34
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
35
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
36
+ }
37
+ };
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ exports.default = default_1;
40
+ function default_1(client) {
41
+ return {
42
+ batch: function (requests) {
43
+ return __awaiter(this, void 0, void 0, function () {
44
+ return __generator(this, function (_a) {
45
+ switch (_a.label) {
46
+ case 0: return [4 /*yield*/, client.post('batch', {
47
+ requests: requests,
48
+ })];
49
+ case 1: return [2 /*return*/, _a.sent()];
50
+ }
51
+ });
52
+ });
53
+ },
54
+ };
55
+ }
@@ -0,0 +1,10 @@
1
+ import { AxiosInstance } from 'axios';
2
+ import { CampaignAction, CampaignContent, CampaignData, CampaignQuery, CampaignSendData, CampaignStatus } from '../@types';
3
+ export default function (client: AxiosInstance): {
4
+ actOnCampaign(campaignId: number, action: CampaignAction, data?: CampaignSendData): Promise<import("axios").AxiosResponse<any, any>>;
5
+ getCampaigns(status?: CampaignStatus, params?: CampaignQuery): Promise<import("axios").AxiosResponse<any, any>>;
6
+ getCampaignCount(status?: CampaignStatus): Promise<number>;
7
+ createCampaign(campaign: CampaignData): Promise<import("axios").AxiosResponse<any, any>>;
8
+ removeCampaign(campaignId: number): Promise<import("axios").AxiosResponse<any, any>>;
9
+ setCampaignContent(campaignId: number, content: CampaignContent): Promise<import("axios").AxiosResponse<any, any>>;
10
+ };