@maizzle/framework
Version:
Maizzle is a framework that helps you quickly build HTML emails with Tailwind CSS.
617 lines (567 loc) • 12.8 kB
TypeScript
import type Events from './events';
import type BuildConfig from './build';
import type MinifyConfig from './minify';
import type PostHTMLConfig from './posthtml';
import type MarkdownConfig from './markdown';
import type { ProcessOptions } from 'postcss';
import type PurgeCSSConfig from './css/purge';
import type PlaintextConfig from './plaintext';
import type CSSInlineConfig from './css/inline';
import type { SpinnerName } from 'cli-spinners';
import type WidowWordsConfig from './widowWords';
import type { CoreBeautifyOptions } from 'js-beautify';
import type { BaseURLConfig } from 'posthtml-base-url';
import type URLParametersConfig from './urlParameters';
import type { PostCssCalcOptions } from 'postcss-calc';
import type { PostHTMLFetchConfig } from 'posthtml-fetch';
import type { Config as TailwindConfig } from 'tailwindcss';
import type { PostHTMLComponents } from 'posthtml-component';
import type { PostHTMLExpressions } from 'posthtml-expressions';
export default interface Config {
/**
* Add or remove attributes from elements.
*/
attributes?: {
/**
* Add attributes to specific elements.
*
* @default {}
*
* @example
* ```
* export default {
* attributes: {
* add: {
* table: {
* cellpadding: 0,
* cellspacing: 0,
* }
* }
* }
* }
* ```
*/
add?: Record<string, Record<string, string | number>>;
/**
* Remove attributes from elements.
*
* @default {}
*
* @example
* ```
* export default {
* attributes: {
* remove: [
* {
* name: 'width',
* value: '100', // or RegExp: /\d/
* },
* ], // or as array: ['width', 'height']
* }
* }
* ```
*/
remove?: Array<string | { name: string; value: string | RegExp }>;
}
/**
* Configure build settings.
*/
build?: BuildConfig;
/**
Define a string that will be prepended to sources and hrefs in your HTML and CSS.
@example
Prepend to all sources and hrefs:
```
export default {
baseURL: 'https://cdn.example.com/'
}
```
Prepend only to `src` attributes on image tags:
```
export default {
baseURL: {
url: 'https://cdn.example.com/',
tags: ['img'],
},
}
```
*/
baseURL?: string | BaseURLConfig;
/**
* Configure components.
*/
components?: PostHTMLComponents;
/**
* Configure how CSS is handled.
*/
css?: {
/**
* Configure CSS inlining.
*/
inline?: CSSInlineConfig;
/**
* Configure CSS purging.
*/
purge?: PurgeCSSConfig;
/**
* Resolve CSS `calc()` expressions to their static values.
*/
resolveCalc?: boolean | PostCssCalcOptions;
/**
* Resolve CSS custom properties to their static values.
*/
resolveProps?: boolean | {
/**
* Whether to preserve custom properties in the output.
*
* @default false
*/
preserve?: boolean | 'computed';
/**
* Define CSS variables that will be added to :root.
*
* @default {}
*/
variables?: {
[key: string]: string | {
/**
* The value of the CSS variable.
*/
value: string;
/**
* Whether the variable is !important.
*/
isImportant?: boolean;
};
};
/**
* Whether to preserve variables injected via JS with the `variables` option.
*
* @default true
*/
preserveInjectedVariables?: boolean;
/**
* Whether to preserve `@media` rules order.
*
* @default false
*/
preserveAtRulesOrder?: boolean;
};
/**
* Normalize escaped character class names like `\:` or `\/` by replacing them
* with email-safe alternatives.
*
* @example
* ```
* export default {
* css: {
* safe: {
* ':': '__',
* '!': 'i-',
* }
* }
* }
* ```
*/
safe?: boolean | Record<string, string>;
/**
* Rewrite longhand CSS inside style attributes with shorthand syntax.
* Only works with `margin`, `padding` and `border`, and only when
* all sides are specified.
*
* @default []
*
* @example
* ```
* export default {
* css: {
* shorthand: {
* tags: ['td', 'div'],
* } // or shorthand: true
* }
* }
* ```
*/
shorthand?: boolean | Record<string, string[]>;
/**
* Ensure that all your HEX colors inside `bgcolor` and `color` attributes are defined with six digits.
*
* @default true
*
* @example
* ```
* export default {
* css: {
* sixHex: false,
* }
* }
* ```
*/
sixHex?: boolean;
/**
* Use a custom Tailwind CSS configuration object.
*/
tailwind?: TailwindConfig;
}
/**
Configure [posthtml-expressions](https://github.com/posthtml/posthtml-expressions) options.
*/
expressions?: PostHTMLExpressions;
/**
* Configure the [`<fetch>`](https://maizzle.com/docs/tags#fetch) tag.
*/
fetch?: PostHTMLFetchConfig;
/**
* Transform text inside elements marked with custom attributes.
* Filters work only on elements that contain only text.
*
* @default {}
*
* @example
* ```
* export default {
* filters: {
* uppercase: str => str.toUpperCase(),
* }
* }
* ```
*/
filters?: boolean | Record<string, (str: string) => string>;
/**
* Define variables outside of the `page` object.
*
* @default {}
*
* @example
* ```
* export default {
* locals: {
* company: {
* name: 'Spacely Space Sprockets, Inc.'
* }
* }
* }
* ```
*
* `company` can then be used like this:
*
* ```
* <p>{{ company.name }}</p>
* ```
*/
locals?: Record<string, any>;
/**
* Configure the Markdown parser.
*
* @example
*
* ```
* export default {
* markdown: {
* root: './', // Path relative to which markdown files are imported
* encoding: 'utf8', // Encoding for imported Markdown files
* markdownit: {}, // Options passed to markdown-it
* plugins: [], // Plugins for markdown-it
* }
* }
* ```
*/
markdown?: MarkdownConfig;
/**
* Minify the compiled HTML email code.
*
* @default false
*
* @example
* ```
* export default {
* minify: true,
* }
* ```
*/
minify?: boolean | MinifyConfig;
/**
Configure the `posthtml-mso` plugin.
*/
outlook?: {
/**
The tag name to use for Outlook conditional comments.
@default 'outlook'
@example
```
export default {
outlook: {
tag: 'mso'
}
}
// You now write <mso>...</mso> instead of <outlook>...</outlook>
```
*/
tag?: string;
};
/**
* Configure plaintext generation.
*/
plaintext?: PlaintextConfig;
/**
* PostHTML configuration.
*/
posthtml?: PostHTMLConfig;
/**
* Configure PostCSS
*/
postcss?: {
/**
* Additional PostCSS plugins that you would like to use.
* @default []
* @example
* ```
* import examplePlugin from 'postcss-example-plugin'
* export default {
* postcss: {
* plugins: [
* examplePlugin()
* ]
* }
* }
* ```
*/
plugins?: Array<() => void>;
/**
* PostCSS options
* @default {}
* @example
* ```
* export default {
* postcss: {
* options: {
* map: true
* }
* }
* ```
*/
options?: ProcessOptions;
};
/**
* [Pretty print](https://maizzle.com/docs/transformers/prettify) your HTML email code
* so that it's nicely indented and more human-readable.
*
* @default undefined
*
* @example
* ```
* export default {
* prettify: true,
* }
* ```
*/
prettify?: boolean | CoreBeautifyOptions;
/**
* Batch-replace strings in your HTML.
*
* @default {}
*
* @example
* ```
* export default {
* replaceStrings: {
* 'replace this exact string': 'with this one',
* '\\s?data-src=""': '', // remove empty data-src="" attributes
* }
* }
* ```
*/
replaceStrings?: Record<string, string>;
/**
* Configure local server settings.
*/
server?: {
/**
* Port to run the local server on.
*
* @default 3000
*/
port?: number;
/**
* Enable HMR-like local development.
* When enabled, Maizzle will watch for changes in your templates
* and inject them into the browser without a full page reload.
*
* @default true
*/
hmr?: boolean;
/**
* Enable synchronized scrolling across browser tabs.
*
* @default false
*/
scrollSync?: boolean;
/**
* Paths to watch for changes.
* When a file in these paths changes, Maizzle will do a full rebuild.
*
* @default []
*/
watch?: string[];
/**
* Toggle reporting compiled file size in the console.
*
* @default false
*/
reportFileSize?: boolean;
/**
* Type of spinner to show in the console.
*
* @default 'circleHalves'
*
* @example
* ```
* export default {
* server: {
* spinner: 'bounce'
* }
* }
* ```
*/
spinner?: SpinnerName;
}
/**
Configure custom parameters to append to URLs.
@example
```
module.exports = {
urlParameters: {
_options: {
tags: ['a'],
qs: {}, // options for the `query-string` library
},
utm_source: 'maizzle',
utm_campaign: 'Campaign Name',
utm_medium: 'email',
custom_parameter: 'foo',
'1stOfApril': 'bar',
}
}
```
*/
urlParameters?: URLParametersConfig;
/**
* Enable or disable all Transformers.
*
* @default true
*
* @example
* ```
* export default {
* useTransformers: false,
* }
* ```
*/
useTransformers?: boolean;
/**
* Prevent widow words inside a tag by adding a ` ` between its last two words.
*
* @default
* {
* minWordCount: 3,
* attrName: 'prevent-widows'
* }
*
* @example
* ```
* export default {
* widowWords: {
* minWordCount: 5,
* },
* }
* ```
*/
widowWords?: WidowWordsConfig;
/**
* Runs after the Environment config has been computed, but before Templates are processed.
* Exposes the `config` object so you can further customize it.
*
* @default undefined
*
* @example
* ```
* export default {
* beforeCreate: async ({config}) => {
* // do something with `config`
* }
* }
* ```
*/
beforeCreate?: Events['beforeCreate'];
/**
* Runs after the Template's config has been computed, but just before it is compiled.
*
* Must return the `html` string, otherwise the original will be used.
*
* @default undefined
*
* @example
* ```
* export default {
* beforeRender: async ({html, matter, config, posthtml, transform}) => {
* // do something...
* return html;
* }
* }
* ```
*/
beforeRender?: Events['beforeRender'];
/**
* Runs after the Template has been compiled, but before any Transformers have been applied.
*
* Must return the `html` string, otherwise the original will be used.
*
* @default undefined
*
* @example
* ```
* export default {
* afterRender: async ({html, matter, config, posthtml, transform}) => {
* // do something...
* return html;
* }
* }
* ```
*/
afterRender?: Events['afterRender'];
/**
* Runs after all Transformers have been applied, just before the final HTML is returned.
*
* Must return the `html` string, otherwise the original will be used.
*
* @default undefined
*
* @example
* ```
* export default {
* afterTransformers: async ({html, matter, config, posthtml, transform}) => {
* // do something...
* return html;
* }
* }
* ```
*/
afterTransformers?: Events['afterTransformers'];
/**
* Runs after all Templates have been compiled and output to disk.
* `files` will contain the paths to all the files inside the `build.output.path` directory.
*
* @default undefined
*
* @example
* ```
* export default {
* afterBuild: async ({files, config, transform}) => {
* // do something...
* }
* }
* ```
*/
afterBuild?: Events['afterBuild'];
[key: string]: any;
}