@maizzle/framework 5.0.0-beta.8 → 5.0.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 (46) hide show
  1. package/package.json +33 -31
  2. package/src/commands/build.js +106 -30
  3. package/src/generators/plaintext.js +22 -18
  4. package/src/generators/render.js +16 -18
  5. package/src/index.js +3 -3
  6. package/src/posthtml/defaultComponentsConfig.js +10 -2
  7. package/src/posthtml/defaultConfig.js +13 -3
  8. package/src/posthtml/index.js +59 -14
  9. package/src/server/index.js +171 -98
  10. package/src/server/routes/index.js +51 -13
  11. package/src/server/views/404.html +59 -0
  12. package/src/server/views/index.html +162 -14
  13. package/src/transformers/addAttributes.js +2 -3
  14. package/src/transformers/attributeToStyle.js +1 -3
  15. package/src/transformers/baseUrl.js +6 -6
  16. package/src/transformers/filters/index.js +1 -2
  17. package/src/transformers/index.js +57 -95
  18. package/src/transformers/inline.js +44 -48
  19. package/src/transformers/markdown.js +14 -7
  20. package/src/transformers/minify.js +4 -3
  21. package/src/transformers/posthtmlMso.js +1 -3
  22. package/src/transformers/prettify.js +4 -3
  23. package/src/transformers/preventWidows.js +15 -65
  24. package/src/transformers/{comb.js → purge.js} +9 -8
  25. package/src/transformers/removeAttributes.js +3 -4
  26. package/src/transformers/replaceStrings.js +7 -5
  27. package/src/transformers/safeClassNames.js +1 -2
  28. package/src/transformers/shorthandCss.js +1 -3
  29. package/src/transformers/sixHex.js +1 -3
  30. package/src/transformers/template.js +9 -9
  31. package/src/transformers/urlParameters.js +1 -3
  32. package/src/transformers/useAttributeSizes.js +1 -3
  33. package/src/utils/getConfigByFilePath.js +10 -0
  34. package/src/utils/node.js +0 -23
  35. package/src/utils/string.js +34 -12
  36. package/types/build.d.ts +51 -28
  37. package/types/config.d.ts +127 -64
  38. package/types/css/inline.d.ts +10 -26
  39. package/types/css/purge.d.ts +3 -3
  40. package/types/events.d.ts +153 -5
  41. package/types/index.d.ts +4 -3
  42. package/types/posthtml.d.ts +3 -3
  43. package/types/urlParameters.d.ts +1 -1
  44. package/types/widowWords.d.ts +16 -36
  45. package/types/components.d.ts +0 -195
  46. package/types/expressions.d.ts +0 -100
@@ -2,19 +2,19 @@ import juice from 'juice'
2
2
  import postcss from 'postcss'
3
3
  import get from 'lodash-es/get.js'
4
4
  import has from 'lodash-es/has.js'
5
+ import * as cheerio from 'cheerio/slim'
5
6
  import remove from 'lodash-es/remove.js'
6
7
  import { render } from 'posthtml-render'
7
- import { calc } from '@csstools/css-calc'
8
8
  import isEmpty from 'lodash-es/isEmpty.js'
9
- import * as cheerio from 'cheerio/lib/slim'
10
9
  import safeParser from 'postcss-safe-parser'
11
10
  import isObject from 'lodash-es/isObject.js'
12
11
  import { parser as parse } from 'posthtml-parser'
13
12
  import { parseCSSRule } from '../utils/string.js'
14
13
  import { useAttributeSizes } from './useAttributeSizes.js'
14
+ import { getPosthtmlOptions } from '../posthtml/defaultConfig.js'
15
15
 
16
16
  const posthtmlPlugin = (options = {}) => tree => {
17
- return inline(render(tree), options).then(html => parse(html))
17
+ return inline(render(tree), options).then(html => parse(html, getPosthtmlOptions()))
18
18
  }
19
19
 
20
20
  export default posthtmlPlugin
@@ -28,10 +28,28 @@ export async function inline(html = '', options = {}) {
28
28
  const removeStyleTags = get(options, 'removeStyleTags', false)
29
29
  const css = get(options, 'customCSS', false)
30
30
 
31
- options.resolveCSSVariables = get(options, 'resolveCSSVariables', true)
32
31
  options.removeInlinedSelectors = get(options, 'removeInlinedSelectors', true)
33
- options.resolveCalc = get(options, 'resolveCalc', true)
34
32
  options.preferUnitlessValues = get(options, 'preferUnitlessValues', true)
33
+ options.safelist = new Set([
34
+ ...get(options, 'safelist', []),
35
+ ...[
36
+ '.body', // Gmail
37
+ '.gmail', // Gmail
38
+ '.apple', // Apple Mail
39
+ '.ios', // Mail on iOS
40
+ '.ox-', // Open-Xchange
41
+ '.outlook', // Outlook.com
42
+ '[data-ogs', // Outlook.com
43
+ '.bloop_container', // Airmail
44
+ '.Singleton', // Apple Mail 10
45
+ '.unused', // Notes 8
46
+ '.moz-text-html', // Thunderbird
47
+ '.mail-detail-content', // Comcast, Libero webmail
48
+ 'edo', // Edison (all)
49
+ '#msgBody', // Freenet uses #msgBody
50
+ '.lang' // Fenced code blocks
51
+ ],
52
+ ])
35
53
 
36
54
  juice.styleToAttribute = get(options, 'styleToAttribute', {})
37
55
  juice.applyWidthAttributes = get(options, 'applyWidthAttributes', true)
@@ -46,12 +64,20 @@ export async function inline(html = '', options = {}) {
46
64
  })
47
65
  }
48
66
 
49
- const $ = cheerio.load(html, { decodeEntities: false, _useHtmlParser2: true })
67
+ const $ = cheerio.load(html, {
68
+ xml: {
69
+ decodeEntities: false,
70
+ xmlMode: false,
71
+ }
72
+ })
50
73
 
51
74
  // Add a `data-embed` attribute to style tags that have the embed attribute
52
- $('style[embed]').each((i, el) => {
75
+ $('style[embed]:not([data-embed])').each((i, el) => {
53
76
  $(el).attr('data-embed', '')
54
77
  })
78
+ $('style[data-embed]:not([embed])').each((i, el) => {
79
+ $(el).attr('embed', '')
80
+ })
55
81
 
56
82
  /**
57
83
  * Inline the CSS
@@ -97,51 +123,26 @@ export async function inline(html = '', options = {}) {
97
123
  }
98
124
  )
99
125
 
100
- const preservedClasses = new Set()
126
+ // Precompile a single regex to match any substring from the preservedClasses set
127
+ const combinedPattern = Array.from(options.safelist)
128
+ .map(pattern => pattern.replace(/[-/\\^$*+?.()|[\]{}]/g, '\\$&')) // Escape special regex chars
129
+ .join('|') // Combine all patterns into a single regex pattern with 'OR' (|)
130
+
131
+ const combinedRegex = new RegExp(combinedPattern)
132
+
101
133
  const selectors = new Set()
102
134
 
103
135
  // Preserve selectors in at rules
104
136
  root.walkAtRules(rule => {
105
137
  if (['media', 'supports'].includes(rule.name)) {
106
138
  rule.walkRules(rule => {
107
- preservedClasses.add(rule.selector)
139
+ options.safelist.add(rule.selector)
108
140
  })
109
141
  }
110
142
  })
111
143
 
112
144
  // For each rule in the CSS block we're parsing
113
145
  root.walkRules(rule => {
114
- // Keep track of declarations in the rule
115
- const declarations = new Set()
116
-
117
- rule.walkDecls(decl => {
118
- // Resolve calc() values to static values
119
- if (options.resolveCalc) {
120
- decl.value = decl.value.includes('calc(') ? calc(decl.value, {precision: 2}) : decl.value
121
- }
122
-
123
- declarations.add(decl)
124
- })
125
-
126
- /**
127
- * Remove duplicate declarations
128
- *
129
- * Only do so if the `resolveCSSVariables` option is enabled,
130
- * otherwise we'll end up removing all declarations that use CSS variables
131
- */
132
- if (options.resolveCSSVariables) {
133
- Array.from(declarations)
134
- /**
135
- * Consider only declarations with a value that includes any of the other declarations' property
136
- * So a decl like color(var(--text-color)) will be removed if there's a decl with a property of --text-color
137
- * */
138
- .filter(decl =>
139
- Array.from(declarations).some(otherDecl => decl.value.includes(otherDecl.prop))
140
- || decl.prop.startsWith('--')
141
- )
142
- .map(decl => decl.remove())
143
- }
144
-
145
146
  const { selector } = rule
146
147
 
147
148
  selectors.add({
@@ -150,14 +151,13 @@ export async function inline(html = '', options = {}) {
150
151
  })
151
152
 
152
153
  // Preserve pseudo selectors
153
- // TODO: revisit pseudos list
154
154
  if ([':hover', ':active', ':focus', ':visited', ':link', ':before', ':after'].some(i => selector.includes(i))) {
155
- preservedClasses.add(selector)
155
+ options.safelist.add(selector)
156
156
  }
157
157
 
158
158
  if (options.removeInlinedSelectors) {
159
159
  // Remove the rule in the <style> tag as long as it's not a preserved class
160
- if (!preservedClasses.has(selector)) {
160
+ if (!options.safelist.has(selector) && !combinedRegex.test(selector)) {
161
161
  rule.remove()
162
162
  }
163
163
 
@@ -182,10 +182,6 @@ export async function inline(html = '', options = {}) {
182
182
  inlineStyles = styleAttr.split(';').reduce((acc, i) => {
183
183
  let { property, value } = parseCSSRule(i)
184
184
 
185
- if (value && options.resolveCalc) {
186
- value = value.includes('calc') ? calc(value, {precision: 2}) : value
187
- }
188
-
189
185
  if (value && options.preferUnitlessValues) {
190
186
  value = value.replace(
191
187
  /\b0(px|rem|em|%|vh|vw|vmin|vmax|in|cm|mm|pt|pc|ex|ch)\b/g,
@@ -216,7 +212,7 @@ export async function inline(html = '', options = {}) {
216
212
  // If the class has been inlined in the style attribute...
217
213
  if (has(inlineStyles, prop)) {
218
214
  // Try to remove the classes that have been inlined
219
- if (![...preservedClasses].some(item => item.endsWith(name) || item.startsWith(name))) {
215
+ if (![...options.safelist].some(item => item.includes(name))) {
220
216
  remove(classList, classToRemove => name.includes(classToRemove))
221
217
  }
222
218
 
@@ -1,19 +1,26 @@
1
1
  import posthtml from 'posthtml'
2
- import { defu as merge } from 'defu'
3
2
  import md from 'posthtml-markdownit'
4
- import posthtmlConfig from '../posthtml/defaultConfig.js'
5
3
 
6
- export async function markdown(html = '', options = {}, posthtmlOptions = {}) {
4
+ export async function markdown(input = '', options = {}, posthtmlOptions = {}) {
7
5
  /**
8
- * Automatically wrap in <md> tag, unless manual mode is enabled
9
- * With manual mode, user must wrap the markdown content in a <md> tag
6
+ * If no input is provided, return an empty string.
7
+ */
8
+ if (!input) {
9
+ return ''
10
+ }
11
+
12
+ /**
13
+ * Automatically wrap in <md> tag, unless manual mode is enabled.
14
+ *
15
+ * With manual mode, user must wrap the input in a <md> tag.
16
+ *
10
17
  * https://github.com/posthtml/posthtml-markdownit#usage
11
18
  */
12
- html = options.manual ? html : `<md>${html}</md>`
19
+ input = options.manual ? input : `<md>${input}</md>`
13
20
 
14
21
  return posthtml([
15
22
  md(options)
16
23
  ])
17
- .process(html, merge(posthtmlOptions, posthtmlConfig))
24
+ .process(input, posthtmlOptions)
18
25
  .then(result => result.html)
19
26
  }
@@ -3,16 +3,17 @@ import { crush } from 'html-crush'
3
3
  import { defu as merge } from 'defu'
4
4
  import { render } from 'posthtml-render'
5
5
  import { parser as parse } from 'posthtml-parser'
6
- import posthtmlConfig from '../posthtml/defaultConfig.js'
6
+ import { getPosthtmlOptions } from '../posthtml/defaultConfig.js'
7
7
 
8
8
  const posthtmlPlugin = (options = {}) => tree => {
9
9
  options = merge(options, {
10
10
  removeLineBreaks: true,
11
11
  })
12
12
 
13
+ const posthtmlConfig = getPosthtmlOptions()
13
14
  const { result: html } = crush(render(tree), options)
14
15
 
15
- return parse(html)
16
+ return parse(html, posthtmlConfig)
16
17
  }
17
18
 
18
19
  export default posthtmlPlugin
@@ -21,6 +22,6 @@ export async function minify(html = '', options = {}, posthtmlOptions = {}) {
21
22
  return posthtml([
22
23
  posthtmlPlugin(options)
23
24
  ])
24
- .process(html, merge(posthtmlOptions, posthtmlConfig))
25
+ .process(html, posthtmlOptions)
25
26
  .then(result => result.html)
26
27
  }
@@ -1,7 +1,5 @@
1
1
  import posthtml from 'posthtml'
2
- import { defu as merge } from 'defu'
3
2
  import posthtmlMso from 'posthtml-mso'
4
- import posthtmlConfig from '../posthtml/defaultConfig.js'
5
3
 
6
4
  export default function posthtmlPlugin(options = {}) {
7
5
  return posthtmlMso(options)
@@ -11,6 +9,6 @@ export async function useMso(html = '', options = {}, posthtmlOptions = {}) {
11
9
  return posthtml([
12
10
  posthtmlPlugin(options)
13
11
  ])
14
- .process(html, merge(posthtmlOptions, posthtmlConfig))
12
+ .process(html, posthtmlOptions)
15
13
  .then(result => result.html)
16
14
  }
@@ -2,7 +2,8 @@ import pretty from 'pretty'
2
2
  import posthtml from 'posthtml'
3
3
  import { defu as merge } from 'defu'
4
4
  import { render } from 'posthtml-render'
5
- import posthtmlConfig from '../posthtml/defaultConfig.js'
5
+ import { parser as parse } from 'posthtml-parser'
6
+ import { getPosthtmlOptions } from '../posthtml/defaultConfig.js'
6
7
 
7
8
  const posthtmlPlugin = (options = {}) => tree => {
8
9
  const defaultConfig = {
@@ -14,7 +15,7 @@ const posthtmlPlugin = (options = {}) => tree => {
14
15
 
15
16
  const config = merge(options, defaultConfig)
16
17
 
17
- return pretty(render(tree), config)
18
+ return parse(pretty(render(tree), config), getPosthtmlOptions())
18
19
  }
19
20
 
20
21
  export default posthtmlPlugin
@@ -23,6 +24,6 @@ export async function prettify(html = '', options = {}, posthtmlOptions = {}) {
23
24
  return posthtml([
24
25
  posthtmlPlugin(options)
25
26
  ])
26
- .process(html, merge(posthtmlOptions, posthtmlConfig))
27
+ .process(html, posthtmlOptions)
27
28
  .then(result => result.html)
28
29
  }
@@ -1,87 +1,37 @@
1
1
  import posthtml from 'posthtml'
2
+ import posthtmlWidows from 'posthtml-widows'
2
3
  import { defu as merge } from 'defu'
3
- import { removeWidows } from 'string-remove-widows'
4
- import posthtmlConfig from '../posthtml/defaultConfig.js'
5
4
 
6
- const posthtmlPlugin = (options = {}) => tree => {
5
+ export default function posthtmlPlugin(options = {}) {
7
6
  options = merge(options, {
8
- minWordCount: 3,
9
- attrName: 'prevent-widows'
7
+ minWords: 3
10
8
  })
11
9
 
12
- // Ignore defaults
10
+ // Custom ignores
13
11
  const mappings = [
14
- // Jinja-like
15
- {
16
- heads: '{{',
17
- tails: '}}'
18
- },
19
- {
20
- heads: ['{% if', '{%- if'],
21
- tails: ['{% endif', '{%- endif']
22
- },
23
- {
24
- heads: ['{% for', '{%- for'],
25
- tails: ['{% endfor', '{%- endfor']
26
- },
27
- {
28
- heads: ['{%', '{%-'],
29
- tails: ['%}', '-%}']
30
- },
31
- {
32
- heads: '{#',
33
- tails: '#}'
34
- },
35
- // ASP/Hexo-like
36
- {
37
- heads: ['<%', '<%=', '<%-'],
38
- tails: ['%>', '=%>', '-%>']
39
- },
40
12
  // MSO comments
41
13
  {
42
- heads: '<!--[',
43
- tails: ']>'
14
+ start: '<!--[',
15
+ end: ']>'
44
16
  },
45
17
  // <![endif]-->
46
18
  {
47
- heads: '<![',
48
- tails: ']--><'
19
+ start: '<![',
20
+ end: ']--><'
49
21
  }
50
22
  ]
51
23
 
52
24
  if (Array.isArray(options.ignore)) {
53
- options.ignore.forEach(pair => mappings.push(pair))
54
- }
55
-
56
- if (typeof options.ignore !== 'string') {
57
- options.ignore = mappings
58
- }
59
-
60
- const process = node => {
61
- if (node.attrs && Object.keys(node.attrs).includes(options.attrName)) {
62
- const widowsRemovedString = removeWidows(tree.render(node.content), options).res
63
- node.content = tree.render(tree.parser(widowsRemovedString))
64
- delete node.attrs[options.attrName]
65
- }
66
-
67
- return node
25
+ options.ignore = options.ignore.concat(mappings)
68
26
  }
69
27
 
70
- return tree.walk(process)
28
+ return posthtmlWidows(options)
71
29
  }
72
30
 
73
- export default posthtmlPlugin
74
-
75
31
  export async function preventWidows(html = '', options = {}, posthtmlOptions = {}) {
76
- // Apply only to elements that contain the `prevent-widows` attribute
77
- if (options.withAttributes) {
78
- return posthtml([
79
- posthtmlPlugin(options)
80
- ])
81
- .process(html, merge(posthtmlOptions, posthtmlConfig))
82
- .then(result => result.html)
83
- }
84
-
85
- // Apply to all elements
86
- return removeWidows(html, options).res
32
+ return posthtml([
33
+ posthtmlPlugin(options)
34
+ ])
35
+ .process(html, posthtmlOptions)
36
+ .then(result => result.html)
87
37
  }
@@ -1,10 +1,10 @@
1
1
  import posthtml from 'posthtml'
2
+ import { comb } from 'email-comb'
2
3
  import get from 'lodash-es/get.js'
3
4
  import { defu as merge } from 'defu'
4
5
  import { render } from 'posthtml-render'
5
- import { comb as emailComb } from 'email-comb'
6
6
  import { parser as parse } from 'posthtml-parser'
7
- import posthtmlConfig from '../posthtml/defaultConfig.js'
7
+ import { getPosthtmlOptions } from '../posthtml/defaultConfig.js'
8
8
 
9
9
  const posthtmlPlugin = options => tree => {
10
10
  const defaultSafelist = [
@@ -30,22 +30,23 @@ const posthtmlPlugin = options => tree => {
30
30
  { heads: '{{', tails: '}}' },
31
31
  { heads: '{%', tails: '%}' },
32
32
  ],
33
- whitelist: [...defaultSafelist, ...get(options, 'whitelist', [])]
33
+ whitelist: [...defaultSafelist, ...get(options, 'safelist', [])]
34
34
  }
35
35
 
36
36
  options = merge(options, defaultOptions)
37
37
 
38
- const { result: html } = emailComb(render(tree), options)
38
+ const posthtmlConfig = getPosthtmlOptions()
39
+ const { result: html } = comb(render(tree), options)
39
40
 
40
- return parse(html)
41
+ return parse(html, posthtmlConfig)
41
42
  }
42
43
 
43
44
  export default posthtmlPlugin
44
45
 
45
- export async function comb(html = '', options = {}, posthtmlOptions = {}) {
46
+ export async function purge(html = '', pluginOptions = {}, posthtmlOptions = {}) {
46
47
  return posthtml([
47
- posthtmlPlugin(options)
48
+ posthtmlPlugin(pluginOptions)
48
49
  ])
49
- .process(html, merge(posthtmlOptions, posthtmlConfig))
50
+ .process(html, posthtmlOptions)
50
51
  .then(result => result.html)
51
52
  }
@@ -1,7 +1,6 @@
1
1
  import posthtml from 'posthtml'
2
2
  import get from 'lodash-es/get.js'
3
- import { defu as merge } from 'defu'
4
- import posthtmlConfig from '../posthtml/defaultConfig.js'
3
+ import { getPosthtmlOptions } from '../posthtml/defaultConfig.js'
5
4
 
6
5
  /**
7
6
  * Remove empty attributes with PostHTML
@@ -49,8 +48,8 @@ export default posthtmlPlugin
49
48
 
50
49
  export async function removeAttributes(html = '', attributes = [], posthtmlOptions = {}) {
51
50
  return posthtml([
52
- posthtmlPlugin(attributes, merge(posthtmlOptions, posthtmlConfig))
51
+ posthtmlPlugin(attributes, getPosthtmlOptions(posthtmlOptions))
53
52
  ])
54
- .process(html, merge(posthtmlOptions, posthtmlConfig))
53
+ .process(html, getPosthtmlOptions())
55
54
  .then(result => result.html)
56
55
  }
@@ -1,9 +1,8 @@
1
1
  import posthtml from 'posthtml'
2
- import { defu as merge } from 'defu'
3
2
  import { render } from 'posthtml-render'
4
3
  import isEmpty from 'lodash-es/isEmpty.js'
5
4
  import { parser as parse } from 'posthtml-parser'
6
- import posthtmlConfig from '../posthtml/defaultConfig.js'
5
+ import { getPosthtmlOptions } from '../posthtml/defaultConfig.js'
7
6
 
8
7
  const posthtmlPlugin = (replacements = {}) => tree => {
9
8
  if (!isEmpty(replacements)) {
@@ -14,10 +13,13 @@ const posthtmlPlugin = (replacements = {}) => tree => {
14
13
  render(tree).replace(patterns, matched => {
15
14
  for (const [regex, replacement] of regexes) {
16
15
  if (regex.test(matched)) {
17
- return replacement
16
+ return matched.replace(regex, replacement)
18
17
  }
19
18
  }
20
- })
19
+
20
+ return matched
21
+ }),
22
+ getPosthtmlOptions()
21
23
  )
22
24
  }
23
25
 
@@ -30,6 +32,6 @@ export async function replaceStrings(html = '', replacements = {}, posthtmlOptio
30
32
  return posthtml([
31
33
  posthtmlPlugin(replacements)
32
34
  ])
33
- .process(html, merge(posthtmlOptions, posthtmlConfig))
35
+ .process(html, posthtmlOptions)
34
36
  .then(result => result.html)
35
37
  }
@@ -1,6 +1,5 @@
1
1
  import posthtml from 'posthtml'
2
2
  import { defu as merge } from 'defu'
3
- import posthtmlConfig from '../posthtml/defaultConfig.js'
4
3
  import posthtmlSafeClassNames from 'posthtml-safe-class-names'
5
4
 
6
5
  export default function posthtmlPlugin(options = {}) {
@@ -24,6 +23,6 @@ export async function safeClassNames(html = '', options = {}, posthtmlOptions =
24
23
  return posthtml([
25
24
  posthtmlPlugin(options)
26
25
  ])
27
- .process(html, merge(posthtmlOptions, posthtmlConfig))
26
+ .process(html, posthtmlOptions)
28
27
  .then(result => result.html)
29
28
  }
@@ -1,6 +1,4 @@
1
1
  import posthtml from 'posthtml'
2
- import { defu as merge } from 'defu'
3
- import posthtmlConfig from '../posthtml/defaultConfig.js'
4
2
  import posthtmlMergeLonghand from 'posthtml-postcss-merge-longhand'
5
3
 
6
4
  export default function posthtmlPlugin(options = {}) {
@@ -17,6 +15,6 @@ export async function shorthandCSS(html = '', options = {}, posthtmlOptions = {}
17
15
  return posthtml([
18
16
  posthtmlPlugin(options)
19
17
  ])
20
- .process(html, merge(posthtmlOptions, posthtmlConfig))
18
+ .process(html, posthtmlOptions)
21
19
  .then(result => result.html)
22
20
  }
@@ -1,7 +1,5 @@
1
1
  import posthtml from 'posthtml'
2
- import { defu as merge } from 'defu'
3
2
  import { conv } from 'color-shorthand-hex-to-six-digit'
4
- import posthtmlConfig from '../posthtml/defaultConfig.js'
5
3
 
6
4
  const posthtmlPlugin = () => tree => {
7
5
  const targets = new Set(['bgcolor', 'color'])
@@ -27,6 +25,6 @@ export async function sixHEX(html = '', posthtmlOptions = {}) {
27
25
  return posthtml([
28
26
  posthtmlPlugin()
29
27
  ])
30
- .process(html, merge(posthtmlOptions, posthtmlConfig))
28
+ .process(html, posthtmlOptions)
31
29
  .then(result => result.html)
32
30
  }
@@ -1,19 +1,19 @@
1
- const posthtmlPlugin = (() => tree => {
1
+ const posthtmlPlugin = () => tree => {
2
2
  const process = node => {
3
3
  // Return the original node if it doesn't have a tag
4
4
  if (!node.tag) {
5
5
  return node
6
6
  }
7
7
 
8
- // Preserve <template> tags marked as such
9
- if (node.tag === 'template' && node.attrs?.preserve) {
10
- node.attrs.preserve = false
8
+ if (node.tag === 'template') {
9
+ // Preserve <template> tags marked as such
10
+ if ('attrs' in node && 'preserve' in node.attrs) {
11
+ node.attrs.preserve = false
11
12
 
12
- return node
13
- }
13
+ return node
14
+ }
14
15
 
15
- // Replace <template> tags with their content
16
- if (node.tag === 'template') {
16
+ // Remove the <template> tag
17
17
  node.tag = false
18
18
  }
19
19
 
@@ -21,6 +21,6 @@ const posthtmlPlugin = (() => tree => {
21
21
  }
22
22
 
23
23
  return tree.walk(process)
24
- })
24
+ }
25
25
 
26
26
  export default posthtmlPlugin
@@ -1,8 +1,6 @@
1
1
  import posthtml from 'posthtml'
2
2
  import get from 'lodash-es/get.js'
3
- import { defu as merge } from 'defu'
4
3
  import urlParameters from 'posthtml-url-parameters'
5
- import posthtmlConfig from '../posthtml/defaultConfig.js'
6
4
 
7
5
  export default function posthtmlPlugin(options = {}) {
8
6
  const { _options, ...parameters } = options
@@ -17,6 +15,6 @@ export async function addURLParams(html = '', options = {}, posthtmlOptions = {}
17
15
  return posthtml([
18
16
  posthtmlPlugin(options)
19
17
  ])
20
- .process(html, merge(posthtmlOptions, posthtmlConfig))
18
+ .process(html, posthtmlOptions)
21
19
  .then(result => result.html)
22
20
  }
@@ -1,8 +1,6 @@
1
1
  import postcss from 'postcss'
2
2
  import posthtml from 'posthtml'
3
3
  import get from 'lodash-es/get.js'
4
- import { defu as merge } from 'defu'
5
- import posthtmlConfig from '../posthtml/defaultConfig.js'
6
4
 
7
5
  const posthtmlPlugin = (mappings = {}) => tree => {
8
6
  if (!Object.keys(mappings).length) {
@@ -60,6 +58,6 @@ export async function useAttributeSizes(html = '', mappings = {}, posthtmlOption
60
58
  return posthtml([
61
59
  posthtmlPlugin(mappings)
62
60
  ])
63
- .process(html, merge(posthtmlOptions, posthtmlConfig))
61
+ .process(html, posthtmlOptions)
64
62
  .then(result => result.html)
65
63
  }
@@ -117,6 +117,16 @@ export async function readFileConfig(config) {
117
117
  }
118
118
  }
119
119
 
120
+ /**
121
+ * Override the `content` key in `baseConfig` with the one in `envConfig`.
122
+ *
123
+ * This is done so that each build uses its own `content` paths, in
124
+ * order to avoid compiling unnecessary files.
125
+ */
126
+ if (Array.isArray(envConfig.content)) {
127
+ baseConfig.content = []
128
+ }
129
+
120
130
  return merge(envConfig, baseConfig)
121
131
  } catch (error) {
122
132
  throw new Error('Could not compute config')
package/src/utils/node.js CHANGED
@@ -1,13 +1,7 @@
1
- import path from 'pathe'
2
1
  import os from 'node:os'
3
2
  import gm from 'gray-matter'
4
3
  import pico from 'picocolors'
5
4
  import { humanFileSize } from './string.js'
6
- import {
7
- copyFile,
8
- mkdir,
9
- readdir
10
- } from 'node:fs/promises'
11
5
 
12
6
  // Return a local IP address
13
7
  export function getLocalIP() {
@@ -72,20 +66,3 @@ export function parseFrontMatter(html) {
72
66
  const { content, data, matter, stringify } = gm(html, {})
73
67
  return { content, data, matter, stringify }
74
68
  }
75
-
76
- export async function copyDirectory(src, dest) {
77
- await mkdir(dest, { recursive: true })
78
-
79
- const entries = await readdir(src, { withFileTypes: true })
80
-
81
- for (const entry of entries) {
82
- const srcPath = path.join(src, entry.name)
83
- const destPath = path.join(dest, entry.name)
84
-
85
- if (entry.isDirectory()) {
86
- await copyDirectory(srcPath, destPath) // Recursively copy subdirectories
87
- } else {
88
- await copyFile(srcPath, destPath) // Copy files
89
- }
90
- }
91
- }