@maizzle/framework 4.8.7 → 5.0.0-beta.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.
Files changed (80) hide show
  1. package/bin/maizzle +3 -1
  2. package/package.json +65 -58
  3. package/src/commands/build.js +244 -19
  4. package/src/commands/serve.js +2 -197
  5. package/src/generators/plaintext.js +192 -91
  6. package/src/generators/render.js +128 -0
  7. package/src/index.js +46 -14
  8. package/src/{generators/posthtml → posthtml}/defaultComponentsConfig.js +6 -4
  9. package/src/{generators/posthtml → posthtml}/defaultConfig.js +1 -1
  10. package/src/posthtml/index.js +74 -0
  11. package/src/posthtml/plugins/expandLinkTag.js +36 -0
  12. package/src/server/client.js +181 -0
  13. package/src/server/index.js +383 -0
  14. package/src/server/routes/hmr.js +24 -0
  15. package/src/server/routes/index.js +38 -0
  16. package/src/server/views/error.html +83 -0
  17. package/src/server/views/index.html +24 -0
  18. package/src/server/websockets.js +27 -0
  19. package/src/transformers/addAttributes.js +30 -0
  20. package/src/transformers/attributeToStyle.js +30 -36
  21. package/src/transformers/baseUrl.js +52 -23
  22. package/src/transformers/comb.js +51 -0
  23. package/src/transformers/core.js +20 -0
  24. package/src/transformers/filters/defaultFilters.js +90 -70
  25. package/src/transformers/filters/index.js +14 -78
  26. package/src/transformers/index.js +268 -63
  27. package/src/transformers/inline.js +240 -0
  28. package/src/transformers/markdown.js +13 -14
  29. package/src/transformers/minify.js +21 -16
  30. package/src/transformers/posthtmlMso.js +13 -8
  31. package/src/transformers/prettify.js +16 -15
  32. package/src/transformers/preventWidows.js +32 -26
  33. package/src/transformers/removeAttributes.js +17 -17
  34. package/src/transformers/replaceStrings.js +30 -9
  35. package/src/transformers/safeClassNames.js +24 -24
  36. package/src/transformers/shorthandCss.js +22 -0
  37. package/src/transformers/sixHex.js +15 -15
  38. package/src/transformers/urlParameters.js +18 -16
  39. package/src/transformers/useAttributeSizes.js +65 -0
  40. package/src/utils/getConfigByFilePath.js +124 -0
  41. package/src/utils/node.js +68 -0
  42. package/src/utils/string.js +117 -0
  43. package/types/build.d.ts +117 -57
  44. package/types/components.d.ts +130 -112
  45. package/types/config.d.ts +454 -242
  46. package/types/css/inline.d.ts +234 -0
  47. package/types/css/purge.d.ts +125 -0
  48. package/types/events.d.ts +5 -105
  49. package/types/index.d.ts +148 -116
  50. package/types/markdown.d.ts +20 -18
  51. package/types/minify.d.ts +122 -120
  52. package/types/plaintext.d.ts +46 -52
  53. package/types/posthtml.d.ts +103 -136
  54. package/types/render.d.ts +0 -117
  55. package/types/urlParameters.d.ts +21 -20
  56. package/types/widowWords.d.ts +9 -7
  57. package/src/functions/plaintext.js +0 -5
  58. package/src/functions/render.js +0 -5
  59. package/src/generators/config.js +0 -52
  60. package/src/generators/output/index.js +0 -4
  61. package/src/generators/output/to-disk.js +0 -254
  62. package/src/generators/output/to-string.js +0 -73
  63. package/src/generators/postcss.js +0 -23
  64. package/src/generators/posthtml/index.js +0 -75
  65. package/src/generators/tailwindcss.js +0 -157
  66. package/src/transformers/extraAttributes.js +0 -33
  67. package/src/transformers/inlineCss.js +0 -42
  68. package/src/transformers/removeInlineBackgroundColor.js +0 -56
  69. package/src/transformers/removeInlineSizes.js +0 -43
  70. package/src/transformers/removeInlinedSelectors.js +0 -100
  71. package/src/transformers/removeUnusedCss.js +0 -48
  72. package/src/transformers/shorthandInlineCSS.js +0 -26
  73. package/src/utils/helpers.js +0 -13
  74. package/types/baseUrl.d.ts +0 -79
  75. package/types/fetch.d.ts +0 -143
  76. package/types/inlineCss.d.ts +0 -207
  77. package/types/layouts.d.ts +0 -39
  78. package/types/removeUnusedCss.d.ts +0 -115
  79. package/types/tailwind.d.ts +0 -22
  80. package/types/templates.d.ts +0 -181
@@ -1,42 +0,0 @@
1
- const juice = require('juice')
2
- const {get, isObject, isEmpty} = require('lodash')
3
-
4
- module.exports = async (html, config = {}, direct = false) => {
5
- if (get(config, 'inlineCSS') === false) {
6
- return html
7
- }
8
-
9
- const options = direct ? config : get(config, 'inlineCSS', {})
10
- // Default `removeStyleTags` to false so we can preserve
11
- // CSS selectors that are not present in the HTML
12
- const removeStyleTags = get(options, 'removeStyleTags', false)
13
- const css = get(config, 'customCSS', false)
14
-
15
- if (get(config, 'inlineCSS') === true || !isEmpty(options)) {
16
- options.applyAttributesTableElements = true
17
- juice.styleToAttribute = get(options, 'styleToAttribute', {})
18
-
19
- juice.widthElements = get(options, 'applyWidthAttributes', []).map(i => i.toUpperCase())
20
- juice.heightElements = get(options, 'applyHeightAttributes', []).map(i => i.toUpperCase())
21
-
22
- juice.excludedProperties = ['--tw-shadow']
23
-
24
- if (!isEmpty(options.excludedProperties)) {
25
- juice.excludedProperties.push(...get(options, 'excludedProperties', []))
26
- }
27
-
28
- if (isObject(options.codeBlocks) && !isEmpty(options.codeBlocks)) {
29
- Object.entries(options.codeBlocks).forEach(([k, v]) => {
30
- juice.codeBlocks[k] = v
31
- })
32
- }
33
-
34
- html = css ?
35
- juice.inlineContent(html, css, {removeStyleTags, ...options}) :
36
- juice(html, {removeStyleTags, ...options})
37
-
38
- return html
39
- }
40
-
41
- return html
42
- }
@@ -1,56 +0,0 @@
1
- const posthtml = require('posthtml')
2
- const {get, merge, isEmpty} = require('lodash')
3
- const parseAttrs = require('posthtml-attrs-parser')
4
- const {toStyleString} = require('../utils/helpers')
5
- const defaultConfig = require('../generators/posthtml/defaultConfig')
6
-
7
- module.exports = async (html, config = {}, direct = false) => {
8
- const posthtmlOptions = merge(defaultConfig, get(config, 'build.posthtml.options', {}))
9
-
10
- if (isEmpty(config)) {
11
- return posthtml([removeInlineBGColor()]).process(html, posthtmlOptions).then(result => result.html)
12
- }
13
-
14
- if (get(config, 'inlineCSS.preferBgColorAttribute') === true) {
15
- return posthtml([removeInlineBGColor()]).process(html, posthtmlOptions).then(result => result.html)
16
- }
17
-
18
- const tags = direct ? (Array.isArray(config) ? config : false) : get(config, 'inlineCSS.preferBgColorAttribute', false)
19
-
20
- if (Array.isArray(tags)) {
21
- return posthtml([removeInlineBGColor({tags})]).process(html, posthtmlOptions).then(result => result.html)
22
- }
23
-
24
- return html
25
- }
26
-
27
- const removeInlineBGColor = (options = {}) => tree => {
28
- options.tags = options.tags || ['body', 'marquee', 'table', 'tbody', 'td', 'tfoot', 'th', 'thead', 'tr']
29
-
30
- const process = node => {
31
- if (!options.tags.includes(node.tag)) {
32
- return node
33
- }
34
-
35
- const attrs = parseAttrs(node.attrs, {
36
- rules: {
37
- bgcolor: {
38
- delimiter: /\s+/,
39
- glue: ' '
40
- }
41
- }
42
- })
43
-
44
- if (attrs.style && attrs.style['background-color']) {
45
- node.attrs.bgcolor = attrs.style['background-color']
46
-
47
- delete attrs.style['background-color']
48
-
49
- node.attrs.style = toStyleString(attrs.style)
50
- }
51
-
52
- return node
53
- }
54
-
55
- return tree.walk(process)
56
- }
@@ -1,43 +0,0 @@
1
- const posthtml = require('posthtml')
2
- const {get, merge, isEmpty} = require('lodash')
3
- const parseAttrs = require('posthtml-attrs-parser')
4
- const {toStyleString} = require('../utils/helpers')
5
- const defaultConfig = require('../generators/posthtml/defaultConfig')
6
-
7
- module.exports = async (html, config = {}, direct = false) => {
8
- const settings = direct ? config : get(config, 'inlineCSS.keepOnlyAttributeSizes', {})
9
-
10
- if (!isEmpty(settings)) {
11
- const posthtmlOptions = merge(defaultConfig, get(config, 'build.posthtml.options', {}))
12
-
13
- return posthtml([removeInlineSizes(settings)]).process(html, posthtmlOptions).then(result => result.html)
14
- }
15
-
16
- return html
17
- }
18
-
19
- const removeInlineSizes = (mappings = {}) => tree => {
20
- const process = node => {
21
- Object.entries(mappings).forEach(([attribute, tags]) => {
22
- tags = Object.values(tags).map(tag => tag.toLowerCase())
23
-
24
- if (!tags.includes(node.tag)) {
25
- return node
26
- }
27
-
28
- const attrs = parseAttrs(node.attrs)
29
-
30
- tags.forEach(() => {
31
- if (get(node, 'attrs.style')) {
32
- delete attrs.style[attribute]
33
-
34
- node.attrs.style = toStyleString(attrs.style)
35
- }
36
- })
37
- })
38
-
39
- return node
40
- }
41
-
42
- return tree.walk(process)
43
- }
@@ -1,100 +0,0 @@
1
- const postcss = require('postcss')
2
- const posthtml = require('posthtml')
3
- const {get, merge, has, remove} = require('lodash')
4
- const parseAttrs = require('posthtml-attrs-parser')
5
- const matchHelper = require('posthtml-match-helper')
6
- const defaultConfig = require('../generators/posthtml/defaultConfig')
7
-
8
- module.exports = async (html, config = {}) => {
9
- if (get(config, 'removeInlinedSelectors') === false) {
10
- return html
11
- }
12
-
13
- const options = {
14
- posthtml: merge(defaultConfig, get(config, 'build.posthtml.options', {})),
15
- removeUnusedCSS: config
16
- }
17
-
18
- return posthtml([plugin(options)]).process(html, options.posthtml).then(result => result.html)
19
- }
20
-
21
- const plugin = (options = {}) => tree => {
22
- const process = node => {
23
- // For each style tag...
24
- if (node.tag === 'style') {
25
- const {root} = postcss().process(node.content)
26
- const preservedClasses = []
27
-
28
- // Preserve selectors in at rules
29
- root.walkAtRules(rule => {
30
- if (['media', 'supports'].includes(rule.name)) {
31
- rule.walkRules(rule => {
32
- preservedClasses.push(rule.selector)
33
- })
34
- }
35
- })
36
-
37
- root.walkRules(rule => {
38
- const {selector} = rule
39
- const prop = get(rule.nodes[0], 'prop')
40
-
41
- // Preserve pseudo selectors
42
- if (selector.includes(':')) {
43
- preservedClasses.push(selector)
44
- }
45
-
46
- try {
47
- const safelist = get(options.removeUnusedCSS, 'whitelist', [])
48
-
49
- // If we find the selector in the HTML...
50
- tree.match(matchHelper(selector), n => {
51
- // If the selector is safelisted, preserve it
52
- if (safelist.some(item => item.endsWith(selector) || item.startsWith(selector))) {
53
- preservedClasses.push(selector)
54
- return n
55
- }
56
-
57
- const parsedAttrs = parseAttrs(n.attrs)
58
- const classAttr = get(parsedAttrs, 'class', [])
59
- const styleAttr = get(parsedAttrs, 'style', {})
60
-
61
- // If the class is in the style attribute (inlined), remove it
62
- if (has(styleAttr, prop)) {
63
- // Remove the class as long as it's not a preserved class
64
- if (!preservedClasses.some(item => item.endsWith(selector) || item.startsWith(selector))) {
65
- remove(classAttr, classToRemove => selector.includes(classToRemove))
66
- }
67
-
68
- // Remove the rule in the <style> tag
69
- if (rule.parent.type !== 'atrule') {
70
- rule.remove()
71
- }
72
- }
73
-
74
- n.attrs = parsedAttrs.compose()
75
-
76
- // Fix issue with .compose() automatically quoting attributes with no values
77
- Object.entries(n.attrs).forEach(([name, value]) => {
78
- if (value === '' && get(options.posthtml, 'recognizeNoValueAttribute') === true) {
79
- n.attrs[name] = true
80
- }
81
- })
82
-
83
- return n
84
- })
85
- } catch {}
86
- })
87
-
88
- node.content = root.toString().trim()
89
-
90
- // Remove <style> tag if it ends up empty after processing
91
- if (node.content.length === 0) {
92
- node.tag = false
93
- }
94
- }
95
-
96
- return node
97
- }
98
-
99
- return tree.walk(process)
100
- }
@@ -1,48 +0,0 @@
1
- const {comb} = require('email-comb')
2
- const {get, merge, isEmpty, isObject} = require('lodash')
3
- const removeInlinedClasses = require('./removeInlinedSelectors')
4
-
5
- module.exports = async (html, config = {}, direct = false) => {
6
- config = direct ? config : get(config, 'removeUnusedCSS')
7
-
8
- // Don't purge CSS if `removeUnusedCSS` is not set
9
- if (!config || (isObject(config) && isEmpty(config))) {
10
- return html
11
- }
12
-
13
- const safelist = [
14
- '*body*', // Gmail
15
- '.gmail*', // Gmail
16
- '.apple*', // Apple Mail
17
- '.ios*', // Mail on iOS
18
- '.ox-*', // Open-Xchange
19
- '.outlook*', // Outlook.com
20
- '[data-ogs*', // Outlook.com
21
- '.bloop_container', // Airmail
22
- '.Singleton', // Apple Mail 10
23
- '.unused', // Notes 8
24
- '.moz-text-html', // Thunderbird
25
- '.mail-detail-content', // Comcast, Libero webmail
26
- '*edo*', // Edison (all)
27
- '#*', // Freenet uses #msgBody
28
- '.lang*' // Fenced code blocks
29
- ]
30
-
31
- const defaultOptions = {
32
- backend: [
33
- {heads: '{{', tails: '}}'},
34
- {heads: '{%', tails: '%}'}
35
- ],
36
- whitelist: get(config, 'whitelist', safelist)
37
- }
38
-
39
- const options = merge(defaultOptions, config)
40
-
41
- /**
42
- * Remove possibly inlined selectors, as long as we're not calling
43
- * this function directly, i.e. Maizzle.removeUnusedCSS()
44
- * */
45
- html = direct ? html : await removeInlinedClasses(html, options)
46
-
47
- return comb(html, options).result
48
- }
@@ -1,26 +0,0 @@
1
- const posthtml = require('posthtml')
2
- const {get, merge, isObject, isEmpty} = require('lodash')
3
- const mergeInlineLonghand = require('posthtml-postcss-merge-longhand')
4
- const defaultConfig = require('../generators/posthtml/defaultConfig')
5
-
6
- module.exports = async (html, config, direct = false) => {
7
- config = direct ?
8
- (isObject(config) ? config : true) :
9
- get(config, 'shorthandCSS', get(config, 'shorthandInlineCSS', []))
10
-
11
- const posthtmlOptions = merge(defaultConfig, get(config, 'build.posthtml.options', {}))
12
-
13
- if (typeof config === 'boolean' && config) {
14
- html = await posthtml([mergeInlineLonghand()])
15
- .process(html, posthtmlOptions)
16
- .then(result => result.html)
17
- }
18
-
19
- if (isObject(config) && !isEmpty(config)) {
20
- html = await posthtml([mergeInlineLonghand(config)])
21
- .process(html, posthtmlOptions)
22
- .then(result => result.html)
23
- }
24
-
25
- return html
26
- }
@@ -1,13 +0,0 @@
1
- module.exports = {
2
- requireUncached: module => {
3
- try {
4
- delete require.cache[require.resolve(module)]
5
- return require(module)
6
- } catch {
7
- throw new Error(`could not load ${module}`)
8
- }
9
- },
10
- // https://github.com/lukeed/console-clear
11
- clearConsole: () => process.stdout.write('\x1B[H\x1B[2J'),
12
- toStyleString: (object = {}) => Object.entries(object).map(([k, v]) => `${k}: ${v}`).join('; ')
13
- }
@@ -1,79 +0,0 @@
1
- export default interface BaseURLConfig {
2
- /**
3
- The URL to prepend.
4
-
5
- @default undefined
6
- */
7
- url: string;
8
-
9
- /**
10
- Tags to apply the `url` to. When using this option, the `url` will only be prepended to the specified tags.
11
-
12
- Maizzle uses a [custom set of tags](https://github.com/posthtml/posthtml-base-url/blob/main/lib/index.js#L6-L60) by default.
13
-
14
- @example
15
-
16
- Prepend `url` to all 'source'-like attribute values on image tags, like `src` and `srcset`:
17
-
18
- ```
19
- module.exports = {
20
- baseURL: {
21
- url: 'https://cdn.example.com/',
22
- tags: ['img'],
23
- },
24
- }
25
- ```
26
-
27
- With more granular control:
28
-
29
- ```
30
- module.exports = {
31
- baseURL: {
32
- url: 'https://cdn.example.com/',
33
- tags: {
34
- img: {
35
- src: true, // use the value of `url` above
36
- srcset: 'https://bar.com/',
37
- },
38
- },
39
- },
40
- }
41
- ```
42
- */
43
- tags?: string[] | Record<string, unknown>;
44
-
45
- /**
46
- Key-value pairs of attributes and the string to prepend to their existing value.
47
-
48
- @default {}
49
-
50
- @example
51
-
52
- Prepend `https://example.com/` to all `data-url` attribute values:
53
-
54
- ```
55
- module.exports = {
56
- baseURL: {
57
- attributes: {
58
- 'data-url': 'https://example.com/',
59
- },
60
- },
61
- }
62
- ```
63
- */
64
- attributes?: Record<string, unknown>;
65
-
66
- /**
67
- Whether the string defined in `url` should be prepended to `url()` values in CSS `<style>` tags.
68
-
69
- @default true
70
- */
71
- styleTag?: boolean;
72
-
73
- /**
74
- Whether the string defined in `url` should be prepended to `url()` values in inline CSS.
75
-
76
- @default true
77
- */
78
- inlineCss?: boolean;
79
- }
package/types/fetch.d.ts DELETED
@@ -1,143 +0,0 @@
1
- import type {Options as GotOptions} from 'got';
2
- import type ExpressionsConfig from './expressions';
3
-
4
- export default interface PostHTMLFetchConfig {
5
- /**
6
- Supported tag names.
7
- Only tags from this array will be processed by the plugin.
8
-
9
- @default ['fetch', 'remote']
10
-
11
- @example
12
- ```
13
- module.exports = {
14
- build: {
15
- posthtml: {
16
- fetch: {
17
- tags: ['get']
18
- }
19
- }
20
- }
21
- }
22
- ```
23
- */
24
- tags?: string[];
25
-
26
- /**
27
- String representing the attribute name containing the URL to fetch.
28
-
29
- @default 'url'
30
-
31
- @example
32
- ```
33
- module.exports = {
34
- build: {
35
- posthtml: {
36
- fetch: {
37
- attribute: 'from'
38
- }
39
- }
40
- }
41
- }
42
- ```
43
- */
44
- attribute?: string;
45
-
46
- /**
47
- `posthtml-fetch` uses `got` to fetch data.
48
- You can pass options directly to it, inside the `got` object.
49
-
50
- @default {}
51
-
52
- @example
53
- ```
54
- module.exports = {
55
- build: {
56
- posthtml: {
57
- got: {
58
- prefixUrl: '...'
59
- }
60
- }
61
- }
62
- }
63
- ```
64
- */
65
- got?: GotOptions;
66
-
67
- /**
68
- When set to `true`, this option will preserve the `tag`, i.e. `<fetch>` around the response body.
69
-
70
- @default false
71
-
72
- @example
73
- ```
74
- module.exports = {
75
- build: {
76
- posthtml: {
77
- fetch: {
78
- preserveTag: true
79
- }
80
- }
81
- }
82
- }
83
- ```
84
- */
85
- preserveTag?: boolean;
86
-
87
- /**
88
- Pass options to `posthtml-expressions`.
89
-
90
- @default {}
91
-
92
- @example
93
- ```
94
- module.exports = {
95
- build: {
96
- posthtml: {
97
- fetch: {
98
- expressions: {
99
- delimiters: ['[[', ']]']
100
- }
101
- }
102
- }
103
- }
104
- }
105
- ```
106
- */
107
- expressions?: ExpressionsConfig;
108
-
109
- /**
110
- List of plugins that will be called after/before receiving and processing `locals`.
111
-
112
- @default {}
113
-
114
- @example
115
- ```
116
- module.exports = {
117
- build: {
118
- posthtml: {
119
- fetch: {
120
- plugins: {
121
- after(tree) {
122
- // Your plugin implementation
123
- },
124
- before: [
125
- tree => {
126
- // Your plugin implementation
127
- },
128
- tree => {
129
- // ..
130
- }
131
- ]
132
- }
133
- }
134
- }
135
- }
136
- }
137
- ```
138
- */
139
- plugins?: {
140
- after?: (tree: any) => void;
141
- before?: Array<(tree: any) => void>;
142
- };
143
- }