@maizzle/framework
Version:
Maizzle is a framework that helps you quickly build HTML emails with Tailwind CSS.
77 lines (76 loc) • 2.6 kB
JavaScript
import { parse } from "../utils/ast/parser.js";
import { serialize } from "../utils/ast/serializer.js";
import "../utils/ast/index.js";
import { isAbsoluteUrl } from "../utils/url.js";
import queryString from "query-string";
import { selectAll } from "css-select";
//#region src/transformers/urlQuery.ts
const DEFAULT_ATTRIBUTES = [
"src",
"href",
"poster",
"srcset",
"background"
];
const DEFAULT_TAGS = ["a"];
/**
* Append query parameters to a URL string using query-string.
*/
function appendParams(url, params, qsOptions, strict) {
if (strict && !isAbsoluteUrl(url)) return url;
return queryString.stringifyUrl({
url,
query: params
}, qsOptions);
}
/**
* Append query parameters to URLs found in matching attributes/elements.
*
* @param html HTML string to transform.
* @param params Query parameters to append (e.g. `{ utm_source: 'newsletter' }`).
* @param options Behaviour overrides — `tags` (CSS selectors, default `['a']`),
* `attributes` (default `['src', 'href', 'poster', 'srcset', 'background']`),
* `strict` (default `true`, only rewrites absolute URLs),
* `qs` (forwarded to `query-string`, default `{ encode: false }`).
* @returns The transformed HTML string.
*
* @example
* import { urlQuery } from '@maizzle/framework'
*
* const out = urlQuery(
* '<a href="https://example.com">x</a>',
* { utm_source: 'newsletter' },
* )
*
* // Restrict to specific tags / attributes:
* urlQuery(html, { ref: 'email' }, { tags: ['a', 'img'], attributes: ['href', 'src'] })
*/
function urlQuery(html, params = {}, options = {}) {
return serialize(urlQueryDom(parse(html), params, options));
}
/**
* DOM-form of {@link urlQuery} used by the internal transformer pipeline.
* Takes a parsed DOM, returns a parsed DOM — avoids redundant
* serialize/parse round-trips when chained with other transformers.
*/
function urlQueryDom(dom, params = {}, options = {}) {
if (!params || Object.keys(params).length === 0) return dom;
const tags = options.tags ?? DEFAULT_TAGS;
const attributes = options.attributes ?? DEFAULT_ATTRIBUTES;
const strict = options.strict ?? true;
const qsOptions = {
encode: false,
...options.qs ?? {}
};
const elements = selectAll(tags.join(", "), dom);
for (const el of elements) for (const attr of attributes) {
const value = el.attribs[attr];
if (!value) continue;
const updated = appendParams(value, params, qsOptions, strict);
if (updated !== value) el.attribs[attr] = updated;
}
return dom;
}
//#endregion
export { urlQuery, urlQueryDom };
//# sourceMappingURL=urlQuery.js.map