UNPKG

@maizzle/framework

Version:

Maizzle is a framework that helps you quickly build HTML emails with Tailwind CSS.

137 lines (122 loc) 3.83 kB
import get from 'lodash-es/get.js' import { defu as merge } from 'defu' // PostHTML import posthtml from 'posthtml' import posthtmlFetch from 'posthtml-fetch' import envTags from './plugins/envTags.js' import components from 'posthtml-component' import posthtmlPostcss from 'posthtml-postcss' import expandLinkTag from './plugins/expandLinkTag.js' import envAttributes from './plugins/envAttributes.js' import { getPosthtmlOptions } from './defaultConfig.js' // PostCSS import tailwindcss from 'tailwindcss' import postcssCalc from 'postcss-calc' import postcssImport from 'postcss-import' import cssVariables from 'postcss-css-variables' import postcssSafeParser from 'postcss-safe-parser' import postcssSortMediaQueries from 'postcss-sort-media-queries' import postcssColorFunctionalNotation from 'postcss-color-functional-notation' import defaultComponentsConfig from './defaultComponentsConfig.js' export async function process(html = '', config = {}) { /** * Configure PostCSS pipeline. Plugins defined and added here * will apply to all `<style>` tags in the HTML. */ const resolveCSSProps = get(config, 'css.resolveProps', true) const mediaConfig = get(config, 'css.media') const resolveCalc = get(config, 'css.resolveCalc') !== false ? get(config, 'css.resolveCalc', { precision: 2 }) // enabled by default, use default precision 2 : false const postcssPlugin = posthtmlPostcss( [ postcssImport(), tailwindcss(get(config, 'css.tailwind', {})), resolveCSSProps && cssVariables(resolveCSSProps), resolveCalc !== false && postcssCalc(resolveCalc), postcssColorFunctionalNotation(), mediaConfig && postcssSortMediaQueries(mediaConfig === true ? {} : mediaConfig), ...get(config, 'postcss.plugins', []), ], merge( get(config, 'postcss.options', {}), { from: config.cwd || './', parser: postcssSafeParser } ) ) /** * Define PostHTML options by merging user-provided ones * on top of a default configuration. */ const posthtmlOptions = getPosthtmlOptions(get(config, 'posthtml.options', {})) const componentsUserOptions = get(config, 'components', {}) const expressionsOptions = merge( get(config, 'expressions', get(config, 'posthtml.expressions', {})), get(componentsUserOptions, 'expressions', {}), ) const locals = merge( get(config, 'locals', {}), get(expressionsOptions, 'locals', {}), { page: config }, ) const fetchPlugin = posthtmlFetch( merge( { expressions: merge( { locals }, expressionsOptions, { missingLocal: '{local}', strictMode: false, }, ), }, get(config, 'fetch', {}) ) ) const componentsConfig = merge( { expressions: merge( { locals }, expressionsOptions, ) }, componentsUserOptions, defaultComponentsConfig ) // Ensure `fileExtension` is array and has no duplicates componentsConfig.fileExtension = Array.from(new Set( [].concat(componentsConfig.fileExtension) )) const beforePlugins = get(config, 'posthtml.plugins.before', []) return posthtml([ ...beforePlugins, envTags(config.env), envAttributes(config.env), expandLinkTag(), postcssPlugin, fetchPlugin, components(componentsConfig), expandLinkTag(), postcssPlugin, envTags(config.env), envAttributes(config.env), ...get( config, 'posthtml.plugins.after', beforePlugins.length > 0 ? [] : get(config, 'posthtml.plugins', []) ), ]) .process(html, posthtmlOptions) .then(result => ({ config: merge(config, { page: config }), html: result.html, })) .catch(error => { throw error }) }