@maizzle/framework 5.0.0-beta.25 → 5.0.0-beta.26

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@maizzle/framework",
3
- "version": "5.0.0-beta.25",
3
+ "version": "5.0.0-beta.26",
4
4
  "description": "Maizzle is a framework that helps you quickly build HTML emails with Tailwind CSS.",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -56,10 +56,10 @@
56
56
  "color-shorthand-hex-to-six-digit": "^5.0.16",
57
57
  "defu": "^6.1.4",
58
58
  "email-comb": "^7.0.21",
59
- "express": "^4.19.2",
59
+ "express": "^4.21.0",
60
60
  "fast-glob": "^3.3.2",
61
61
  "gray-matter": "^4.0.3",
62
- "html-crush": "^6.0.18",
62
+ "html-crush": "^6.0.19",
63
63
  "is-url-superb": "^6.1.0",
64
64
  "istextorbinary": "^9.5.0",
65
65
  "juice": "^11.0.0",
@@ -67,7 +67,7 @@
67
67
  "morphdom": "^2.7.4",
68
68
  "ora": "^8.1.0",
69
69
  "pathe": "^1.1.2",
70
- "postcss": "^8.4.39",
70
+ "postcss": "^8.4.47",
71
71
  "postcss-custom-properties": "^14.0.1",
72
72
  "postcss-import": "^16.1.0",
73
73
  "postcss-safe-parser": "^7.0.0",
@@ -81,7 +81,7 @@
81
81
  "posthtml-fetch": "^4.0.0",
82
82
  "posthtml-markdownit": "^3.1.0",
83
83
  "posthtml-mso": "^3.1.0",
84
- "posthtml-parser": "^0.12.0",
84
+ "posthtml-parser": "^0.12.1",
85
85
  "posthtml-postcss": "^1.0.2",
86
86
  "posthtml-postcss-merge-longhand": "^3.1.2",
87
87
  "posthtml-render": "^3.0.0",
@@ -90,16 +90,16 @@
90
90
  "pretty": "^2.0.0",
91
91
  "string-remove-widows": "^4.0.22",
92
92
  "string-strip-html": "^13.4.8",
93
- "tailwindcss": "^3.4.10",
94
- "ws": "^8.17.0"
93
+ "tailwindcss": "^3.4.13",
94
+ "ws": "^8.18.0"
95
95
  },
96
96
  "devDependencies": {
97
- "@biomejs/biome": "1.8.3",
97
+ "@biomejs/biome": "1.9.2",
98
98
  "@types/js-beautify": "^1.14.3",
99
- "@types/markdown-it": "^14.1.1",
100
- "@vitest/coverage-v8": "^2.0.1",
99
+ "@types/markdown-it": "^14.1.2",
100
+ "@vitest/coverage-v8": "^2.1.1",
101
101
  "supertest": "^7.0.0",
102
- "vitest": "^2.0.1"
102
+ "vitest": "^2.1.1"
103
103
  },
104
104
  "engines": {
105
105
  "node": ">=18.20"
@@ -124,16 +124,7 @@ export async function run(html = '', config = {}) {
124
124
  }
125
125
 
126
126
  /**
127
- * 8. Purge CSS
128
- *
129
- * Remove unused CSS, uglify classes etc.
130
- */
131
- if (get(config, 'css.purge')) {
132
- posthtmlPlugins.push(comb(config.css.purge))
133
- }
134
-
135
- /**
136
- * 9. Remove attributes
127
+ * 8. Remove attributes
137
128
  *
138
129
  * Remove attributes from HTML tags
139
130
  * If `undefined`, removes empty `style` and `class` attributes
@@ -148,7 +139,7 @@ export async function run(html = '', config = {}) {
148
139
  }
149
140
 
150
141
  /**
151
- * 10. Shorthand CSS
142
+ * 9. Shorthand CSS
152
143
  *
153
144
  * Convert longhand CSS properties to shorthand in `style` attributes.
154
145
  */
@@ -159,7 +150,7 @@ export async function run(html = '', config = {}) {
159
150
  }
160
151
 
161
152
  /**
162
- * 11. Add attributes
153
+ * 10. Add attributes
163
154
  *
164
155
  * Add attributes to HTML tags.
165
156
  */
@@ -170,7 +161,7 @@ export async function run(html = '', config = {}) {
170
161
  }
171
162
 
172
163
  /**
173
- * 12. Base URL
164
+ * 11. Base URL
174
165
  *
175
166
  * Add a base URL to relative paths.
176
167
  */
@@ -181,7 +172,7 @@ export async function run(html = '', config = {}) {
181
172
  }
182
173
 
183
174
  /**
184
- * 13. URL parameters
175
+ * 12. URL parameters
185
176
  *
186
177
  * Add parameters to URLs.
187
178
  */
@@ -192,7 +183,7 @@ export async function run(html = '', config = {}) {
192
183
  }
193
184
 
194
185
  /**
195
- * 14. Six-digit HEX
186
+ * 13. Six-digit HEX
196
187
  *
197
188
  * Enabled by default, converts three-digit HEX colors to six-digit.
198
189
  */
@@ -203,7 +194,7 @@ export async function run(html = '', config = {}) {
203
194
  }
204
195
 
205
196
  /**
206
- * 15. PostHTML MSO
197
+ * 14. PostHTML MSO
207
198
  *
208
199
  * Enabled by default, simplifies writing MSO conditionals for Outlook.
209
200
  */
@@ -214,7 +205,23 @@ export async function run(html = '', config = {}) {
214
205
  }
215
206
 
216
207
  /**
217
- * 16. Prettify
208
+ * 15. Purge CSS
209
+ *
210
+ * Remove unused CSS, uglify classes etc.
211
+ */
212
+ if (get(config, 'css.purge')) {
213
+ posthtmlPlugins.push(comb(config.css.purge))
214
+ }
215
+
216
+ /**
217
+ * 16. <template> tags
218
+ *
219
+ * Replace <template> tags with their content.
220
+ */
221
+ posthtmlPlugins.push(templateTag())
222
+
223
+ /**
224
+ * 17. Prettify
218
225
  *
219
226
  * Pretty-print HTML using js-beautify.
220
227
  */
@@ -225,7 +232,7 @@ export async function run(html = '', config = {}) {
225
232
  }
226
233
 
227
234
  /**
228
- * 17. Minify
235
+ * 18. Minify
229
236
  *
230
237
  * Minify HTML using html-crush.
231
238
  */
@@ -235,13 +242,6 @@ export async function run(html = '', config = {}) {
235
242
  )
236
243
  }
237
244
 
238
- /**
239
- * 18. <template> tags
240
- *
241
- * Replace <template> tags with their content.
242
- */
243
- posthtmlPlugins.push(templateTag())
244
-
245
245
  /**
246
246
  * 19. Replace strings
247
247
  *
@@ -55,9 +55,12 @@ export async function inline(html = '', options = {}) {
55
55
  })
56
56
 
57
57
  // Add a `data-embed` attribute to style tags that have the embed attribute
58
- $('style[embed]').each((i, el) => {
58
+ $('style[embed]:not([data-embed])').each((i, el) => {
59
59
  $(el).attr('data-embed', '')
60
60
  })
61
+ $('style[data-embed]:not([embed])').each((i, el) => {
62
+ $(el).attr('embed', '')
63
+ })
61
64
 
62
65
  /**
63
66
  * Inline the CSS
@@ -103,7 +106,31 @@ export async function inline(html = '', options = {}) {
103
106
  }
104
107
  )
105
108
 
106
- const preservedClasses = new Set()
109
+ const preservedClasses = new Set([
110
+ '.body', // Gmail
111
+ '.gmail', // Gmail
112
+ '.apple', // Apple Mail
113
+ '.ios', // Mail on iOS
114
+ '.ox-', // Open-Xchange
115
+ '.outlook', // Outlook.com
116
+ '[data-ogs', // Outlook.com
117
+ '.bloop_container', // Airmail
118
+ '.Singleton', // Apple Mail 10
119
+ '.unused', // Notes 8
120
+ '.moz-text-html', // Thunderbird
121
+ '.mail-detail-content', // Comcast, Libero webmail
122
+ 'edo', // Edison (all)
123
+ '#msgBody', // Freenet uses #msgBody
124
+ '.lang' // Fenced code blocks
125
+ ])
126
+
127
+ // Precompile a single regex to match any substring from the preservedClasses set
128
+ const combinedPattern = Array.from(preservedClasses)
129
+ .map(pattern => pattern.replace(/[-/\\^$*+?.()|[\]{}]/g, '\\$&')) // Escape special regex chars
130
+ .join('|') // Combine all patterns into a single regex pattern with 'OR' (|)
131
+
132
+ const combinedRegex = new RegExp(combinedPattern)
133
+
107
134
  const selectors = new Set()
108
135
 
109
136
  // Preserve selectors in at rules
@@ -163,7 +190,7 @@ export async function inline(html = '', options = {}) {
163
190
 
164
191
  if (options.removeInlinedSelectors) {
165
192
  // Remove the rule in the <style> tag as long as it's not a preserved class
166
- if (!preservedClasses.has(selector)) {
193
+ if (!preservedClasses.has(selector) && !combinedRegex.test(selector)) {
167
194
  rule.remove()
168
195
  }
169
196
 
@@ -194,3 +194,13 @@ export function parseCSSRule(rule) {
194
194
 
195
195
  return { property, value }
196
196
  }
197
+
198
+ /**
199
+ * Normalize a string by removing extra whitespace.
200
+ *
201
+ * @param {String} str The string to clean
202
+ * @returns {String} The cleaned string
203
+ */
204
+ export function cleanString(str) {
205
+ return str.replace(/\s+/g, ' ').trim()
206
+ }