@openfn/language-mailchimp 0.4.1 → 0.6.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
@@ -12,36 +12,6 @@ official
12
12
  [configuration-schema](https://docs.openfn.org/adaptors/packages/mailchimp-configuration-schema/)
13
13
  definition.
14
14
 
15
- #### sample expression with multiple operations
16
-
17
- ```js
18
- upsertMembers({
19
- listId: 'someId',
20
- users: state =>
21
- state.response.body.rows.map(u => ({
22
- email: u.email,
23
- status: u.allow_other_emails ? 'subscribed' : 'unsubscribed',
24
- mergeFields: { FNAME: u.first_name, LNAME: u.last_name },
25
- })),
26
- options: {},
27
- });
28
-
29
- tagMembers({
30
- listId: 'someId', // All Subscribers
31
- tagId: 'someTag', // User
32
- members: state => state.response.body.rows.map(u => u.email),
33
- });
34
-
35
- tagMembers({
36
- listId: 'someId', // All Subscribers
37
- tagId: 'someTag', // Other Emails Allowed
38
- members: state =>
39
- state.response.body.rows
40
- .filter(u => u.allow_other_emails)
41
- .map(u => u.email),
42
- });
43
- ```
44
-
45
15
  ## Development
46
16
 
47
17
  Clone the [adaptors monorepo](https://github.com/OpenFn/adaptors). Follow the
package/dist/index.cjs CHANGED
@@ -25,23 +25,34 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
25
25
  // src/index.js
26
26
  var src_exports = {};
27
27
  __export(src_exports, {
28
- alterState: () => import_language_common2.alterState,
28
+ addMember: () => addMember,
29
+ alterState: () => import_language_common3.alterState,
30
+ archiveMember: () => archiveMember,
29
31
  axios: () => import_axios.default,
30
- dataPath: () => import_language_common2.dataPath,
31
- dataValue: () => import_language_common2.dataValue,
32
+ dataPath: () => import_language_common3.dataPath,
33
+ dataValue: () => import_language_common3.dataValue,
32
34
  default: () => src_default,
33
- each: () => import_language_common2.each,
35
+ deleteMember: () => deleteMember,
36
+ each: () => import_language_common3.each,
34
37
  execute: () => execute,
35
- field: () => import_language_common2.field,
36
- fields: () => import_language_common2.fields,
37
- fn: () => import_language_common2.fn,
38
- lastReferenceValue: () => import_language_common2.lastReferenceValue,
38
+ field: () => import_language_common3.field,
39
+ fields: () => import_language_common3.fields,
40
+ fn: () => import_language_common3.fn,
41
+ get: () => get,
42
+ lastReferenceValue: () => import_language_common3.lastReferenceValue,
43
+ listAudienceInfo: () => listAudienceInfo,
44
+ listAudiences: () => listAudiences,
39
45
  listBatches: () => listBatches,
46
+ listMembers: () => listMembers,
40
47
  md5: () => import_md5.default,
41
- merge: () => import_language_common2.merge,
42
- sourceValue: () => import_language_common2.sourceValue,
48
+ merge: () => import_language_common3.merge,
49
+ post: () => post,
50
+ request: () => request,
51
+ sourceValue: () => import_language_common3.sourceValue,
43
52
  startBatch: () => startBatch,
44
53
  tagMembers: () => tagMembers,
54
+ updateMember: () => updateMember,
55
+ updateMemberTags: () => updateMemberTags,
45
56
  upsertMembers: () => upsertMembers
46
57
  });
47
58
  module.exports = __toCommonJS(src_exports);
@@ -49,115 +60,274 @@ module.exports = __toCommonJS(src_exports);
49
60
  // src/Adaptor.js
50
61
  var Adaptor_exports = {};
51
62
  __export(Adaptor_exports, {
52
- alterState: () => import_language_common2.alterState,
63
+ addMember: () => addMember,
64
+ alterState: () => import_language_common3.alterState,
65
+ archiveMember: () => archiveMember,
53
66
  axios: () => import_axios.default,
54
- dataPath: () => import_language_common2.dataPath,
55
- dataValue: () => import_language_common2.dataValue,
56
- each: () => import_language_common2.each,
67
+ dataPath: () => import_language_common3.dataPath,
68
+ dataValue: () => import_language_common3.dataValue,
69
+ deleteMember: () => deleteMember,
70
+ each: () => import_language_common3.each,
57
71
  execute: () => execute,
58
- field: () => import_language_common2.field,
59
- fields: () => import_language_common2.fields,
60
- fn: () => import_language_common2.fn,
61
- lastReferenceValue: () => import_language_common2.lastReferenceValue,
72
+ field: () => import_language_common3.field,
73
+ fields: () => import_language_common3.fields,
74
+ fn: () => import_language_common3.fn,
75
+ get: () => get,
76
+ lastReferenceValue: () => import_language_common3.lastReferenceValue,
77
+ listAudienceInfo: () => listAudienceInfo,
78
+ listAudiences: () => listAudiences,
62
79
  listBatches: () => listBatches,
80
+ listMembers: () => listMembers,
63
81
  md5: () => import_md5.default,
64
- merge: () => import_language_common2.merge,
65
- sourceValue: () => import_language_common2.sourceValue,
82
+ merge: () => import_language_common3.merge,
83
+ post: () => post,
84
+ request: () => request,
85
+ sourceValue: () => import_language_common3.sourceValue,
66
86
  startBatch: () => startBatch,
67
87
  tagMembers: () => tagMembers,
88
+ updateMember: () => updateMember,
89
+ updateMemberTags: () => updateMemberTags,
68
90
  upsertMembers: () => upsertMembers
69
91
  });
70
- var import_language_common = require("@openfn/language-common");
92
+ var import_md5 = __toESM(require("md5"), 1);
71
93
  var import_axios = __toESM(require("axios"), 1);
72
94
  var import_mailchimp_marketing = __toESM(require("@mailchimp/mailchimp_marketing"), 1);
73
- var import_md5 = __toESM(require("md5"), 1);
95
+ var import_util = require("@openfn/language-common/util");
74
96
  var import_language_common2 = require("@openfn/language-common");
97
+
98
+ // src/Utils.js
99
+ var import_language_common = require("@openfn/language-common");
100
+ var import_undici = require("undici");
101
+ var client;
102
+ var getClient = (baseUrl) => {
103
+ if (client) {
104
+ return client;
105
+ }
106
+ return new import_undici.Client(baseUrl);
107
+ };
108
+ function handleResponse(response, state, callback) {
109
+ const nextState = {
110
+ ...(0, import_language_common.composeNextState)(state, response),
111
+ response
112
+ };
113
+ if (callback)
114
+ return callback(nextState);
115
+ return nextState;
116
+ }
117
+
118
+ // src/Adaptor.js
119
+ var import_language_common3 = require("@openfn/language-common");
75
120
  function execute(...operations) {
76
121
  const initialState = {
77
122
  references: [],
78
123
  data: null
79
124
  };
80
125
  return (state) => {
81
- return (0, import_language_common.execute)(...operations)({
126
+ return (0, import_language_common2.execute)(
127
+ createClient,
128
+ ...operations,
129
+ cleanupState
130
+ )({
82
131
  ...initialState,
83
132
  ...state
84
133
  });
85
134
  };
86
135
  }
87
- function upsertMembers(params) {
136
+ function createClient(state) {
137
+ const { apiKey, server } = state.configuration;
138
+ const baseUrl = `https://${server}.api.mailchimp.com`;
139
+ const apiClient = getClient(baseUrl);
140
+ import_mailchimp_marketing.default.setConfig({ apiKey, server });
141
+ return { ...state, apiClient, client: import_mailchimp_marketing.default };
142
+ }
143
+ function cleanupState(state) {
144
+ if (state == null ? void 0 : state.apiClient)
145
+ delete state.apiClient;
146
+ if (state == null ? void 0 : state.client)
147
+ delete state.client;
148
+ return state;
149
+ }
150
+ function upsertMembers(params, callback = (s) => s) {
88
151
  return (state) => {
89
- const { apiKey, server } = state.configuration;
90
- const { listId, users, options } = (0, import_language_common.expandReferences)(params)(state);
91
- import_mailchimp_marketing.default.setConfig({ apiKey, server });
92
- return Promise.all(
93
- users.map(
94
- (user) => import_mailchimp_marketing.default.lists.setListMember(listId, (0, import_md5.default)(user.email), {
95
- email_address: user.email,
96
- status_if_new: user.status,
97
- merge_fields: user.mergeFields
98
- }).then((response) => {
99
- state.references.push(response);
100
- })
101
- )
102
- ).then(() => {
103
- return state;
104
- });
152
+ const [resolvedParams] = (0, import_util.expandReferences)(state, params);
153
+ const defaultOptions2 = {
154
+ update_existing: true,
155
+ sync_tags: false
156
+ };
157
+ const { listId: listId2, users, options } = resolvedParams;
158
+ const opts = { ...defaultOptions2, ...options };
159
+ const membersList = users.map((member2) => ({
160
+ email_address: member2.email,
161
+ status: member2.status,
162
+ merge_fields: member2.mergeFields,
163
+ tags: member2.tags
164
+ }));
165
+ return state.client.lists.batchListMembers(listId2, {
166
+ ...opts,
167
+ members: membersList
168
+ }).then((response) => handleResponse(response, state, callback));
105
169
  };
106
170
  }
107
- function tagMembers(params) {
171
+ function tagMembers(params, callback = (s) => s) {
108
172
  return (state) => {
109
- const { apiKey, server } = state.configuration;
110
- const { listId, tagId, members } = (0, import_language_common.expandReferences)(params)(state);
111
- import_mailchimp_marketing.default.setConfig({ apiKey, server });
112
- return import_mailchimp_marketing.default.lists.batchSegmentMembers({ members_to_add: members }, listId, tagId).then((response) => {
113
- const nextState = (0, import_language_common.composeNextState)(state, response);
114
- return nextState;
115
- });
173
+ const [resolvedParams] = (0, import_util.expandReferences)(state, params);
174
+ const { listId: listId2, tagId, members } = resolvedParams;
175
+ return state.client.lists.batchSegmentMembers({ members_to_add: members }, listId2, tagId).then((response) => handleResponse(response, state, callback));
116
176
  };
117
177
  }
118
- function startBatch(params) {
178
+ function startBatch(params, callback = (s) => s) {
119
179
  return (state) => {
120
- const { apiKey, server } = state.configuration;
121
- const { operations } = (0, import_language_common.expandReferences)(params)(state);
122
- import_mailchimp_marketing.default.setConfig({ apiKey, server });
123
- return import_mailchimp_marketing.default.batches.start({ operations: [...operations] }).then((response) => {
124
- console.log(response);
125
- const nextState = (0, import_language_common.composeNextState)(state, response);
126
- return nextState;
127
- });
180
+ const [resolvedParams] = (0, import_util.expandReferences)(state, params);
181
+ const { operations } = resolvedParams;
182
+ return state.client.batches.start({ operations: [...operations] }).then((response) => handleResponse(response, state, callback));
183
+ };
184
+ }
185
+ function listBatches(params, callback = (s) => s) {
186
+ return (state) => {
187
+ const [resolvedParams] = (0, import_util.expandReferences)(state, params);
188
+ return state.client.batches.list(resolvedParams).then((response) => handleResponse(response, state, callback));
189
+ };
190
+ }
191
+ function listMembers(params, callback = (s) => s) {
192
+ return (state) => {
193
+ const [resolvedParams] = (0, import_util.expandReferences)(state, params);
194
+ const { listId: listId2, ...otherParams } = resolvedParams;
195
+ return state.client.lists.getListMembersInfo(listId2, otherParams).then((response) => handleResponse(response, state, callback));
128
196
  };
129
197
  }
130
- function listBatches(params) {
198
+ function addMember(params, callback = (s) => s) {
131
199
  return (state) => {
200
+ const [resolvedParams] = (0, import_util.expandReferences)(state, params);
201
+ const { listId: listId2, member: member2 } = resolvedParams;
202
+ return state.client.lists.addListMember(listId2, ...member2).then((response) => handleResponse(response, state, callback));
203
+ };
204
+ }
205
+ function updateMember(params = { listId, subscriberHash, member }, callback = (s) => s) {
206
+ return (state) => {
207
+ const requiredParams = ["listId", "subscriberHash"];
208
+ const [resolvedParams] = (0, import_util.expandReferences)(state, params);
209
+ assertKeys(resolvedParams, requiredParams);
210
+ const { listId: listId2, subscriberHash: subscriberHash2, member: member2 } = resolvedParams;
211
+ return state.client.lists.updateListMember(listId2, subscriberHash2, member2).then((response) => handleResponse(response, state, callback));
212
+ };
213
+ }
214
+ function updateMemberTags(params, callback = (s) => s) {
215
+ return (state) => {
216
+ const [resolvedParams] = (0, import_util.expandReferences)(state, params);
217
+ const { listId: listId2, subscriberHash: subscriberHash2, tags } = resolvedParams;
218
+ return state.client.lists.updateListMemberTags(listId2, subscriberHash2, { tags }).then((response) => handleResponse(response, state, callback));
219
+ };
220
+ }
221
+ function archiveMember(params, callback = (s) => s) {
222
+ return (state) => {
223
+ const [resolvedParams] = (0, import_util.expandReferences)(state, params);
224
+ const { listId: listId2, subscriberHash: subscriberHash2 } = resolvedParams;
225
+ return state.client.lists.deleteListMember(listId2, subscriberHash2).then((response) => handleResponse(response, state, callback));
226
+ };
227
+ }
228
+ function deleteMember(params, callback = (s) => s) {
229
+ return (state) => {
230
+ const [resolvedParams] = (0, import_util.expandReferences)(state, params);
231
+ const { listId: listId2, subscriberHash: subscriberHash2 } = resolvedParams;
232
+ return state.client.lists.deleteListMemberPermanent(listId2, subscriberHash2).then((response) => handleResponse(response, state, callback));
233
+ };
234
+ }
235
+ function listAudiences(query, callback = (s) => s) {
236
+ return (state) => {
237
+ const [resolvedQuery] = (0, import_util.expandReferences)(state, query);
238
+ return state.client.lists.getAllLists(resolvedQuery).then((response) => handleResponse(response, state, callback));
239
+ };
240
+ }
241
+ function listAudienceInfo(query, callback = (s) => s) {
242
+ return (state) => {
243
+ const [resolvedQuery] = (0, import_util.expandReferences)(state, query);
244
+ const { listId: listId2, ...queries } = resolvedQuery;
245
+ return state.client.lists.getList(listId2, queries).then((response) => handleResponse(response, state, callback));
246
+ };
247
+ }
248
+ var defaultOptions = {
249
+ query: {},
250
+ body: void 0
251
+ };
252
+ var assertOK = (response, fullUrl) => {
253
+ if (response.statusCode >= 400) {
254
+ const defaultErrorMesssage = `Request to ${fullUrl} failed with status: ${response.statusCode}`;
255
+ const error = new Error(defaultErrorMesssage);
256
+ error.code = response.statusCode;
257
+ error.url = fullUrl;
258
+ throw error;
259
+ }
260
+ };
261
+ var request = (method, path, options, callback) => {
262
+ return async (state) => {
263
+ const apiVersion = "3.0";
132
264
  const { apiKey, server } = state.configuration;
133
- import_mailchimp_marketing.default.setConfig({ apiKey, server });
134
- return import_mailchimp_marketing.default.batches.list().then((response) => {
135
- console.log(response);
136
- const nextState = (0, import_language_common.composeNextState)(state, response);
137
- return nextState;
265
+ const [resolvedMethod, resolvedPath, resolvedOptions] = (0, import_util.expandReferences)(
266
+ state,
267
+ method,
268
+ path,
269
+ options
270
+ );
271
+ const { query, body } = { ...defaultOptions, ...resolvedOptions };
272
+ const apiToken = Buffer.from(`openfn:${apiKey}`, "utf-8").toString(
273
+ "base64"
274
+ );
275
+ const headers = {
276
+ "Content-Type": "application/json",
277
+ Authorization: `Basic ${apiToken}`
278
+ };
279
+ const urlPath = `/${apiVersion}${resolvedPath}`;
280
+ const response = await state.apiClient.request({
281
+ method: resolvedMethod,
282
+ path: urlPath,
283
+ headers,
284
+ query,
285
+ body: body ? JSON.stringify(body) : void 0
138
286
  });
287
+ assertOK(response, `https://${server}.api.mailchimp.com${urlPath}`);
288
+ const responseBody = await response.body.json();
289
+ const nextState = {
290
+ data: responseBody,
291
+ response: responseBody
292
+ };
293
+ if (callback)
294
+ return callback(nextState);
295
+ return nextState;
139
296
  };
140
- }
297
+ };
298
+ var get = (path, query, callback) => request("GET", path, { query }, callback);
299
+ var post = (path, body, query, callback) => request("POST", path, { body, query }, callback);
141
300
 
142
301
  // src/index.js
143
302
  var src_default = Adaptor_exports;
144
303
  // Annotate the CommonJS export names for ESM import in node:
145
304
  0 && (module.exports = {
305
+ addMember,
146
306
  alterState,
307
+ archiveMember,
147
308
  axios,
148
309
  dataPath,
149
310
  dataValue,
311
+ deleteMember,
150
312
  each,
151
313
  execute,
152
314
  field,
153
315
  fields,
154
316
  fn,
317
+ get,
155
318
  lastReferenceValue,
319
+ listAudienceInfo,
320
+ listAudiences,
156
321
  listBatches,
322
+ listMembers,
157
323
  md5,
158
324
  merge,
325
+ post,
326
+ request,
159
327
  sourceValue,
160
328
  startBatch,
161
329
  tagMembers,
330
+ updateMember,
331
+ updateMemberTags,
162
332
  upsertMembers
163
333
  });
package/dist/index.js CHANGED
@@ -7,32 +7,62 @@ var __export = (target, all) => {
7
7
  // src/Adaptor.js
8
8
  var Adaptor_exports = {};
9
9
  __export(Adaptor_exports, {
10
+ addMember: () => addMember,
10
11
  alterState: () => alterState,
12
+ archiveMember: () => archiveMember,
11
13
  axios: () => axios,
12
14
  dataPath: () => dataPath,
13
15
  dataValue: () => dataValue,
16
+ deleteMember: () => deleteMember,
14
17
  each: () => each,
15
18
  execute: () => execute,
16
19
  field: () => field,
17
20
  fields: () => fields,
18
21
  fn: () => fn,
22
+ get: () => get,
19
23
  lastReferenceValue: () => lastReferenceValue,
24
+ listAudienceInfo: () => listAudienceInfo,
25
+ listAudiences: () => listAudiences,
20
26
  listBatches: () => listBatches,
27
+ listMembers: () => listMembers,
21
28
  md5: () => md5,
22
29
  merge: () => merge,
30
+ post: () => post,
31
+ request: () => request,
23
32
  sourceValue: () => sourceValue,
24
33
  startBatch: () => startBatch,
25
34
  tagMembers: () => tagMembers,
35
+ updateMember: () => updateMember,
36
+ updateMemberTags: () => updateMemberTags,
26
37
  upsertMembers: () => upsertMembers
27
38
  });
28
- import {
29
- execute as commonExecute,
30
- composeNextState,
31
- expandReferences
32
- } from "@openfn/language-common";
33
- import axios from "axios";
34
- import client from "@mailchimp/mailchimp_marketing";
35
39
  import md5 from "md5";
40
+ import axios from "axios";
41
+ import client2 from "@mailchimp/mailchimp_marketing";
42
+ import { expandReferences } from "@openfn/language-common/util";
43
+ import { execute as commonExecute } from "@openfn/language-common";
44
+
45
+ // src/Utils.js
46
+ import { composeNextState } from "@openfn/language-common";
47
+ import { Client, MockAgent } from "undici";
48
+ var client;
49
+ var getClient = (baseUrl) => {
50
+ if (client) {
51
+ return client;
52
+ }
53
+ return new Client(baseUrl);
54
+ };
55
+ function handleResponse(response, state, callback) {
56
+ const nextState = {
57
+ ...composeNextState(state, response),
58
+ response
59
+ };
60
+ if (callback)
61
+ return callback(nextState);
62
+ return nextState;
63
+ }
64
+
65
+ // src/Adaptor.js
36
66
  import {
37
67
  fn,
38
68
  alterState,
@@ -51,86 +81,211 @@ function execute(...operations) {
51
81
  data: null
52
82
  };
53
83
  return (state) => {
54
- return commonExecute(...operations)({
84
+ return commonExecute(
85
+ createClient,
86
+ ...operations,
87
+ cleanupState
88
+ )({
55
89
  ...initialState,
56
90
  ...state
57
91
  });
58
92
  };
59
93
  }
60
- function upsertMembers(params) {
94
+ function createClient(state) {
95
+ const { apiKey, server } = state.configuration;
96
+ const baseUrl = `https://${server}.api.mailchimp.com`;
97
+ const apiClient = getClient(baseUrl);
98
+ client2.setConfig({ apiKey, server });
99
+ return { ...state, apiClient, client: client2 };
100
+ }
101
+ function cleanupState(state) {
102
+ if (state == null ? void 0 : state.apiClient)
103
+ delete state.apiClient;
104
+ if (state == null ? void 0 : state.client)
105
+ delete state.client;
106
+ return state;
107
+ }
108
+ function upsertMembers(params, callback = (s) => s) {
109
+ return (state) => {
110
+ const [resolvedParams] = expandReferences(state, params);
111
+ const defaultOptions2 = {
112
+ update_existing: true,
113
+ sync_tags: false
114
+ };
115
+ const { listId: listId2, users, options } = resolvedParams;
116
+ const opts = { ...defaultOptions2, ...options };
117
+ const membersList = users.map((member2) => ({
118
+ email_address: member2.email,
119
+ status: member2.status,
120
+ merge_fields: member2.mergeFields,
121
+ tags: member2.tags
122
+ }));
123
+ return state.client.lists.batchListMembers(listId2, {
124
+ ...opts,
125
+ members: membersList
126
+ }).then((response) => handleResponse(response, state, callback));
127
+ };
128
+ }
129
+ function tagMembers(params, callback = (s) => s) {
61
130
  return (state) => {
62
- const { apiKey, server } = state.configuration;
63
- const { listId, users, options } = expandReferences(params)(state);
64
- client.setConfig({ apiKey, server });
65
- return Promise.all(
66
- users.map(
67
- (user) => client.lists.setListMember(listId, md5(user.email), {
68
- email_address: user.email,
69
- status_if_new: user.status,
70
- merge_fields: user.mergeFields
71
- }).then((response) => {
72
- state.references.push(response);
73
- })
74
- )
75
- ).then(() => {
76
- return state;
77
- });
131
+ const [resolvedParams] = expandReferences(state, params);
132
+ const { listId: listId2, tagId, members } = resolvedParams;
133
+ return state.client.lists.batchSegmentMembers({ members_to_add: members }, listId2, tagId).then((response) => handleResponse(response, state, callback));
78
134
  };
79
135
  }
80
- function tagMembers(params) {
136
+ function startBatch(params, callback = (s) => s) {
81
137
  return (state) => {
82
- const { apiKey, server } = state.configuration;
83
- const { listId, tagId, members } = expandReferences(params)(state);
84
- client.setConfig({ apiKey, server });
85
- return client.lists.batchSegmentMembers({ members_to_add: members }, listId, tagId).then((response) => {
86
- const nextState = composeNextState(state, response);
87
- return nextState;
88
- });
138
+ const [resolvedParams] = expandReferences(state, params);
139
+ const { operations } = resolvedParams;
140
+ return state.client.batches.start({ operations: [...operations] }).then((response) => handleResponse(response, state, callback));
89
141
  };
90
142
  }
91
- function startBatch(params) {
143
+ function listBatches(params, callback = (s) => s) {
92
144
  return (state) => {
93
- const { apiKey, server } = state.configuration;
94
- const { operations } = expandReferences(params)(state);
95
- client.setConfig({ apiKey, server });
96
- return client.batches.start({ operations: [...operations] }).then((response) => {
97
- console.log(response);
98
- const nextState = composeNextState(state, response);
99
- return nextState;
100
- });
145
+ const [resolvedParams] = expandReferences(state, params);
146
+ return state.client.batches.list(resolvedParams).then((response) => handleResponse(response, state, callback));
147
+ };
148
+ }
149
+ function listMembers(params, callback = (s) => s) {
150
+ return (state) => {
151
+ const [resolvedParams] = expandReferences(state, params);
152
+ const { listId: listId2, ...otherParams } = resolvedParams;
153
+ return state.client.lists.getListMembersInfo(listId2, otherParams).then((response) => handleResponse(response, state, callback));
101
154
  };
102
155
  }
103
- function listBatches(params) {
156
+ function addMember(params, callback = (s) => s) {
104
157
  return (state) => {
158
+ const [resolvedParams] = expandReferences(state, params);
159
+ const { listId: listId2, member: member2 } = resolvedParams;
160
+ return state.client.lists.addListMember(listId2, ...member2).then((response) => handleResponse(response, state, callback));
161
+ };
162
+ }
163
+ function updateMember(params = { listId, subscriberHash, member }, callback = (s) => s) {
164
+ return (state) => {
165
+ const requiredParams = ["listId", "subscriberHash"];
166
+ const [resolvedParams] = expandReferences(state, params);
167
+ assertKeys(resolvedParams, requiredParams);
168
+ const { listId: listId2, subscriberHash: subscriberHash2, member: member2 } = resolvedParams;
169
+ return state.client.lists.updateListMember(listId2, subscriberHash2, member2).then((response) => handleResponse(response, state, callback));
170
+ };
171
+ }
172
+ function updateMemberTags(params, callback = (s) => s) {
173
+ return (state) => {
174
+ const [resolvedParams] = expandReferences(state, params);
175
+ const { listId: listId2, subscriberHash: subscriberHash2, tags } = resolvedParams;
176
+ return state.client.lists.updateListMemberTags(listId2, subscriberHash2, { tags }).then((response) => handleResponse(response, state, callback));
177
+ };
178
+ }
179
+ function archiveMember(params, callback = (s) => s) {
180
+ return (state) => {
181
+ const [resolvedParams] = expandReferences(state, params);
182
+ const { listId: listId2, subscriberHash: subscriberHash2 } = resolvedParams;
183
+ return state.client.lists.deleteListMember(listId2, subscriberHash2).then((response) => handleResponse(response, state, callback));
184
+ };
185
+ }
186
+ function deleteMember(params, callback = (s) => s) {
187
+ return (state) => {
188
+ const [resolvedParams] = expandReferences(state, params);
189
+ const { listId: listId2, subscriberHash: subscriberHash2 } = resolvedParams;
190
+ return state.client.lists.deleteListMemberPermanent(listId2, subscriberHash2).then((response) => handleResponse(response, state, callback));
191
+ };
192
+ }
193
+ function listAudiences(query, callback = (s) => s) {
194
+ return (state) => {
195
+ const [resolvedQuery] = expandReferences(state, query);
196
+ return state.client.lists.getAllLists(resolvedQuery).then((response) => handleResponse(response, state, callback));
197
+ };
198
+ }
199
+ function listAudienceInfo(query, callback = (s) => s) {
200
+ return (state) => {
201
+ const [resolvedQuery] = expandReferences(state, query);
202
+ const { listId: listId2, ...queries } = resolvedQuery;
203
+ return state.client.lists.getList(listId2, queries).then((response) => handleResponse(response, state, callback));
204
+ };
205
+ }
206
+ var defaultOptions = {
207
+ query: {},
208
+ body: void 0
209
+ };
210
+ var assertOK = (response, fullUrl) => {
211
+ if (response.statusCode >= 400) {
212
+ const defaultErrorMesssage = `Request to ${fullUrl} failed with status: ${response.statusCode}`;
213
+ const error = new Error(defaultErrorMesssage);
214
+ error.code = response.statusCode;
215
+ error.url = fullUrl;
216
+ throw error;
217
+ }
218
+ };
219
+ var request = (method, path, options, callback) => {
220
+ return async (state) => {
221
+ const apiVersion = "3.0";
105
222
  const { apiKey, server } = state.configuration;
106
- client.setConfig({ apiKey, server });
107
- return client.batches.list().then((response) => {
108
- console.log(response);
109
- const nextState = composeNextState(state, response);
110
- return nextState;
223
+ const [resolvedMethod, resolvedPath, resolvedOptions] = expandReferences(
224
+ state,
225
+ method,
226
+ path,
227
+ options
228
+ );
229
+ const { query, body } = { ...defaultOptions, ...resolvedOptions };
230
+ const apiToken = Buffer.from(`openfn:${apiKey}`, "utf-8").toString(
231
+ "base64"
232
+ );
233
+ const headers = {
234
+ "Content-Type": "application/json",
235
+ Authorization: `Basic ${apiToken}`
236
+ };
237
+ const urlPath = `/${apiVersion}${resolvedPath}`;
238
+ const response = await state.apiClient.request({
239
+ method: resolvedMethod,
240
+ path: urlPath,
241
+ headers,
242
+ query,
243
+ body: body ? JSON.stringify(body) : void 0
111
244
  });
245
+ assertOK(response, `https://${server}.api.mailchimp.com${urlPath}`);
246
+ const responseBody = await response.body.json();
247
+ const nextState = {
248
+ data: responseBody,
249
+ response: responseBody
250
+ };
251
+ if (callback)
252
+ return callback(nextState);
253
+ return nextState;
112
254
  };
113
- }
255
+ };
256
+ var get = (path, query, callback) => request("GET", path, { query }, callback);
257
+ var post = (path, body, query, callback) => request("POST", path, { body, query }, callback);
114
258
 
115
259
  // src/index.js
116
260
  var src_default = Adaptor_exports;
117
261
  export {
262
+ addMember,
118
263
  alterState,
264
+ archiveMember,
119
265
  axios,
120
266
  dataPath,
121
267
  dataValue,
122
268
  src_default as default,
269
+ deleteMember,
123
270
  each,
124
271
  execute,
125
272
  field,
126
273
  fields,
127
274
  fn,
275
+ get,
128
276
  lastReferenceValue,
277
+ listAudienceInfo,
278
+ listAudiences,
129
279
  listBatches,
280
+ listMembers,
130
281
  md5,
131
282
  merge,
283
+ post,
284
+ request,
132
285
  sourceValue,
133
286
  startBatch,
134
287
  tagMembers,
288
+ updateMember,
289
+ updateMemberTags,
135
290
  upsertMembers
136
291
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openfn/language-mailchimp",
3
- "version": "0.4.1",
3
+ "version": "0.6.0",
4
4
  "description": "An OpenFn adaptor for use with Mailchimp",
5
5
  "main": "dist/index.cjs",
6
6
  "author": "Open Function Group",
@@ -15,17 +15,17 @@
15
15
  "@mailchimp/mailchimp_marketing": "^3.0.80",
16
16
  "@openfn/language-common": "^1.8.1",
17
17
  "axios": "^0.21.2",
18
- "md5": "^2.3.0"
18
+ "md5": "^2.3.0",
19
+ "undici": "^5.22.1"
19
20
  },
20
21
  "devDependencies": {
21
22
  "@openfn/buildtools": "^1.0.2",
22
23
  "@openfn/simple-ast": "0.4.1",
23
24
  "assertion-error": "^1.1.0",
24
- "chai": "^3.5.0",
25
+ "chai": "^4.3.6",
25
26
  "deep-eql": "^0.1.3",
26
27
  "esno": "^0.16.3",
27
28
  "mocha": "^7.2.0",
28
- "nock": "^12.0.3",
29
29
  "rimraf": "^3.0.2"
30
30
  },
31
31
  "repository": {
@@ -12,33 +12,130 @@
12
12
  */
13
13
  export function execute(...operations: Operations): Operation;
14
14
  /**
15
- * Add members to a particular audience
15
+ * Add or update a list members
16
16
  * @example
17
- * upsertMembers(params)
17
+ * upsertMembers((state) => ({
18
+ * listId: "someId",
19
+ * users: state.response.body.rows.map((u) => ({
20
+ * email: u.email,
21
+ * status: u.allow_other_emails ? "subscribed" : "unsubscribed",
22
+ * mergeFields: { FNAME: u.first_name, LNAME: u.last_name },
23
+ * })),
24
+ * }));
18
25
  * @function
19
26
  * @param {object} params - a listId, users, and options
27
+ * @param {function} [callback] - Optional callback to handle the response
20
28
  * @returns {Operation}
21
29
  */
22
- export function upsertMembers(params: object): Operation;
30
+ export function upsertMembers(params: object, callback?: Function): Operation;
23
31
  /**
24
32
  * Tag members with a particular tag
25
33
  * @example
26
- * tagMembers(params)
34
+ * tagMembers((state) => ({
35
+ * listId: "someId", // All Subscribers list
36
+ * tagId: "someTag", // User tag
37
+ * members: state.response.body.rows.map((u) => u.email),
38
+ * }));
39
+ * @example
40
+ * tagMembers((state) => ({
41
+ * listId: "someId",
42
+ * tagId: "someTag",
43
+ * members: state.response.body.rows
44
+ * .filter((u) => u.allow_other_emails)
45
+ * .map((u) => u.email),
46
+ * }));
27
47
  * @function
28
48
  * @param {object} params - a tagId, members, and a list
49
+ * @param {function} [callback] - Optional callback to handle the response
29
50
  * @returns {Operation}
30
51
  */
31
- export function tagMembers(params: object): Operation;
52
+ export function tagMembers(params: object, callback?: Function): Operation;
32
53
  /**
33
54
  * Start a batch with a list of operations.
34
55
  * @example
35
56
  * startBatch(params)
36
57
  * @function
37
58
  * @param {object} params - operations batch job
59
+ * @param {function} [callback] - Optional callback to handle the response
60
+ * @returns {Operation}
61
+ */
62
+ export function startBatch(params: object, callback?: Function): Operation;
63
+ /**
64
+ * listBatches
65
+ * @function
66
+ * @param {object} params - a listId, and options
67
+ * @param {function} [callback] - Optional callback to handle the response
68
+ * @returns {Operation}
69
+ */
70
+ export function listBatches(params: object, callback?: Function): Operation;
71
+ /**
72
+ * listMembers
73
+ * @function
74
+ * @param {object} params - a listId, and options
75
+ * @param {function} [callback] - Optional callback to handle the response
76
+ * @returns {Operation}
77
+ */
78
+ export function listMembers(params: object, callback?: Function): Operation;
79
+ /**
80
+ * addMember to a list
81
+ * @function
82
+ * @param {object} params - a listId, and options
83
+ * @param {function} [callback] - Optional callback to handle the response
84
+ * @returns {Operation}
85
+ */
86
+ export function addMember(params: object, callback?: Function): Operation;
87
+ /**
88
+ * updateMember
89
+ * @function
90
+ * @param {object} params - a listId,subscriberHash and member
91
+ * @param {function} [callback] - Optional callback to handle the response
92
+ * @returns {Operation}
93
+ */
94
+ export function updateMember(params?: object, callback?: Function): Operation;
95
+ /**
96
+ * updateMemberTags
97
+ * @function
98
+ * @param {object} params - a listId, and options
99
+ * @param {function} [callback] - Optional callback to handle the response
100
+ * @returns {Operation}
101
+ */
102
+ export function updateMemberTags(params: object, callback?: Function): Operation;
103
+ /**
104
+ * archiveMember in a list
105
+ * @function
106
+ * @param {object} params - a listId, and options
107
+ * @param {function} [callback] - Optional callback to handle the response
108
+ * @returns {Operation}
109
+ */
110
+ export function archiveMember(params: object, callback?: Function): Operation;
111
+ /**
112
+ * Permanently delete a member from a list
113
+ * @function
114
+ * @param {object} params - a listId, and options
115
+ * @param {function} [callback] - Optional callback to handle the response
116
+ * @returns {Operation}
117
+ */
118
+ export function deleteMember(params: object, callback?: Function): Operation;
119
+ /**
120
+ * Get information about all lists in the account.
121
+ * @function
122
+ * @param {object} query - Query parameters
123
+ * @param {function} [callback] - Optional callback to handle the response
124
+ * @returns {Operation}
125
+ */
126
+ export function listAudiences(query: object, callback?: Function): Operation;
127
+ /**
128
+ * Get information about a specific list in your Mailchimp account.
129
+ * Results include list members who have signed up but haven't confirmed their subscription yet and unsubscribed or cleaned.
130
+ * @function
131
+ * @param {object} query - listId and query parameters
132
+ * @param {function} [callback] - Optional callback to handle the response
38
133
  * @returns {Operation}
39
134
  */
40
- export function startBatch(params: object): Operation;
41
- export function listBatches(params: any): (state: any) => any;
135
+ export function listAudienceInfo(query: object, callback?: Function): Operation;
136
+ export function request(method: string, path: string, options: any, callback?: Function): Operation;
137
+ export function get(path: string, query: object, callback?: Function): Operation;
138
+ export function post(path: string, body: object, query: object, callback?: Function): Operation;
42
139
  import axios from "axios";
43
140
  export { axios, md5 };
44
141
  export { fn, alterState, dataPath, dataValue, each, field, fields, lastReferenceValue, merge, sourceValue } from "@openfn/language-common";
@@ -0,0 +1,3 @@
1
+ export function handleResponse(response: any, state: any, callback: any): any;
2
+ export function getClient(baseUrl: any): any;
3
+ export function enableMockClient(baseUrl: any): import("undici/types/mock-interceptor").Interceptable;