@maizzle/framework 5.0.0-beta.6 → 5.0.0-beta.8

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.6",
3
+ "version": "5.0.0-beta.8",
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",
@@ -73,7 +73,7 @@
73
73
  "postcss-safe-parser": "^7.0.0",
74
74
  "posthtml": "^0.16.6",
75
75
  "posthtml-attrs-parser": "^1.1.0",
76
- "posthtml-base-url": "^3.1.2",
76
+ "posthtml-base-url": "^3.1.3",
77
77
  "posthtml-component": "^1.1.0",
78
78
  "posthtml-content": "^2.0.1",
79
79
  "posthtml-extra-attributes": "^3.0.0",
@@ -212,13 +212,11 @@ export default async (config = {}) => {
212
212
  /**
213
213
  * Add file to CLI table for build summary logging
214
214
  */
215
- if (config.build.summary) {
216
- table.push([
217
- path.relative(get(rendered.config, 'build.output.path'), outputPath),
218
- getColorizedFileSize(rendered.html),
219
- formatTime(Date.now() - templateBuildStartTime)
220
- ])
221
- }
215
+ table.push([
216
+ path.relative(get(rendered.config, 'build.output.path'), outputPath),
217
+ getColorizedFileSize(rendered.html),
218
+ formatTime(Date.now() - templateBuildStartTime)
219
+ ])
222
220
  }
223
221
 
224
222
  /**
@@ -233,7 +231,7 @@ export default async (config = {}) => {
233
231
  await copyDirectory(rootDir, path.join(buildOutputPath, get(config, 'build.static.destination')))
234
232
  }
235
233
 
236
- const compiledFiles = await fg.glob(path.join(buildOutputPath, '**/*'))
234
+ const allOutputFiles = await fg.glob(path.join(buildOutputPath, '**/*'))
237
235
 
238
236
  /**
239
237
  * Run `afterBuild` event
@@ -241,7 +239,7 @@ export default async (config = {}) => {
241
239
  if (typeof config.afterBuild === 'function') {
242
240
  await config.afterBuild({
243
241
  config,
244
- files: compiledFiles,
242
+ files: allOutputFiles,
245
243
  transform: transformers,
246
244
  })
247
245
  }
@@ -256,10 +254,10 @@ export default async (config = {}) => {
256
254
  console.log(table.toString() + '\n')
257
255
  }
258
256
 
259
- spinner.succeed(`Build completed in ${formatTime(Date.now() - startTime)}`)
257
+ spinner.succeed(`Built ${table.length} template${table.length > 1 ? 's' : ''} in ${formatTime(Date.now() - startTime)}`)
260
258
 
261
259
  return {
262
- files: compiledFiles,
260
+ files: allOutputFiles,
263
261
  config
264
262
  }
265
263
  } catch (error) {
@@ -8,6 +8,7 @@ import posthtmlPostcss from 'posthtml-postcss'
8
8
  import defaultPosthtmlConfig from './defaultConfig.js'
9
9
  import expandLinkTag from './plugins/expandLinkTag.js'
10
10
  import envAttributes from './plugins/envAttributes.js'
11
+ import envTags from './plugins/envTags.js'
11
12
 
12
13
  // PostCSS
13
14
  import tailwindcss from 'tailwindcss'
@@ -51,6 +52,7 @@ export async function process(html = '', config = {}) {
51
52
 
52
53
  return posthtml([
53
54
  ...get(config, 'posthtml.plugins.before', []),
55
+ envTags(config.env),
54
56
  envAttributes(config.env),
55
57
  expandLinkTag,
56
58
  postcssPlugin,
@@ -0,0 +1,33 @@
1
+ const plugin = (env => tree => {
2
+ const process = node => {
3
+ env = env || 'local'
4
+
5
+ // Return the original node if it doesn't have a tag
6
+ if (!node.tag) {
7
+ return node
8
+ }
9
+
10
+ const tagEnv = node.tag.split(':').pop()
11
+
12
+ // Tag targets current env, remove it and return its content
13
+ if (node.tag === `env:${env}`) {
14
+ node.tag = false
15
+ }
16
+
17
+ // Tag doesn't target current env, remove it completely
18
+ if (
19
+ typeof node.tag === 'string'
20
+ && node.tag.startsWith('env:')
21
+ && tagEnv !== env
22
+ ) {
23
+ node.content = []
24
+ node.tag = false
25
+ }
26
+
27
+ return node
28
+ }
29
+
30
+ return tree.walk(process)
31
+ })
32
+
33
+ export default plugin
@@ -8,6 +8,7 @@ import minify from './minify.js'
8
8
  import baseUrl from './baseUrl.js'
9
9
  import inlineCSS from './inline.js'
10
10
  import prettify from './prettify.js'
11
+ import templateTag from './template.js'
11
12
  import filters from './filters/index.js'
12
13
  import markdown from 'posthtml-markdownit'
13
14
  import posthtmlMso from './posthtmlMso.js'
@@ -251,7 +252,14 @@ export async function run(html = '', config = {}) {
251
252
  }
252
253
 
253
254
  /**
254
- * 18. Replace strings
255
+ * 18. <template> tags
256
+ *
257
+ * Replace <template> tags with their content
258
+ */
259
+ posthtmlPlugins.push(templateTag())
260
+
261
+ /**
262
+ * 19. Replace strings
255
263
  *
256
264
  * Replace strings through regular expressions
257
265
  */
@@ -10,6 +10,7 @@ import * as cheerio from 'cheerio/lib/slim'
10
10
  import safeParser from 'postcss-safe-parser'
11
11
  import isObject from 'lodash-es/isObject.js'
12
12
  import { parser as parse } from 'posthtml-parser'
13
+ import { parseCSSRule } from '../utils/string.js'
13
14
  import { useAttributeSizes } from './useAttributeSizes.js'
14
15
 
15
16
  const posthtmlPlugin = (options = {}) => tree => {
@@ -179,7 +180,7 @@ export async function inline(html = '', options = {}) {
179
180
 
180
181
  if (styleAttr) {
181
182
  inlineStyles = styleAttr.split(';').reduce((acc, i) => {
182
- let [property, value] = i.split(':').map(i => i.trim())
183
+ let { property, value } = parseCSSRule(i)
183
184
 
184
185
  if (value && options.resolveCalc) {
185
186
  value = value.includes('calc') ? calc(value, {precision: 2}) : value
@@ -0,0 +1,26 @@
1
+ const posthtmlPlugin = (() => tree => {
2
+ const process = node => {
3
+ // Return the original node if it doesn't have a tag
4
+ if (!node.tag) {
5
+ return node
6
+ }
7
+
8
+ // Preserve <template> tags marked as such
9
+ if (node.tag === 'template' && node.attrs?.preserve) {
10
+ node.attrs.preserve = false
11
+
12
+ return node
13
+ }
14
+
15
+ // Replace <template> tags with their content
16
+ if (node.tag === 'template') {
17
+ node.tag = false
18
+ }
19
+
20
+ return node
21
+ }
22
+
23
+ return tree.walk(process)
24
+ })
25
+
26
+ export default posthtmlPlugin
@@ -161,3 +161,24 @@ export function getFileExtensionsFromPattern(pattern) {
161
161
 
162
162
  return ['html'] // No recognizable extension pattern, default to 'html'
163
163
  }
164
+
165
+ export function parseCSSRule(rule) {
166
+ // Step 1: Trim the input string
167
+ rule = rule.trim()
168
+
169
+ // Step 2: Find the index of the first colon
170
+ const colonIndex = rule.indexOf(':')
171
+
172
+ // Step 3: Extract property and value parts
173
+ if (colonIndex === -1) {
174
+ return {
175
+ property: '',
176
+ value: ''
177
+ }
178
+ }
179
+
180
+ const property = rule.slice(0, colonIndex).trim()
181
+ const value = rule.slice(colonIndex + 1).trim()
182
+
183
+ return { property, value }
184
+ }