import jsonp from 'jsonp'
import { computed, MaybeRefOrGetter, toValue } from 'vue'
import flatten from 'lodash/flatten'
import castArray from 'lodash/castArray'
interface FormDataResult { result: string, msg: string }
/**
* Builds and submits a Mailchimp newsletter signup request via JSONP.
*
* @param email - Subscriber email address (plain value, ref, or getter).
* @param action - Mailchimp form action URL; required before `send` can succeed.
* @param emailField - Name of the Mailchimp merge field carrying the email.
* @param tracker - Mailchimp signup tracker value (the `SIGNUP` parameter).
* @param referrer - Explicit referrer to record; falls back to the parent/document referrer when omitted.
* @param defaultGroups - Mailchimp interest group names to opt into; comma-separated strings are split.
* @returns An object with a `send` function that resolves with the Mailchimp `FormDataResult`.
* @remarks Internal building block; not exported from the package root.
* @example
*
*/
export function useSendEmail(
email: MaybeRefOrGetter,
action?: string,
emailField?: string,
tracker?: string,
referrer?: string | null,
defaultGroups?: string[] | string
) {
const groups = computed(() => {
return flatten(castArray(defaultGroups).map(g => g.split(',')))
})
// Mailchimp's JSONP endpoint lives at /post-json and echoes the callback via the "c" param.
const urlFromAction = computed(() => {
return action?.replace('/post?', '/post-json?').concat('&c=?')
})
const parentReferrer = computed(() => {
if (referrer) {
return referrer
}
return window.location !== window.parent.location
? document.referrer
: document.location.href
})
const submitUrl = computed(() => {
if (typeof urlFromAction.value == 'undefined' || !tracker || !emailField) {
throw new Error('Missing url Info')
}
const emailValue = toValue(email)
const url = new URL(urlFromAction.value)
url.searchParams.set('SIGNUP', tracker)
url.searchParams.set('MMERGE24', parentReferrer.value)
url.searchParams.set(emailField, emailValue)
groups.value.map((group: string) => url.searchParams.set(group, '1'))
return url.href
})
function send(): Promise {
return new Promise((resolve, reject) => {
jsonp(
submitUrl.value,
{ param: 'c' },
(err: any, data: FormDataResult) => {
return err ? reject(err) : resolve(data)
}
)
})
}
return { send }
}