digital-tools 2.1.3 → 2.4.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/.turbo/turbo-build.log +1 -1
- package/CHANGELOG.md +19 -0
- package/README.md +2 -0
- package/dist/client.d.ts +109 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +69 -0
- package/dist/client.js.map +1 -0
- package/dist/define.d.ts +2 -2
- package/dist/define.d.ts.map +1 -1
- package/dist/define.js +21 -11
- package/dist/define.js.map +1 -1
- package/dist/function-ref.d.ts +229 -0
- package/dist/function-ref.d.ts.map +1 -0
- package/dist/function-ref.js +28 -0
- package/dist/function-ref.js.map +1 -0
- package/dist/function-sugar.d.ts +57 -0
- package/dist/function-sugar.d.ts.map +1 -0
- package/dist/function-sugar.js +79 -0
- package/dist/function-sugar.js.map +1 -0
- package/dist/index.d.ts +10 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +24 -4
- package/dist/index.js.map +1 -1
- package/dist/providers/analytics/mixpanel.d.ts.map +1 -1
- package/dist/providers/analytics/mixpanel.js +21 -18
- package/dist/providers/analytics/mixpanel.js.map +1 -1
- package/dist/providers/calendar/cal-com.d.ts.map +1 -1
- package/dist/providers/calendar/cal-com.js +10 -10
- package/dist/providers/calendar/cal-com.js.map +1 -1
- package/dist/providers/calendar/google-calendar.d.ts.map +1 -1
- package/dist/providers/calendar/google-calendar.js +4 -4
- package/dist/providers/calendar/google-calendar.js.map +1 -1
- package/dist/providers/crm/hubspot.d.ts.map +1 -1
- package/dist/providers/crm/hubspot.js +107 -85
- package/dist/providers/crm/hubspot.js.map +1 -1
- package/dist/providers/development/github.d.ts.map +1 -1
- package/dist/providers/development/github.js +40 -43
- package/dist/providers/development/github.js.map +1 -1
- package/dist/providers/ecommerce/shopify.d.ts.map +1 -1
- package/dist/providers/ecommerce/shopify.js +79 -62
- package/dist/providers/ecommerce/shopify.js.map +1 -1
- package/dist/providers/email/resend.d.ts.map +1 -1
- package/dist/providers/email/resend.js +20 -16
- package/dist/providers/email/resend.js.map +1 -1
- package/dist/providers/email/sendgrid.d.ts.map +1 -1
- package/dist/providers/email/sendgrid.js +12 -9
- package/dist/providers/email/sendgrid.js.map +1 -1
- package/dist/providers/finance/stripe.d.ts.map +1 -1
- package/dist/providers/finance/stripe.js +44 -42
- package/dist/providers/finance/stripe.js.map +1 -1
- package/dist/providers/forms/typeform.d.ts.map +1 -1
- package/dist/providers/forms/typeform.js +68 -58
- package/dist/providers/forms/typeform.js.map +1 -1
- package/dist/providers/knowledge/notion.d.ts.map +1 -1
- package/dist/providers/knowledge/notion.js +75 -41
- package/dist/providers/knowledge/notion.js.map +1 -1
- package/dist/providers/marketing/mailchimp.d.ts.map +1 -1
- package/dist/providers/marketing/mailchimp.js +74 -61
- package/dist/providers/marketing/mailchimp.js.map +1 -1
- package/dist/providers/media/cloudinary.d.ts.map +1 -1
- package/dist/providers/media/cloudinary.js +30 -28
- package/dist/providers/media/cloudinary.js.map +1 -1
- package/dist/providers/messaging/slack.d.ts.map +1 -1
- package/dist/providers/messaging/slack.js +75 -58
- package/dist/providers/messaging/slack.js.map +1 -1
- package/dist/providers/messaging/twilio-sms.d.ts.map +1 -1
- package/dist/providers/messaging/twilio-sms.js +33 -15
- package/dist/providers/messaging/twilio-sms.js.map +1 -1
- package/dist/providers/project-management/linear.d.ts.map +1 -1
- package/dist/providers/project-management/linear.js +31 -27
- package/dist/providers/project-management/linear.js.map +1 -1
- package/dist/providers/spreadsheet/google-sheets.d.ts.map +1 -1
- package/dist/providers/spreadsheet/google-sheets.js +21 -18
- package/dist/providers/spreadsheet/google-sheets.js.map +1 -1
- package/dist/providers/spreadsheet/xlsx.d.ts.map +1 -1
- package/dist/providers/spreadsheet/xlsx.js +4 -4
- package/dist/providers/spreadsheet/xlsx.js.map +1 -1
- package/dist/providers/storage/index.js +1 -0
- package/dist/providers/storage/index.js.map +1 -1
- package/dist/providers/storage/s3.d.ts.map +1 -1
- package/dist/providers/storage/s3.js +36 -27
- package/dist/providers/storage/s3.js.map +1 -1
- package/dist/providers/support/zendesk.d.ts.map +1 -1
- package/dist/providers/support/zendesk.js +24 -25
- package/dist/providers/support/zendesk.js.map +1 -1
- package/dist/providers/tasks/todoist.d.ts.map +1 -1
- package/dist/providers/tasks/todoist.js +18 -18
- package/dist/providers/tasks/todoist.js.map +1 -1
- package/dist/providers/video-conferencing/google-meet.d.ts.map +1 -1
- package/dist/providers/video-conferencing/google-meet.js +11 -11
- package/dist/providers/video-conferencing/google-meet.js.map +1 -1
- package/dist/providers/video-conferencing/jitsi.js +14 -14
- package/dist/providers/video-conferencing/jitsi.js.map +1 -1
- package/dist/providers/video-conferencing/teams.d.ts.map +1 -1
- package/dist/providers/video-conferencing/teams.js +9 -7
- package/dist/providers/video-conferencing/teams.js.map +1 -1
- package/dist/providers/video-conferencing/zoom.d.ts.map +1 -1
- package/dist/providers/video-conferencing/zoom.js +26 -24
- package/dist/providers/video-conferencing/zoom.js.map +1 -1
- package/dist/tools/data.d.ts.map +1 -1
- package/dist/tools/data.js +5 -12
- package/dist/tools/data.js.map +1 -1
- package/dist/tools/index.d.ts +1 -0
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +1 -0
- package/dist/tools/index.js.map +1 -1
- package/dist/tools/system.d.ts +289 -0
- package/dist/tools/system.d.ts.map +1 -0
- package/dist/tools/system.js +752 -0
- package/dist/tools/system.js.map +1 -0
- package/dist/tools/web.d.ts.map +1 -1
- package/dist/tools/web.js +22 -10
- package/dist/tools/web.js.map +1 -1
- package/dist/track-record.d.ts +101 -0
- package/dist/track-record.d.ts.map +1 -0
- package/dist/track-record.js +17 -0
- package/dist/track-record.js.map +1 -0
- package/dist/types.d.ts +210 -9
- package/dist/types.d.ts.map +1 -1
- package/dist/verb-registration.d.ts +122 -0
- package/dist/verb-registration.d.ts.map +1 -0
- package/dist/verb-registration.js +176 -0
- package/dist/verb-registration.js.map +1 -0
- package/dist/worker.d.ts +93 -0
- package/dist/worker.d.ts.map +1 -0
- package/dist/worker.js +315 -0
- package/dist/worker.js.map +1 -0
- package/dist/wrap.d.ts +89 -0
- package/dist/wrap.d.ts.map +1 -0
- package/dist/wrap.js +225 -0
- package/dist/wrap.js.map +1 -0
- package/package.json +31 -14
- package/src/client.ts +136 -0
- package/src/define.ts +30 -24
- package/src/function-ref.ts +264 -0
- package/src/function-sugar.ts +134 -0
- package/src/index.ts +132 -10
- package/src/providers/analytics/mixpanel.ts +19 -18
- package/src/providers/calendar/cal-com.ts +29 -18
- package/src/providers/calendar/google-calendar.ts +20 -14
- package/src/providers/crm/hubspot.ts +225 -99
- package/src/providers/development/github.ts +206 -135
- package/src/providers/ecommerce/shopify.ts +250 -89
- package/src/providers/email/resend.ts +101 -28
- package/src/providers/email/sendgrid.ts +12 -9
- package/src/providers/finance/stripe.ts +128 -49
- package/src/providers/forms/typeform.ts +74 -58
- package/src/providers/knowledge/notion.ts +340 -88
- package/src/providers/marketing/mailchimp.ts +86 -70
- package/src/providers/media/cloudinary.ts +99 -41
- package/src/providers/messaging/slack.ts +283 -85
- package/src/providers/messaging/twilio-sms.ts +35 -15
- package/src/providers/project-management/linear.ts +143 -55
- package/src/providers/spreadsheet/google-sheets.ts +222 -56
- package/src/providers/spreadsheet/xlsx.ts +47 -16
- package/src/providers/storage/s3.ts +119 -47
- package/src/providers/support/zendesk.ts +196 -46
- package/src/providers/tasks/todoist.ts +20 -26
- package/src/providers/video-conferencing/google-meet.ts +17 -20
- package/src/providers/video-conferencing/jitsi.ts +14 -14
- package/src/providers/video-conferencing/teams.ts +14 -13
- package/src/providers/video-conferencing/zoom.ts +54 -49
- package/src/tools/data.ts +6 -16
- package/src/tools/index.ts +1 -0
- package/src/tools/system.ts +887 -0
- package/src/tools/web.ts +22 -10
- package/src/track-record.ts +106 -0
- package/src/types.ts +241 -13
- package/src/verb-registration.ts +197 -0
- package/src/worker.ts +370 -0
- package/src/wrap.ts +260 -0
- package/test/client.test.ts +146 -0
- package/test/communication-tools-extended.test.ts +734 -0
- package/test/data-tools-extended.test.ts +743 -0
- package/test/define-extended.test.ts +819 -0
- package/test/define.test.ts +150 -41
- package/test/entities.test.ts +623 -0
- package/test/extended-entities.test.ts +1228 -0
- package/test/provider-implementations.test.ts +725 -0
- package/test/provider-registry-extended.test.ts +583 -0
- package/test/providers/google-sheets.test.ts +851 -0
- package/test/providers/helpers.ts +554 -0
- package/test/providers/hubspot.test.ts +576 -0
- package/test/providers/slack.test.ts +932 -0
- package/test/providers/stripe.test.ts +701 -0
- package/test/providers.test.ts +578 -0
- package/test/system-tools-extended.test.ts +632 -0
- package/test/system.test.ts +673 -0
- package/test/tools.test.ts +15 -11
- package/test/types.test.ts +402 -0
- package/test/verb-registration.test.ts +395 -0
- package/test/web-tools.test.ts +553 -0
- package/test/worker-extended.test.ts +699 -0
- package/test/worker.test.ts +576 -0
- package/test/wrap.test.ts +366 -0
- package/tsconfig.json +3 -13
- package/vitest.config.ts +37 -0
- package/wrangler.jsonc +9 -0
- package/LICENSE +0 -21
- package/dist/providers/voice/vapi.d.ts +0 -27
- package/dist/providers/voice/vapi.d.ts.map +0 -1
- package/dist/providers/voice/vapi.js +0 -440
- package/dist/providers/voice/vapi.js.map +0 -1
- package/src/define.js +0 -259
- package/src/entities/advertising.js +0 -999
- package/src/entities/ai.js +0 -756
- package/src/entities/analytics.js +0 -1588
- package/src/entities/automation.js +0 -601
- package/src/entities/communication.js +0 -1150
- package/src/entities/crm.js +0 -1386
- package/src/entities/design.js +0 -546
- package/src/entities/development.js +0 -2212
- package/src/entities/document.js +0 -874
- package/src/entities/ecommerce.js +0 -1429
- package/src/entities/experiment.js +0 -1039
- package/src/entities/finance.js +0 -3478
- package/src/entities/forms.js +0 -1892
- package/src/entities/hr.js +0 -661
- package/src/entities/identity.js +0 -997
- package/src/entities/index.js +0 -282
- package/src/entities/infrastructure.js +0 -1153
- package/src/entities/knowledge.js +0 -1438
- package/src/entities/marketing.js +0 -1610
- package/src/entities/media.js +0 -1634
- package/src/entities/notification.js +0 -1199
- package/src/entities/presentation.js +0 -1274
- package/src/entities/productivity.js +0 -1317
- package/src/entities/project-management.js +0 -1136
- package/src/entities/recruiting.js +0 -736
- package/src/entities/shipping.js +0 -509
- package/src/entities/signature.js +0 -1102
- package/src/entities/site.js +0 -222
- package/src/entities/spreadsheet.js +0 -1341
- package/src/entities/storage.js +0 -1198
- package/src/entities/support.js +0 -1166
- package/src/entities/video-conferencing.js +0 -1750
- package/src/entities/video.js +0 -950
- package/src/entities.js +0 -1663
- package/src/index.js +0 -74
- package/src/providers/analytics/index.js +0 -17
- package/src/providers/analytics/mixpanel.js +0 -255
- package/src/providers/calendar/cal-com.js +0 -303
- package/src/providers/calendar/google-calendar.js +0 -335
- package/src/providers/calendar/index.js +0 -20
- package/src/providers/crm/hubspot.js +0 -566
- package/src/providers/crm/index.js +0 -17
- package/src/providers/development/github.js +0 -472
- package/src/providers/development/index.js +0 -17
- package/src/providers/ecommerce/index.js +0 -17
- package/src/providers/ecommerce/shopify.js +0 -378
- package/src/providers/email/index.js +0 -20
- package/src/providers/email/resend.js +0 -258
- package/src/providers/email/sendgrid.js +0 -161
- package/src/providers/finance/index.js +0 -17
- package/src/providers/finance/stripe.js +0 -549
- package/src/providers/forms/index.js +0 -17
- package/src/providers/forms/typeform.js +0 -500
- package/src/providers/index.js +0 -123
- package/src/providers/knowledge/index.js +0 -17
- package/src/providers/knowledge/notion.js +0 -389
- package/src/providers/marketing/index.js +0 -17
- package/src/providers/marketing/mailchimp.js +0 -443
- package/src/providers/media/cloudinary.js +0 -318
- package/src/providers/media/index.js +0 -17
- package/src/providers/messaging/index.js +0 -20
- package/src/providers/messaging/slack.js +0 -393
- package/src/providers/messaging/twilio-sms.js +0 -249
- package/src/providers/project-management/index.js +0 -17
- package/src/providers/project-management/linear.js +0 -575
- package/src/providers/registry.js +0 -86
- package/src/providers/spreadsheet/google-sheets.js +0 -375
- package/src/providers/spreadsheet/index.js +0 -20
- package/src/providers/spreadsheet/xlsx.js +0 -423
- package/src/providers/storage/index.js +0 -24
- package/src/providers/storage/s3.js +0 -419
- package/src/providers/support/index.js +0 -17
- package/src/providers/support/zendesk.js +0 -373
- package/src/providers/tasks/index.js +0 -17
- package/src/providers/tasks/todoist.js +0 -286
- package/src/providers/types.js +0 -9
- package/src/providers/video-conferencing/google-meet.js +0 -286
- package/src/providers/video-conferencing/index.js +0 -31
- package/src/providers/video-conferencing/jitsi.js +0 -254
- package/src/providers/video-conferencing/teams.js +0 -270
- package/src/providers/video-conferencing/zoom.js +0 -332
- package/src/registry.js +0 -128
- package/src/tools/communication.js +0 -184
- package/src/tools/data.js +0 -205
- package/src/tools/index.js +0 -11
- package/src/tools/web.js +0 -137
- package/src/types.js +0 -10
- package/test/define.test.js +0 -306
- package/test/registry.test.js +0 -357
- package/test/tools.test.js +0 -363
|
@@ -48,10 +48,7 @@ export function createMailchimpProvider(config: ProviderConfig): MarketingProvid
|
|
|
48
48
|
/**
|
|
49
49
|
* Make authenticated API request
|
|
50
50
|
*/
|
|
51
|
-
async function makeRequest<T>(
|
|
52
|
-
endpoint: string,
|
|
53
|
-
options: RequestInit = {}
|
|
54
|
-
): Promise<T> {
|
|
51
|
+
async function makeRequest<T>(endpoint: string, options: RequestInit = {}): Promise<T> {
|
|
55
52
|
const url = `${baseUrl}${endpoint}`
|
|
56
53
|
const response = await fetch(url, {
|
|
57
54
|
...options,
|
|
@@ -100,8 +97,8 @@ export function createMailchimpProvider(config: ProviderConfig): MarketingProvid
|
|
|
100
97
|
info: mailchimpInfo,
|
|
101
98
|
|
|
102
99
|
async initialize(cfg: ProviderConfig): Promise<void> {
|
|
103
|
-
apiKey = cfg
|
|
104
|
-
serverPrefix = cfg
|
|
100
|
+
apiKey = cfg['apiKey'] as string
|
|
101
|
+
serverPrefix = cfg['serverPrefix'] as string
|
|
105
102
|
|
|
106
103
|
if (!apiKey) {
|
|
107
104
|
throw new Error('Mailchimp API key is required')
|
|
@@ -190,17 +187,17 @@ export function createMailchimpProvider(config: ProviderConfig): MarketingProvid
|
|
|
190
187
|
}
|
|
191
188
|
|
|
192
189
|
if (subscriber.firstName || subscriber.lastName) {
|
|
193
|
-
body
|
|
190
|
+
body['merge_fields'] = {
|
|
194
191
|
...(subscriber.firstName && { FNAME: subscriber.firstName }),
|
|
195
192
|
...(subscriber.lastName && { LNAME: subscriber.lastName }),
|
|
196
193
|
...subscriber.mergeFields,
|
|
197
194
|
}
|
|
198
195
|
} else if (subscriber.mergeFields) {
|
|
199
|
-
body
|
|
196
|
+
body['merge_fields'] = subscriber.mergeFields
|
|
200
197
|
}
|
|
201
198
|
|
|
202
199
|
if (subscriber.tags?.length) {
|
|
203
|
-
body
|
|
200
|
+
body['tags'] = subscriber.tags
|
|
204
201
|
}
|
|
205
202
|
|
|
206
203
|
const response = await makeRequest<{
|
|
@@ -216,18 +213,24 @@ export function createMailchimpProvider(config: ProviderConfig): MarketingProvid
|
|
|
216
213
|
body: JSON.stringify(body),
|
|
217
214
|
})
|
|
218
215
|
|
|
216
|
+
const subscribedAt = response.timestamp_signup
|
|
217
|
+
? new Date(response.timestamp_signup)
|
|
218
|
+
: response.timestamp_opt
|
|
219
|
+
? new Date(response.timestamp_opt)
|
|
220
|
+
: undefined
|
|
221
|
+
|
|
219
222
|
return {
|
|
220
223
|
id: response.id,
|
|
221
224
|
email: response.email_address,
|
|
222
|
-
firstName: response.merge_fields?.FNAME,
|
|
223
|
-
lastName: response.merge_fields?.LNAME,
|
|
224
225
|
status: mapStatus(response.status),
|
|
225
226
|
tags: response.tags.map((t) => t.name),
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
227
|
+
...(response.merge_fields?.FNAME !== undefined && {
|
|
228
|
+
firstName: response.merge_fields.FNAME,
|
|
229
|
+
}),
|
|
230
|
+
...(response.merge_fields?.LNAME !== undefined && {
|
|
231
|
+
lastName: response.merge_fields.LNAME,
|
|
232
|
+
}),
|
|
233
|
+
...(subscribedAt !== undefined && { subscribedAt }),
|
|
231
234
|
}
|
|
232
235
|
},
|
|
233
236
|
|
|
@@ -238,23 +241,20 @@ export function createMailchimpProvider(config: ProviderConfig): MarketingProvid
|
|
|
238
241
|
): Promise<SubscriberData> {
|
|
239
242
|
// Mailchimp uses MD5 hash of lowercase email as subscriber ID
|
|
240
243
|
const crypto = await import('crypto')
|
|
241
|
-
const subscriberId = crypto
|
|
242
|
-
.createHash('md5')
|
|
243
|
-
.update(email.toLowerCase())
|
|
244
|
-
.digest('hex')
|
|
244
|
+
const subscriberId = crypto.createHash('md5').update(email.toLowerCase()).digest('hex')
|
|
245
245
|
|
|
246
246
|
const body: Record<string, unknown> = {}
|
|
247
247
|
|
|
248
248
|
if (updates.email) {
|
|
249
|
-
body
|
|
249
|
+
body['email_address'] = updates.email
|
|
250
250
|
}
|
|
251
251
|
|
|
252
252
|
if (updates.status) {
|
|
253
|
-
body
|
|
253
|
+
body['status'] = updates.status
|
|
254
254
|
}
|
|
255
255
|
|
|
256
256
|
if (updates.firstName || updates.lastName || updates.mergeFields) {
|
|
257
|
-
body
|
|
257
|
+
body['merge_fields'] = {
|
|
258
258
|
...(updates.firstName && { FNAME: updates.firstName }),
|
|
259
259
|
...(updates.lastName && { LNAME: updates.lastName }),
|
|
260
260
|
...updates.mergeFields,
|
|
@@ -262,7 +262,7 @@ export function createMailchimpProvider(config: ProviderConfig): MarketingProvid
|
|
|
262
262
|
}
|
|
263
263
|
|
|
264
264
|
if (updates.tags?.length) {
|
|
265
|
-
body
|
|
265
|
+
body['tags'] = updates.tags
|
|
266
266
|
}
|
|
267
267
|
|
|
268
268
|
const response = await makeRequest<{
|
|
@@ -278,28 +278,31 @@ export function createMailchimpProvider(config: ProviderConfig): MarketingProvid
|
|
|
278
278
|
body: JSON.stringify(body),
|
|
279
279
|
})
|
|
280
280
|
|
|
281
|
+
const updateSubscribedAt = response.timestamp_signup
|
|
282
|
+
? new Date(response.timestamp_signup)
|
|
283
|
+
: response.timestamp_opt
|
|
284
|
+
? new Date(response.timestamp_opt)
|
|
285
|
+
: undefined
|
|
286
|
+
|
|
281
287
|
return {
|
|
282
288
|
id: response.id,
|
|
283
289
|
email: response.email_address,
|
|
284
|
-
firstName: response.merge_fields?.FNAME,
|
|
285
|
-
lastName: response.merge_fields?.LNAME,
|
|
286
290
|
status: mapStatus(response.status),
|
|
287
291
|
tags: response.tags.map((t) => t.name),
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
292
|
+
...(response.merge_fields?.FNAME !== undefined && {
|
|
293
|
+
firstName: response.merge_fields.FNAME,
|
|
294
|
+
}),
|
|
295
|
+
...(response.merge_fields?.LNAME !== undefined && {
|
|
296
|
+
lastName: response.merge_fields.LNAME,
|
|
297
|
+
}),
|
|
298
|
+
...(updateSubscribedAt !== undefined && { subscribedAt: updateSubscribedAt }),
|
|
293
299
|
}
|
|
294
300
|
},
|
|
295
301
|
|
|
296
302
|
async removeSubscriber(audienceId: string, email: string): Promise<boolean> {
|
|
297
303
|
try {
|
|
298
304
|
const crypto = await import('crypto')
|
|
299
|
-
const subscriberId = crypto
|
|
300
|
-
.createHash('md5')
|
|
301
|
-
.update(email.toLowerCase())
|
|
302
|
-
.digest('hex')
|
|
305
|
+
const subscriberId = crypto.createHash('md5').update(email.toLowerCase()).digest('hex')
|
|
303
306
|
|
|
304
307
|
await makeRequest(`/lists/${audienceId}/members/${subscriberId}`, {
|
|
305
308
|
method: 'DELETE',
|
|
@@ -343,19 +346,23 @@ export function createMailchimpProvider(config: ProviderConfig): MarketingProvid
|
|
|
343
346
|
total_items: number
|
|
344
347
|
}>(`/lists/${audienceId}/members?${params}`)
|
|
345
348
|
|
|
346
|
-
const items = response.members.map((member) =>
|
|
347
|
-
|
|
348
|
-
email: member.email_address,
|
|
349
|
-
firstName: member.merge_fields?.FNAME,
|
|
350
|
-
lastName: member.merge_fields?.LNAME,
|
|
351
|
-
status: mapStatus(member.status),
|
|
352
|
-
tags: member.tags.map((t) => t.name),
|
|
353
|
-
subscribedAt: member.timestamp_signup
|
|
349
|
+
const items = response.members.map((member) => {
|
|
350
|
+
const memberSubscribedAt = member.timestamp_signup
|
|
354
351
|
? new Date(member.timestamp_signup)
|
|
355
352
|
: member.timestamp_opt
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
353
|
+
? new Date(member.timestamp_opt)
|
|
354
|
+
: undefined
|
|
355
|
+
|
|
356
|
+
return {
|
|
357
|
+
id: member.id,
|
|
358
|
+
email: member.email_address,
|
|
359
|
+
status: mapStatus(member.status),
|
|
360
|
+
tags: member.tags.map((t) => t.name),
|
|
361
|
+
...(member.merge_fields?.FNAME !== undefined && { firstName: member.merge_fields.FNAME }),
|
|
362
|
+
...(member.merge_fields?.LNAME !== undefined && { lastName: member.merge_fields.LNAME }),
|
|
363
|
+
...(memberSubscribedAt !== undefined && { subscribedAt: memberSubscribedAt }),
|
|
364
|
+
}
|
|
365
|
+
})
|
|
359
366
|
|
|
360
367
|
const offset = options?.offset || 0
|
|
361
368
|
const limit = options?.limit || 10
|
|
@@ -403,10 +410,10 @@ export function createMailchimpProvider(config: ProviderConfig): MarketingProvid
|
|
|
403
410
|
if (campaign.content?.html || campaign.content?.text) {
|
|
404
411
|
const contentBody: Record<string, unknown> = {}
|
|
405
412
|
if (campaign.content.html) {
|
|
406
|
-
contentBody
|
|
413
|
+
contentBody['html'] = campaign.content.html
|
|
407
414
|
}
|
|
408
415
|
if (campaign.content.text) {
|
|
409
|
-
contentBody
|
|
416
|
+
contentBody['plain_text'] = campaign.content.text
|
|
410
417
|
}
|
|
411
418
|
|
|
412
419
|
await makeRequest(`/campaigns/${response.id}/content`, {
|
|
@@ -415,6 +422,8 @@ export function createMailchimpProvider(config: ProviderConfig): MarketingProvid
|
|
|
415
422
|
})
|
|
416
423
|
}
|
|
417
424
|
|
|
425
|
+
const createSentAt = response.send_time ? new Date(response.send_time) : undefined
|
|
426
|
+
|
|
418
427
|
return {
|
|
419
428
|
id: response.id,
|
|
420
429
|
name: response.settings.title,
|
|
@@ -423,8 +432,8 @@ export function createMailchimpProvider(config: ProviderConfig): MarketingProvid
|
|
|
423
432
|
subject: response.settings.subject_line,
|
|
424
433
|
fromName: response.settings.from_name,
|
|
425
434
|
fromEmail: response.settings.reply_to,
|
|
426
|
-
sentAt: response.send_time ? new Date(response.send_time) : undefined,
|
|
427
435
|
createdAt: new Date(response.create_time),
|
|
436
|
+
...(createSentAt !== undefined && { sentAt: createSentAt }),
|
|
428
437
|
}
|
|
429
438
|
},
|
|
430
439
|
|
|
@@ -445,6 +454,8 @@ export function createMailchimpProvider(config: ProviderConfig): MarketingProvid
|
|
|
445
454
|
send_time?: string
|
|
446
455
|
}>(`/campaigns/${campaignId}`)
|
|
447
456
|
|
|
457
|
+
const getSentAt = response.send_time ? new Date(response.send_time) : undefined
|
|
458
|
+
|
|
448
459
|
return {
|
|
449
460
|
id: response.id,
|
|
450
461
|
name: response.settings.title,
|
|
@@ -453,8 +464,8 @@ export function createMailchimpProvider(config: ProviderConfig): MarketingProvid
|
|
|
453
464
|
subject: response.settings.subject_line,
|
|
454
465
|
fromName: response.settings.from_name,
|
|
455
466
|
fromEmail: response.settings.reply_to,
|
|
456
|
-
sentAt: response.send_time ? new Date(response.send_time) : undefined,
|
|
457
467
|
createdAt: new Date(response.create_time),
|
|
468
|
+
...(getSentAt !== undefined && { sentAt: getSentAt }),
|
|
458
469
|
}
|
|
459
470
|
} catch (error) {
|
|
460
471
|
if (error instanceof Error && error.message.includes('404')) {
|
|
@@ -471,7 +482,7 @@ export function createMailchimpProvider(config: ProviderConfig): MarketingProvid
|
|
|
471
482
|
const body: Record<string, unknown> = {}
|
|
472
483
|
|
|
473
484
|
if (updates.name || updates.subject || updates.fromName || updates.fromEmail) {
|
|
474
|
-
body
|
|
485
|
+
body['settings'] = {
|
|
475
486
|
...(updates.name && { title: updates.name }),
|
|
476
487
|
...(updates.subject && { subject_line: updates.subject }),
|
|
477
488
|
...(updates.fromName && { from_name: updates.fromName }),
|
|
@@ -480,7 +491,7 @@ export function createMailchimpProvider(config: ProviderConfig): MarketingProvid
|
|
|
480
491
|
}
|
|
481
492
|
|
|
482
493
|
if (updates.audienceId) {
|
|
483
|
-
body
|
|
494
|
+
body['recipients'] = { list_id: updates.audienceId }
|
|
484
495
|
}
|
|
485
496
|
|
|
486
497
|
const response = await makeRequest<{
|
|
@@ -505,10 +516,10 @@ export function createMailchimpProvider(config: ProviderConfig): MarketingProvid
|
|
|
505
516
|
if (updates.content?.html || updates.content?.text) {
|
|
506
517
|
const contentBody: Record<string, unknown> = {}
|
|
507
518
|
if (updates.content.html) {
|
|
508
|
-
contentBody
|
|
519
|
+
contentBody['html'] = updates.content.html
|
|
509
520
|
}
|
|
510
521
|
if (updates.content.text) {
|
|
511
|
-
contentBody
|
|
522
|
+
contentBody['plain_text'] = updates.content.text
|
|
512
523
|
}
|
|
513
524
|
|
|
514
525
|
await makeRequest(`/campaigns/${response.id}/content`, {
|
|
@@ -517,6 +528,8 @@ export function createMailchimpProvider(config: ProviderConfig): MarketingProvid
|
|
|
517
528
|
})
|
|
518
529
|
}
|
|
519
530
|
|
|
531
|
+
const updateSentAt = response.send_time ? new Date(response.send_time) : undefined
|
|
532
|
+
|
|
520
533
|
return {
|
|
521
534
|
id: response.id,
|
|
522
535
|
name: response.settings.title,
|
|
@@ -525,14 +538,12 @@ export function createMailchimpProvider(config: ProviderConfig): MarketingProvid
|
|
|
525
538
|
subject: response.settings.subject_line,
|
|
526
539
|
fromName: response.settings.from_name,
|
|
527
540
|
fromEmail: response.settings.reply_to,
|
|
528
|
-
sentAt: response.send_time ? new Date(response.send_time) : undefined,
|
|
529
541
|
createdAt: new Date(response.create_time),
|
|
542
|
+
...(updateSentAt !== undefined && { sentAt: updateSentAt }),
|
|
530
543
|
}
|
|
531
544
|
},
|
|
532
545
|
|
|
533
|
-
async listCampaigns(
|
|
534
|
-
options?: CampaignListOptions
|
|
535
|
-
): Promise<PaginatedResult<CampaignData>> {
|
|
546
|
+
async listCampaigns(options?: CampaignListOptions): Promise<PaginatedResult<CampaignData>> {
|
|
536
547
|
const params = new URLSearchParams()
|
|
537
548
|
params.set('count', String(options?.limit || 10))
|
|
538
549
|
params.set('offset', String(options?.offset || 0))
|
|
@@ -563,17 +574,21 @@ export function createMailchimpProvider(config: ProviderConfig): MarketingProvid
|
|
|
563
574
|
total_items: number
|
|
564
575
|
}>(`/campaigns?${params}`)
|
|
565
576
|
|
|
566
|
-
const items = response.campaigns.map((campaign) =>
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
+
const items = response.campaigns.map((campaign) => {
|
|
578
|
+
const campaignSentAt = campaign.send_time ? new Date(campaign.send_time) : undefined
|
|
579
|
+
|
|
580
|
+
return {
|
|
581
|
+
id: campaign.id,
|
|
582
|
+
name: campaign.settings.title,
|
|
583
|
+
status: campaign.status as 'draft' | 'scheduled' | 'sending' | 'sent',
|
|
584
|
+
audienceId: campaign.recipients.list_id,
|
|
585
|
+
subject: campaign.settings.subject_line,
|
|
586
|
+
fromName: campaign.settings.from_name,
|
|
587
|
+
fromEmail: campaign.settings.reply_to,
|
|
588
|
+
createdAt: new Date(campaign.create_time),
|
|
589
|
+
...(campaignSentAt !== undefined && { sentAt: campaignSentAt }),
|
|
590
|
+
}
|
|
591
|
+
})
|
|
577
592
|
|
|
578
593
|
const offset = options?.offset || 0
|
|
579
594
|
const limit = options?.limit || 10
|
|
@@ -634,7 +649,8 @@ export function createMailchimpProvider(config: ProviderConfig): MarketingProvid
|
|
|
634
649
|
return {
|
|
635
650
|
campaignId: response.campaign_id,
|
|
636
651
|
sent: response.emails_sent,
|
|
637
|
-
delivered:
|
|
652
|
+
delivered:
|
|
653
|
+
response.emails_sent - (response.bounces.hard_bounces + response.bounces.soft_bounces),
|
|
638
654
|
opens: response.opens.opens_total,
|
|
639
655
|
uniqueOpens: response.opens.unique_opens,
|
|
640
656
|
clicks: response.clicks.clicks_total,
|
|
@@ -22,6 +22,56 @@ import { defineProvider } from '../registry.js'
|
|
|
22
22
|
|
|
23
23
|
const CLOUDINARY_API_VERSION = 'v1_1'
|
|
24
24
|
|
|
25
|
+
// =============================================================================
|
|
26
|
+
// Cloudinary API Response Types
|
|
27
|
+
// =============================================================================
|
|
28
|
+
|
|
29
|
+
/** Cloudinary error response */
|
|
30
|
+
interface CloudinaryErrorResponse {
|
|
31
|
+
error?: {
|
|
32
|
+
message?: string
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/** Cloudinary upload response */
|
|
37
|
+
interface CloudinaryUploadResponse {
|
|
38
|
+
public_id: string
|
|
39
|
+
url: string
|
|
40
|
+
secure_url: string
|
|
41
|
+
resource_type: string
|
|
42
|
+
format: string
|
|
43
|
+
bytes: number
|
|
44
|
+
width?: number
|
|
45
|
+
height?: number
|
|
46
|
+
duration?: number
|
|
47
|
+
created_at: string
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/** Cloudinary resource from API */
|
|
51
|
+
interface CloudinaryResource {
|
|
52
|
+
public_id: string
|
|
53
|
+
url: string
|
|
54
|
+
secure_url: string
|
|
55
|
+
resource_type: string
|
|
56
|
+
format: string
|
|
57
|
+
bytes: number
|
|
58
|
+
width?: number
|
|
59
|
+
height?: number
|
|
60
|
+
duration?: number
|
|
61
|
+
created_at: string
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/** Cloudinary resources list response */
|
|
65
|
+
interface CloudinaryResourcesResponse {
|
|
66
|
+
resources?: CloudinaryResource[]
|
|
67
|
+
next_cursor?: string
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/** Cloudinary delete response */
|
|
71
|
+
interface CloudinaryDeleteResponse {
|
|
72
|
+
deleted?: Record<string, string>
|
|
73
|
+
}
|
|
74
|
+
|
|
25
75
|
/**
|
|
26
76
|
* Cloudinary provider info
|
|
27
77
|
*/
|
|
@@ -53,7 +103,11 @@ export function createCloudinaryProvider(config: ProviderConfig): MediaProvider
|
|
|
53
103
|
return 'Basic ' + Buffer.from(`${apiKey}:${apiSecret}`).toString('base64')
|
|
54
104
|
}
|
|
55
105
|
|
|
56
|
-
function buildTransformUrl(
|
|
106
|
+
function buildTransformUrl(
|
|
107
|
+
publicId: string,
|
|
108
|
+
resourceType: string,
|
|
109
|
+
transforms?: TransformOptions
|
|
110
|
+
): string {
|
|
57
111
|
const protocol = secure ? 'https' : 'http'
|
|
58
112
|
const baseUrl = `${protocol}://res.cloudinary.com/${cloudName}`
|
|
59
113
|
|
|
@@ -76,10 +130,10 @@ export function createCloudinaryProvider(config: ProviderConfig): MediaProvider
|
|
|
76
130
|
info: cloudinaryInfo,
|
|
77
131
|
|
|
78
132
|
async initialize(cfg: ProviderConfig): Promise<void> {
|
|
79
|
-
cloudName = cfg
|
|
80
|
-
apiKey = cfg
|
|
81
|
-
apiSecret = cfg
|
|
82
|
-
secure = cfg
|
|
133
|
+
cloudName = cfg['cloudName'] as string
|
|
134
|
+
apiKey = cfg['apiKey'] as string
|
|
135
|
+
apiSecret = cfg['apiSecret'] as string
|
|
136
|
+
secure = cfg['secure'] !== false
|
|
83
137
|
|
|
84
138
|
if (!cloudName || !apiKey || !apiSecret) {
|
|
85
139
|
throw new Error('Cloudinary requires cloudName, apiKey, and apiSecret')
|
|
@@ -125,7 +179,10 @@ export function createCloudinaryProvider(config: ProviderConfig): MediaProvider
|
|
|
125
179
|
formData.append('file', file)
|
|
126
180
|
} else {
|
|
127
181
|
// Buffer - convert to ArrayBuffer for Blob
|
|
128
|
-
const arrayBuffer = file.buffer.slice(
|
|
182
|
+
const arrayBuffer = file.buffer.slice(
|
|
183
|
+
file.byteOffset,
|
|
184
|
+
file.byteOffset + file.byteLength
|
|
185
|
+
) as ArrayBuffer
|
|
129
186
|
const blob = new Blob([arrayBuffer])
|
|
130
187
|
formData.append('file', blob)
|
|
131
188
|
}
|
|
@@ -140,7 +197,12 @@ export function createCloudinaryProvider(config: ProviderConfig): MediaProvider
|
|
|
140
197
|
formData.append('tags', options.tags.join(','))
|
|
141
198
|
}
|
|
142
199
|
if (options?.metadata) {
|
|
143
|
-
formData.append(
|
|
200
|
+
formData.append(
|
|
201
|
+
'context',
|
|
202
|
+
Object.entries(options.metadata)
|
|
203
|
+
.map(([k, v]) => `${k}=${v}`)
|
|
204
|
+
.join('|')
|
|
205
|
+
)
|
|
144
206
|
}
|
|
145
207
|
|
|
146
208
|
try {
|
|
@@ -153,29 +215,27 @@ export function createCloudinaryProvider(config: ProviderConfig): MediaProvider
|
|
|
153
215
|
})
|
|
154
216
|
|
|
155
217
|
if (!response.ok) {
|
|
156
|
-
const errorData = await response.json().catch(() => ({}))
|
|
157
|
-
throw new Error(
|
|
218
|
+
const errorData = (await response.json().catch(() => ({}))) as CloudinaryErrorResponse
|
|
219
|
+
throw new Error(errorData.error?.message || `Upload failed: HTTP ${response.status}`)
|
|
158
220
|
}
|
|
159
221
|
|
|
160
|
-
const data = await response.json() as
|
|
222
|
+
const data = (await response.json()) as CloudinaryUploadResponse
|
|
161
223
|
|
|
162
224
|
return {
|
|
163
225
|
id: data.public_id,
|
|
164
226
|
publicId: data.public_id,
|
|
165
227
|
url: data.url,
|
|
166
228
|
secureUrl: data.secure_url,
|
|
167
|
-
resourceType: data.resource_type,
|
|
229
|
+
resourceType: data.resource_type as 'image' | 'video' | 'raw',
|
|
168
230
|
format: data.format,
|
|
169
231
|
bytes: data.bytes,
|
|
170
|
-
width: data.width,
|
|
171
|
-
height: data.height,
|
|
172
|
-
duration: data.duration,
|
|
173
232
|
createdAt: new Date(data.created_at),
|
|
233
|
+
...(data.width !== undefined && { width: data.width }),
|
|
234
|
+
...(data.height !== undefined && { height: data.height }),
|
|
235
|
+
...(data.duration !== undefined && { duration: data.duration }),
|
|
174
236
|
}
|
|
175
237
|
} catch (error) {
|
|
176
|
-
throw new Error(
|
|
177
|
-
error instanceof Error ? error.message : 'Upload failed'
|
|
178
|
-
)
|
|
238
|
+
throw new Error(error instanceof Error ? error.message : 'Upload failed')
|
|
179
239
|
}
|
|
180
240
|
},
|
|
181
241
|
|
|
@@ -202,37 +262,37 @@ export function createCloudinaryProvider(config: ProviderConfig): MediaProvider
|
|
|
202
262
|
return null
|
|
203
263
|
}
|
|
204
264
|
|
|
205
|
-
const data = await videoResponse.json() as
|
|
265
|
+
const data = (await videoResponse.json()) as CloudinaryResource
|
|
206
266
|
return {
|
|
207
267
|
id: data.public_id,
|
|
208
268
|
publicId: data.public_id,
|
|
209
269
|
url: data.url,
|
|
210
270
|
secureUrl: data.secure_url,
|
|
211
|
-
resourceType: data.resource_type,
|
|
271
|
+
resourceType: data.resource_type as 'image' | 'video' | 'raw',
|
|
212
272
|
format: data.format,
|
|
213
273
|
bytes: data.bytes,
|
|
214
|
-
width: data.width,
|
|
215
|
-
height: data.height,
|
|
216
|
-
duration: data.duration,
|
|
217
274
|
createdAt: new Date(data.created_at),
|
|
275
|
+
...(data.width !== undefined && { width: data.width }),
|
|
276
|
+
...(data.height !== undefined && { height: data.height }),
|
|
277
|
+
...(data.duration !== undefined && { duration: data.duration }),
|
|
218
278
|
}
|
|
219
279
|
}
|
|
220
280
|
|
|
221
|
-
const data = await response.json() as
|
|
281
|
+
const data = (await response.json()) as CloudinaryResource
|
|
222
282
|
return {
|
|
223
283
|
id: data.public_id,
|
|
224
284
|
publicId: data.public_id,
|
|
225
285
|
url: data.url,
|
|
226
286
|
secureUrl: data.secure_url,
|
|
227
|
-
resourceType: data.resource_type,
|
|
287
|
+
resourceType: data.resource_type as 'image' | 'video' | 'raw',
|
|
228
288
|
format: data.format,
|
|
229
289
|
bytes: data.bytes,
|
|
230
|
-
width: data.width,
|
|
231
|
-
height: data.height,
|
|
232
|
-
duration: data.duration,
|
|
233
290
|
createdAt: new Date(data.created_at),
|
|
291
|
+
...(data.width !== undefined && { width: data.width }),
|
|
292
|
+
...(data.height !== undefined && { height: data.height }),
|
|
293
|
+
...(data.duration !== undefined && { duration: data.duration }),
|
|
234
294
|
}
|
|
235
|
-
} catch
|
|
295
|
+
} catch {
|
|
236
296
|
return null
|
|
237
297
|
}
|
|
238
298
|
},
|
|
@@ -250,7 +310,7 @@ export function createCloudinaryProvider(config: ProviderConfig): MediaProvider
|
|
|
250
310
|
})
|
|
251
311
|
|
|
252
312
|
if (response.ok) {
|
|
253
|
-
const result = await response.json() as
|
|
313
|
+
const result = (await response.json()) as CloudinaryDeleteResponse
|
|
254
314
|
return result.deleted?.[assetId] === 'deleted'
|
|
255
315
|
}
|
|
256
316
|
|
|
@@ -265,12 +325,12 @@ export function createCloudinaryProvider(config: ProviderConfig): MediaProvider
|
|
|
265
325
|
})
|
|
266
326
|
|
|
267
327
|
if (response.ok) {
|
|
268
|
-
const result = await response.json() as
|
|
328
|
+
const result = (await response.json()) as CloudinaryDeleteResponse
|
|
269
329
|
return result.deleted?.[assetId] === 'deleted'
|
|
270
330
|
}
|
|
271
331
|
|
|
272
332
|
return false
|
|
273
|
-
} catch
|
|
333
|
+
} catch {
|
|
274
334
|
return false
|
|
275
335
|
}
|
|
276
336
|
},
|
|
@@ -301,31 +361,29 @@ export function createCloudinaryProvider(config: ProviderConfig): MediaProvider
|
|
|
301
361
|
throw new Error(`List failed: HTTP ${response.status}`)
|
|
302
362
|
}
|
|
303
363
|
|
|
304
|
-
const data = await response.json() as
|
|
364
|
+
const data = (await response.json()) as CloudinaryResourcesResponse
|
|
305
365
|
|
|
306
|
-
const items: MediaAssetData[] = (data.resources || []).map((resource
|
|
366
|
+
const items: MediaAssetData[] = (data.resources || []).map((resource) => ({
|
|
307
367
|
id: resource.public_id,
|
|
308
368
|
publicId: resource.public_id,
|
|
309
369
|
url: resource.url,
|
|
310
370
|
secureUrl: resource.secure_url,
|
|
311
|
-
resourceType: resource.resource_type,
|
|
371
|
+
resourceType: resource.resource_type as 'image' | 'video' | 'raw',
|
|
312
372
|
format: resource.format,
|
|
313
373
|
bytes: resource.bytes,
|
|
314
|
-
width: resource.width,
|
|
315
|
-
height: resource.height,
|
|
316
|
-
duration: resource.duration,
|
|
317
374
|
createdAt: new Date(resource.created_at),
|
|
375
|
+
...(resource.width !== undefined && { width: resource.width }),
|
|
376
|
+
...(resource.height !== undefined && { height: resource.height }),
|
|
377
|
+
...(resource.duration !== undefined && { duration: resource.duration }),
|
|
318
378
|
}))
|
|
319
379
|
|
|
320
380
|
return {
|
|
321
381
|
items,
|
|
322
382
|
hasMore: !!data.next_cursor,
|
|
323
|
-
nextCursor: data.next_cursor,
|
|
383
|
+
...(data.next_cursor !== undefined && { nextCursor: data.next_cursor }),
|
|
324
384
|
}
|
|
325
385
|
} catch (error) {
|
|
326
|
-
throw new Error(
|
|
327
|
-
error instanceof Error ? error.message : 'List failed'
|
|
328
|
-
)
|
|
386
|
+
throw new Error(error instanceof Error ? error.message : 'List failed')
|
|
329
387
|
}
|
|
330
388
|
},
|
|
331
389
|
|