@maizzle/framework 5.0.0-beta.9 → 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.
- package/package.json +31 -29
- package/src/commands/build.js +106 -30
- package/src/generators/plaintext.js +22 -18
- package/src/generators/render.js +16 -18
- package/src/index.js +3 -3
- package/src/posthtml/defaultComponentsConfig.js +10 -2
- package/src/posthtml/defaultConfig.js +13 -3
- package/src/posthtml/index.js +59 -14
- package/src/server/index.js +171 -98
- package/src/server/routes/index.js +51 -13
- package/src/server/views/404.html +59 -0
- package/src/server/views/index.html +162 -14
- package/src/transformers/addAttributes.js +2 -3
- package/src/transformers/attributeToStyle.js +1 -3
- package/src/transformers/baseUrl.js +6 -6
- package/src/transformers/filters/index.js +1 -2
- package/src/transformers/index.js +57 -95
- package/src/transformers/inline.js +44 -48
- package/src/transformers/markdown.js +14 -7
- package/src/transformers/minify.js +4 -3
- package/src/transformers/posthtmlMso.js +1 -3
- package/src/transformers/prettify.js +4 -3
- package/src/transformers/preventWidows.js +15 -65
- package/src/transformers/{comb.js → purge.js} +9 -8
- package/src/transformers/removeAttributes.js +3 -4
- package/src/transformers/replaceStrings.js +7 -5
- package/src/transformers/safeClassNames.js +1 -2
- package/src/transformers/shorthandCss.js +1 -3
- package/src/transformers/sixHex.js +1 -3
- package/src/transformers/template.js +9 -9
- package/src/transformers/urlParameters.js +1 -3
- package/src/transformers/useAttributeSizes.js +1 -3
- package/src/utils/getConfigByFilePath.js +10 -0
- package/src/utils/node.js +0 -23
- package/src/utils/string.js +34 -12
- package/types/build.d.ts +51 -28
- package/types/config.d.ts +127 -64
- package/types/css/inline.d.ts +10 -26
- package/types/css/purge.d.ts +3 -3
- package/types/events.d.ts +153 -5
- package/types/index.d.ts +4 -3
- package/types/posthtml.d.ts +3 -3
- package/types/urlParameters.d.ts +1 -1
- package/types/widowWords.d.ts +16 -36
- package/types/components.d.ts +0 -195
- package/types/expressions.d.ts +0 -100
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@maizzle/framework",
|
|
3
|
-
"version": "5.0.0
|
|
3
|
+
"version": "5.0.0",
|
|
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",
|
|
@@ -48,58 +48,60 @@
|
|
|
48
48
|
"html-emails"
|
|
49
49
|
],
|
|
50
50
|
"dependencies": {
|
|
51
|
-
"@
|
|
52
|
-
"
|
|
53
|
-
"cheerio": "^1.0.0-rc.12",
|
|
51
|
+
"@maizzle/cli": "^2.0.0",
|
|
52
|
+
"cheerio": "^1.0.0",
|
|
54
53
|
"chokidar": "^3.6.0",
|
|
55
54
|
"cli-table3": "^0.6.5",
|
|
56
55
|
"color-shorthand-hex-to-six-digit": "^5.0.16",
|
|
57
56
|
"defu": "^6.1.4",
|
|
58
57
|
"email-comb": "^7.0.21",
|
|
59
|
-
"express": "^4.
|
|
58
|
+
"express": "^4.21.0",
|
|
60
59
|
"fast-glob": "^3.3.2",
|
|
61
60
|
"gray-matter": "^4.0.3",
|
|
62
|
-
"html-crush": "^6.0.
|
|
61
|
+
"html-crush": "^6.0.19",
|
|
63
62
|
"is-url-superb": "^6.1.0",
|
|
64
63
|
"istextorbinary": "^9.5.0",
|
|
65
|
-
"juice": "^
|
|
64
|
+
"juice": "^11.0.0",
|
|
66
65
|
"lodash-es": "^4.17.21",
|
|
67
66
|
"morphdom": "^2.7.4",
|
|
68
|
-
"ora": "^8.0
|
|
67
|
+
"ora": "^8.1.0",
|
|
69
68
|
"pathe": "^1.1.2",
|
|
70
|
-
"postcss": "^8.4.
|
|
71
|
-
"postcss-
|
|
69
|
+
"postcss": "^8.4.49",
|
|
70
|
+
"postcss-calc": "^10.0.2",
|
|
71
|
+
"postcss-css-variables": "^0.19.0",
|
|
72
72
|
"postcss-import": "^16.1.0",
|
|
73
73
|
"postcss-safe-parser": "^7.0.0",
|
|
74
74
|
"posthtml": "^0.16.6",
|
|
75
|
-
"posthtml-attrs-parser": "^1.1.
|
|
75
|
+
"posthtml-attrs-parser": "^1.1.1",
|
|
76
76
|
"posthtml-base-url": "^3.1.4",
|
|
77
|
-
"posthtml-component": "^
|
|
78
|
-
"posthtml-content": "^2.0
|
|
79
|
-
"posthtml-
|
|
80
|
-
"posthtml-
|
|
81
|
-
"posthtml-
|
|
82
|
-
"posthtml-
|
|
83
|
-
"posthtml-
|
|
84
|
-
"posthtml-
|
|
77
|
+
"posthtml-component": "^2.1.0",
|
|
78
|
+
"posthtml-content": "^2.1.0",
|
|
79
|
+
"posthtml-expressions": "^1.11.4",
|
|
80
|
+
"posthtml-extra-attributes": "^3.1.0",
|
|
81
|
+
"posthtml-fetch": "^4.0.0",
|
|
82
|
+
"posthtml-markdownit": "^3.1.0",
|
|
83
|
+
"posthtml-mso": "^3.1.0",
|
|
84
|
+
"posthtml-parser": "^0.12.1",
|
|
85
|
+
"posthtml-postcss": "^1.0.2",
|
|
86
|
+
"posthtml-postcss-merge-longhand": "^3.1.2",
|
|
85
87
|
"posthtml-render": "^3.0.0",
|
|
86
|
-
"posthtml-safe-class-names": "^4.0
|
|
87
|
-
"posthtml-url-parameters": "^3.
|
|
88
|
+
"posthtml-safe-class-names": "^4.1.0",
|
|
89
|
+
"posthtml-url-parameters": "^3.1.0",
|
|
90
|
+
"posthtml-widows": "^1.0.0",
|
|
88
91
|
"pretty": "^2.0.0",
|
|
89
|
-
"string-remove-widows": "^4.0.22",
|
|
90
92
|
"string-strip-html": "^13.4.8",
|
|
91
|
-
"tailwindcss": "^3.4.
|
|
92
|
-
"ws": "^8.
|
|
93
|
+
"tailwindcss": "^3.4.16",
|
|
94
|
+
"ws": "^8.18.0"
|
|
93
95
|
},
|
|
94
96
|
"devDependencies": {
|
|
95
|
-
"@biomejs/biome": "1.
|
|
97
|
+
"@biomejs/biome": "1.9.2",
|
|
96
98
|
"@types/js-beautify": "^1.14.3",
|
|
97
|
-
"@types/markdown-it": "^14.1.
|
|
98
|
-
"@vitest/coverage-v8": "^2.
|
|
99
|
+
"@types/markdown-it": "^14.1.2",
|
|
100
|
+
"@vitest/coverage-v8": "^2.1.5",
|
|
99
101
|
"supertest": "^7.0.0",
|
|
100
|
-
"vitest": "^2.
|
|
102
|
+
"vitest": "^2.1.5"
|
|
101
103
|
},
|
|
102
104
|
"engines": {
|
|
103
|
-
"node": ">=18.
|
|
105
|
+
"node": ">=18.20"
|
|
104
106
|
}
|
|
105
107
|
}
|
package/src/commands/build.js
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import {
|
|
2
2
|
readFile,
|
|
3
3
|
writeFile,
|
|
4
|
+
copyFile,
|
|
4
5
|
lstat,
|
|
5
6
|
mkdir,
|
|
6
|
-
rm
|
|
7
|
+
rm,
|
|
8
|
+
cp,
|
|
7
9
|
} from 'node:fs/promises'
|
|
8
10
|
import path from 'pathe'
|
|
9
11
|
import fg from 'fast-glob'
|
|
@@ -24,10 +26,7 @@ import {
|
|
|
24
26
|
getFileExtensionsFromPattern,
|
|
25
27
|
} from '../utils/string.js'
|
|
26
28
|
|
|
27
|
-
import {
|
|
28
|
-
getColorizedFileSize,
|
|
29
|
-
copyDirectory,
|
|
30
|
-
} from '../utils/node.js'
|
|
29
|
+
import { getColorizedFileSize } from '../utils/node.js'
|
|
31
30
|
|
|
32
31
|
import {
|
|
33
32
|
generatePlaintext,
|
|
@@ -37,7 +36,26 @@ import {
|
|
|
37
36
|
|
|
38
37
|
import { readFileConfig } from '../utils/getConfigByFilePath.js'
|
|
39
38
|
|
|
40
|
-
|
|
39
|
+
/**
|
|
40
|
+
* Ensures that a directory exists, creating it if needed.
|
|
41
|
+
*
|
|
42
|
+
* @param {string} filePath - The path to the file to check.
|
|
43
|
+
*/
|
|
44
|
+
async function ensureDirectoryExistence(filePath) {
|
|
45
|
+
const dirname = path.dirname(filePath)
|
|
46
|
+
await mkdir(dirname, { recursive: true })
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Copy a file from source to target.
|
|
51
|
+
*
|
|
52
|
+
* @param {string} source - The source file path.
|
|
53
|
+
* @param {string} target - The target file path.
|
|
54
|
+
*/
|
|
55
|
+
async function copyFileAsync(source, target) {
|
|
56
|
+
await ensureDirectoryExistence(target)
|
|
57
|
+
await copyFile(source, target)
|
|
58
|
+
}
|
|
41
59
|
|
|
42
60
|
/**
|
|
43
61
|
* Compile templates and output to the build directory.
|
|
@@ -52,7 +70,10 @@ export default async (config = {}) => {
|
|
|
52
70
|
try {
|
|
53
71
|
const startTime = Date.now()
|
|
54
72
|
|
|
55
|
-
|
|
73
|
+
/**
|
|
74
|
+
* Read the config file for this environment,
|
|
75
|
+
* merging it with the default config.
|
|
76
|
+
*/
|
|
56
77
|
config = await readFileConfig(config).catch(() => { throw new Error('Could not compute config') })
|
|
57
78
|
|
|
58
79
|
/**
|
|
@@ -84,17 +105,10 @@ export default async (config = {}) => {
|
|
|
84
105
|
})
|
|
85
106
|
|
|
86
107
|
/**
|
|
87
|
-
*
|
|
88
|
-
*
|
|
89
|
-
* 1. Resolve globs in `build.content` to folders that should be copied over to `build.output.path`
|
|
90
|
-
* 2. Check that templates to be built, actually exist
|
|
108
|
+
* Check that templates to be built, actually exist
|
|
91
109
|
*/
|
|
92
|
-
const contentPaths = get(config, 'build.content', 'src/templates/**/*.html')
|
|
93
|
-
|
|
94
|
-
// 1. Resolve globs in `build.content` to folders that should be copied over to `build.output.path`
|
|
95
|
-
const rootDirs = await getRootDirectories(contentPaths)
|
|
110
|
+
const contentPaths = get(config, 'build.content', ['src/templates/**/*.html'])
|
|
96
111
|
|
|
97
|
-
// 2. Check that templates to be built, actually exist
|
|
98
112
|
const templateFolders = Array.isArray(contentPaths) ? contentPaths : [contentPaths]
|
|
99
113
|
const templatePaths = await fg.glob([...new Set(templateFolders)])
|
|
100
114
|
|
|
@@ -108,8 +122,48 @@ export default async (config = {}) => {
|
|
|
108
122
|
*
|
|
109
123
|
* Copies each `build.content` path to the `build.output.path` directory.
|
|
110
124
|
*/
|
|
111
|
-
|
|
112
|
-
|
|
125
|
+
let from = get(config, 'build.output.from', ['src/templates', 'src'])
|
|
126
|
+
|
|
127
|
+
const globPathsToCopy = contentPaths.map(glob => {
|
|
128
|
+
// Keep negated paths as they are
|
|
129
|
+
if (glob.startsWith('!')) {
|
|
130
|
+
return glob
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
// Keep single-file sources as they are
|
|
134
|
+
if (!/\*/.test(glob)) {
|
|
135
|
+
return glob
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
// Update non-negated paths to target all files, avoiding duplication
|
|
139
|
+
return glob.replace(/\/\*\*\/\*\.\{.*?\}$|\/\*\*\/\*\.[^/]*$|\/*\.[^/]*$/, '/**/*')
|
|
140
|
+
})
|
|
141
|
+
|
|
142
|
+
try {
|
|
143
|
+
from = Array.isArray(from) ? from : [from]
|
|
144
|
+
|
|
145
|
+
/**
|
|
146
|
+
* Copy files from source to destination
|
|
147
|
+
*
|
|
148
|
+
* The array/set conversion is to remove duplicates
|
|
149
|
+
*/
|
|
150
|
+
for (const file of await fg(Array.from(new Set(globPathsToCopy)))) {
|
|
151
|
+
let relativePath
|
|
152
|
+
for (const dir of from) {
|
|
153
|
+
if (file.startsWith(dir)) {
|
|
154
|
+
relativePath = path.relative(dir, file)
|
|
155
|
+
break
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
if (!relativePath) {
|
|
159
|
+
relativePath = path.relative('.', file)
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
const targetPath = path.join(buildOutputPath, relativePath)
|
|
163
|
+
await copyFileAsync(file, targetPath)
|
|
164
|
+
}
|
|
165
|
+
} catch (error) {
|
|
166
|
+
console.error('Error while processing pattern:', error)
|
|
113
167
|
}
|
|
114
168
|
|
|
115
169
|
/**
|
|
@@ -121,13 +175,15 @@ export default async (config = {}) => {
|
|
|
121
175
|
const outputExtensions = new Set()
|
|
122
176
|
|
|
123
177
|
for (const pattern of contentPaths) {
|
|
124
|
-
outputExtensions.add(
|
|
178
|
+
getFileExtensionsFromPattern(pattern).map(ext => outputExtensions.add(ext))
|
|
125
179
|
}
|
|
126
180
|
|
|
127
181
|
/**
|
|
128
182
|
* Create a list of templates to compile
|
|
129
183
|
*/
|
|
130
|
-
const extensions = outputExtensions.size > 1
|
|
184
|
+
const extensions = outputExtensions.size > 1
|
|
185
|
+
? `{${[...outputExtensions].join(',')}}`
|
|
186
|
+
: [...outputExtensions][0] || 'html'
|
|
131
187
|
|
|
132
188
|
const templatesToCompile = await fg.glob(
|
|
133
189
|
path.join(
|
|
@@ -154,7 +210,26 @@ export default async (config = {}) => {
|
|
|
154
210
|
|
|
155
211
|
const html = await readFile(templatePath, 'utf8')
|
|
156
212
|
|
|
157
|
-
|
|
213
|
+
/**
|
|
214
|
+
* Render the markup.
|
|
215
|
+
*
|
|
216
|
+
* Merging a custom `components` object to make sure that file extensions from both
|
|
217
|
+
* `build.content` * and * `components.fileExtension` are used when scanning for
|
|
218
|
+
* component files.
|
|
219
|
+
*/
|
|
220
|
+
const userComponentFileExtensions = get(config, 'components.fileExtension', ['html'])
|
|
221
|
+
|
|
222
|
+
const rendered = await render(html, merge(
|
|
223
|
+
{
|
|
224
|
+
components: {
|
|
225
|
+
fileExtension: [
|
|
226
|
+
...outputExtensions,
|
|
227
|
+
...(new Set([].concat(userComponentFileExtensions))),
|
|
228
|
+
],
|
|
229
|
+
}
|
|
230
|
+
},
|
|
231
|
+
config
|
|
232
|
+
))
|
|
158
233
|
|
|
159
234
|
/**
|
|
160
235
|
* Generate plaintext
|
|
@@ -167,12 +242,14 @@ export default async (config = {}) => {
|
|
|
167
242
|
if (Boolean(plaintextConfig) || !isEmpty(plaintextConfig)) {
|
|
168
243
|
const posthtmlOptions = get(rendered.config, 'posthtml.options', {})
|
|
169
244
|
|
|
170
|
-
|
|
245
|
+
await writePlaintextFile(
|
|
246
|
+
await generatePlaintext(rendered.html, merge(plaintextConfig, posthtmlOptions)),
|
|
247
|
+
rendered.config
|
|
248
|
+
).catch(error => {
|
|
249
|
+
throw new Error(`Error writing plaintext file: ${error}`)
|
|
250
|
+
})
|
|
251
|
+
|
|
171
252
|
rendered.html = await handlePlaintextTags(rendered.html, posthtmlOptions)
|
|
172
|
-
await writePlaintextFile(plaintext, rendered.config)
|
|
173
|
-
.catch(error => {
|
|
174
|
-
throw new Error(`Error writing plaintext file: ${error}`)
|
|
175
|
-
})
|
|
176
253
|
}
|
|
177
254
|
|
|
178
255
|
/**
|
|
@@ -225,10 +302,10 @@ export default async (config = {}) => {
|
|
|
225
302
|
* TODO: support an array of objects with source and destination,
|
|
226
303
|
* i.e. static: [{ source: 'src/assets', destination: 'assets' }, ...]
|
|
227
304
|
*/
|
|
228
|
-
const staticSourcePaths =
|
|
305
|
+
const staticSourcePaths = getRootDirectories([...new Set(get(config, 'build.static.source', []))])
|
|
229
306
|
|
|
230
|
-
for await (const rootDir of
|
|
231
|
-
await
|
|
307
|
+
for await (const rootDir of staticSourcePaths) {
|
|
308
|
+
await cp(rootDir, path.join(buildOutputPath, get(config, 'build.static.destination')), { recursive: true })
|
|
232
309
|
}
|
|
233
310
|
|
|
234
311
|
const allOutputFiles = await fg.glob(path.join(buildOutputPath, '**/*'))
|
|
@@ -240,7 +317,6 @@ export default async (config = {}) => {
|
|
|
240
317
|
await config.afterBuild({
|
|
241
318
|
config,
|
|
242
319
|
files: allOutputFiles,
|
|
243
|
-
transform: transformers,
|
|
244
320
|
})
|
|
245
321
|
}
|
|
246
322
|
|
|
@@ -3,8 +3,8 @@ import posthtml from 'posthtml'
|
|
|
3
3
|
import get from 'lodash-es/get.js'
|
|
4
4
|
import { defu as merge } from 'defu'
|
|
5
5
|
import { stripHtml } from 'string-strip-html'
|
|
6
|
-
import defaultConfig from '../posthtml/defaultConfig.js'
|
|
7
6
|
import { writeFile, lstat, mkdir } from 'node:fs/promises'
|
|
7
|
+
import { getPosthtmlOptions } from '../posthtml/defaultConfig.js'
|
|
8
8
|
|
|
9
9
|
/**
|
|
10
10
|
* Removes HTML tags from a given HTML string based on
|
|
@@ -46,7 +46,7 @@ const removeTags = ({ tag = 'not-plaintext', html = '', config = {} }) => {
|
|
|
46
46
|
return tree.walk(process)
|
|
47
47
|
}
|
|
48
48
|
|
|
49
|
-
const posthtmlOptions = merge(
|
|
49
|
+
const posthtmlOptions = merge(config, getPosthtmlOptions())
|
|
50
50
|
|
|
51
51
|
return posthtml([posthtmlPlugin()]).process(html, { ...posthtmlOptions }).then(res => res.html)
|
|
52
52
|
}
|
|
@@ -95,7 +95,7 @@ export async function handlePlaintextTags(html = '', config = {}) {
|
|
|
95
95
|
return tree.walk(process)
|
|
96
96
|
}
|
|
97
97
|
|
|
98
|
-
const posthtmlOptions = merge(
|
|
98
|
+
const posthtmlOptions = merge(config, getPosthtmlOptions())
|
|
99
99
|
|
|
100
100
|
return posthtml([posthtmlPlugin()]).process(html, { ...posthtmlOptions }).then(res => res.html)
|
|
101
101
|
}
|
|
@@ -154,17 +154,11 @@ export async function writePlaintextFile(plaintext = '', config = {}) {
|
|
|
154
154
|
const plaintextExtension = get(plaintextConfig, 'output.extension', 'txt')
|
|
155
155
|
|
|
156
156
|
/**
|
|
157
|
-
* If `plaintext: true` (either from Front Matter or from config)
|
|
157
|
+
* If `plaintext: true` (either from Front Matter or from config),
|
|
158
|
+
* output plaintext file in the same location as the HTML file.
|
|
158
159
|
*/
|
|
159
160
|
if (plaintextConfig === true) {
|
|
160
|
-
|
|
161
|
-
if (typeof config.permalink === 'string') {
|
|
162
|
-
// Output plaintext at the `permalink` path
|
|
163
|
-
plaintextOutputPath = config.permalink
|
|
164
|
-
} else {
|
|
165
|
-
// Output plaintext at the same directory as the HTML file
|
|
166
|
-
plaintextOutputPath = get(config, 'build.output.path')
|
|
167
|
-
}
|
|
161
|
+
plaintextOutputPath = get(config, 'build.output.path')
|
|
168
162
|
}
|
|
169
163
|
|
|
170
164
|
/**
|
|
@@ -179,12 +173,22 @@ export async function writePlaintextFile(plaintext = '', config = {}) {
|
|
|
179
173
|
// No need to handle if it's an object, since we already set it to that initially
|
|
180
174
|
|
|
181
175
|
/**
|
|
182
|
-
* If `
|
|
176
|
+
* If the template has a `permalink` key set in the FM, always output plaintext file there
|
|
177
|
+
*/
|
|
178
|
+
if (typeof config.permalink === 'string') {
|
|
179
|
+
plaintextOutputPath = config.permalink
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
/**
|
|
183
|
+
* If `plaintextOutputPath` is a file path, output file there.
|
|
184
|
+
*
|
|
185
|
+
* The file will be output relative to the project root, and the extension
|
|
186
|
+
* doesn't matter, it will be replaced with `plaintextExtension`.
|
|
183
187
|
*/
|
|
184
188
|
if (path.extname(plaintextOutputPath)) {
|
|
185
189
|
// Ensure the target directory exists
|
|
186
190
|
await lstat(plaintextOutputPath).catch(async () => {
|
|
187
|
-
await mkdir(plaintextOutputPath, { recursive: true })
|
|
191
|
+
await mkdir(path.dirname(plaintextOutputPath), { recursive: true })
|
|
188
192
|
})
|
|
189
193
|
|
|
190
194
|
// Ensure correct extension is used
|
|
@@ -193,19 +197,19 @@ export async function writePlaintextFile(plaintext = '', config = {}) {
|
|
|
193
197
|
path.basename(plaintextOutputPath, path.extname(plaintextOutputPath)) + '.' + plaintextExtension
|
|
194
198
|
)
|
|
195
199
|
|
|
196
|
-
console.log('plaintextOutputPath', plaintextOutputPath);
|
|
197
|
-
|
|
198
200
|
return writeFile(plaintextOutputPath, plaintext)
|
|
199
201
|
}
|
|
200
202
|
|
|
201
203
|
/**
|
|
202
|
-
* If `plaintextOutputPath` is a directory path, output file there
|
|
204
|
+
* If `plaintextOutputPath` is a directory path, output file there using the Template's name.
|
|
205
|
+
*
|
|
206
|
+
* The file will be output relative to the `build.output.path` directory.
|
|
203
207
|
*/
|
|
204
208
|
const templateFileName = get(config, 'build.current.path.name')
|
|
205
209
|
|
|
206
210
|
plaintextOutputPath = path.join(
|
|
207
|
-
path.dirname(plaintextOutputPath),
|
|
208
211
|
get(config, 'build.current.path.dir'),
|
|
212
|
+
plaintextOutputPath,
|
|
209
213
|
templateFileName + '.' + plaintextExtension
|
|
210
214
|
)
|
|
211
215
|
|
package/src/generators/render.js
CHANGED
|
@@ -4,8 +4,9 @@ import { cwd } from 'node:process'
|
|
|
4
4
|
import { defu as merge } from 'defu'
|
|
5
5
|
import expressions from 'posthtml-expressions'
|
|
6
6
|
import { parseFrontMatter } from '../utils/node.js'
|
|
7
|
+
import { getPosthtmlOptions } from '../posthtml/defaultConfig.js'
|
|
7
8
|
import { process as compilePostHTML } from '../posthtml/index.js'
|
|
8
|
-
import { run as useTransformers
|
|
9
|
+
import { run as useTransformers } from '../transformers/index.js'
|
|
9
10
|
|
|
10
11
|
export async function render(html = '', config = {}) {
|
|
11
12
|
if (typeof html !== 'string') {
|
|
@@ -40,7 +41,7 @@ export async function render(html = '', config = {}) {
|
|
|
40
41
|
})
|
|
41
42
|
]
|
|
42
43
|
)
|
|
43
|
-
.process(matter)
|
|
44
|
+
.process(matter, getPosthtmlOptions())
|
|
44
45
|
.then(({ html }) => parseFrontMatter(`---${html}\n---`))
|
|
45
46
|
|
|
46
47
|
const templateConfig = merge(matterData, config)
|
|
@@ -57,20 +58,21 @@ export async function render(html = '', config = {}) {
|
|
|
57
58
|
*
|
|
58
59
|
* @param {Object} options
|
|
59
60
|
* @param {string} options.html - The HTML to be transformed
|
|
61
|
+
* @param {Object} options.matter - The front matter data
|
|
60
62
|
* @param {Object} options.config - The current template config
|
|
61
|
-
* @param {function} options.render - The render function
|
|
62
63
|
* @returns {string} - The transformed HTML, or the original one if nothing was returned
|
|
63
64
|
*/
|
|
64
65
|
if (typeof templateConfig.beforeRender === 'function') {
|
|
65
66
|
content = await templateConfig.beforeRender(({
|
|
66
67
|
html: content,
|
|
68
|
+
matter: matterData,
|
|
67
69
|
config: templateConfig,
|
|
68
|
-
posthtml: compilePostHTML,
|
|
69
|
-
transform: transformers,
|
|
70
70
|
})) ?? content
|
|
71
71
|
}
|
|
72
72
|
|
|
73
|
-
|
|
73
|
+
/**
|
|
74
|
+
* Compile PostHTML
|
|
75
|
+
*/
|
|
74
76
|
const compiled = await compilePostHTML(content, templateConfig)
|
|
75
77
|
|
|
76
78
|
/**
|
|
@@ -78,20 +80,18 @@ export async function render(html = '', config = {}) {
|
|
|
78
80
|
*
|
|
79
81
|
* @param {Object} options
|
|
80
82
|
* @param {string} options.html - The HTML to be transformed
|
|
83
|
+
* @param {Object} options.matter - The front matter data
|
|
81
84
|
* @param {Object} options.config - The current template config
|
|
82
|
-
* @param {function} options.render - The render function
|
|
83
85
|
* @returns {string} - The transformed HTML, or the original one if nothing was returned
|
|
84
86
|
*/
|
|
85
87
|
if (typeof templateConfig.afterRender === 'function') {
|
|
86
88
|
compiled.html = await templateConfig.afterRender(({
|
|
87
89
|
html: compiled.html,
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
transform: transformers,
|
|
90
|
+
matter: matterData,
|
|
91
|
+
config: compiled.config,
|
|
91
92
|
})) ?? compiled.html
|
|
92
93
|
}
|
|
93
94
|
|
|
94
|
-
// Run Transformers
|
|
95
95
|
/**
|
|
96
96
|
* Run Transformers
|
|
97
97
|
*
|
|
@@ -102,30 +102,28 @@ export async function render(html = '', config = {}) {
|
|
|
102
102
|
* @returns {string} - The transformed HTML
|
|
103
103
|
*/
|
|
104
104
|
if (templateConfig.useTransformers !== false) {
|
|
105
|
-
compiled.html = await useTransformers(compiled.html,
|
|
105
|
+
compiled.html = await useTransformers(compiled.html, compiled.config).then(({ html }) => html)
|
|
106
106
|
}
|
|
107
107
|
|
|
108
|
-
// Run `afterTransformers` event
|
|
109
108
|
/**
|
|
110
109
|
* Run `afterTransformers` event
|
|
111
110
|
*
|
|
112
111
|
* @param {Object} options
|
|
113
112
|
* @param {string} options.html - The HTML to be transformed
|
|
113
|
+
* @param {Object} options.matter - The front matter data
|
|
114
114
|
* @param {Object} options.config - The current template config
|
|
115
|
-
* @param {function} options.render - The render function
|
|
116
115
|
* @returns {string} - The transformed HTML, or the original one if nothing was returned
|
|
117
116
|
*/
|
|
118
117
|
if (typeof templateConfig.afterTransformers === 'function') {
|
|
119
118
|
compiled.html = await templateConfig.afterTransformers(({
|
|
120
119
|
html: compiled.html,
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
transform: transformers,
|
|
120
|
+
matter: matterData,
|
|
121
|
+
config: compiled.config,
|
|
124
122
|
})) ?? compiled.html
|
|
125
123
|
}
|
|
126
124
|
|
|
127
125
|
return {
|
|
128
|
-
config:
|
|
126
|
+
config: compiled.config,
|
|
129
127
|
html: compiled.html,
|
|
130
128
|
}
|
|
131
129
|
}
|
package/src/index.js
CHANGED
|
@@ -5,7 +5,7 @@ import { render } from './generators/render.js'
|
|
|
5
5
|
import { addAttributes } from './transformers/addAttributes.js'
|
|
6
6
|
import { attributeToStyle } from './transformers/attributeToStyle.js'
|
|
7
7
|
import { addBaseUrl } from './transformers/baseUrl.js'
|
|
8
|
-
import {
|
|
8
|
+
import { purge } from './transformers/purge.js'
|
|
9
9
|
import { filters } from './transformers/filters/index.js'
|
|
10
10
|
import { inline } from './transformers/inline.js'
|
|
11
11
|
import { markdown } from './transformers/markdown.js'
|
|
@@ -29,8 +29,8 @@ export {
|
|
|
29
29
|
addAttributes,
|
|
30
30
|
attributeToStyle,
|
|
31
31
|
addBaseUrl,
|
|
32
|
-
|
|
33
|
-
|
|
32
|
+
purge as removeUnusedCSS,
|
|
33
|
+
purge as purgeCSS,
|
|
34
34
|
filters,
|
|
35
35
|
inline as inlineCSS,
|
|
36
36
|
markdown,
|
|
@@ -1,8 +1,16 @@
|
|
|
1
1
|
export default {
|
|
2
2
|
root: './',
|
|
3
|
-
folders: ['src/components', 'src/layouts', 'src/templates'],
|
|
4
|
-
fileExtension: 'html',
|
|
5
3
|
tag: 'component',
|
|
4
|
+
fileExtension: ['html'],
|
|
5
|
+
folders: [
|
|
6
|
+
'layouts',
|
|
7
|
+
'emails',
|
|
8
|
+
'templates',
|
|
9
|
+
'components',
|
|
10
|
+
'src/layouts',
|
|
11
|
+
'src/templates',
|
|
12
|
+
'src/components'
|
|
13
|
+
],
|
|
6
14
|
expressions: {
|
|
7
15
|
loopTags: ['each', 'for'],
|
|
8
16
|
missingLocal: '{local}',
|
|
@@ -1,4 +1,14 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
import { defu as merge } from 'defu'
|
|
2
|
+
|
|
3
|
+
export function getPosthtmlOptions(userConfigOptions = {}) {
|
|
4
|
+
return merge(
|
|
5
|
+
userConfigOptions,
|
|
6
|
+
{
|
|
7
|
+
recognizeNoValueAttribute: true,
|
|
8
|
+
recognizeSelfClosing: true,
|
|
9
|
+
directives: [
|
|
10
|
+
{ name: '?php', start: '<', end: '>' },
|
|
11
|
+
],
|
|
12
|
+
}
|
|
13
|
+
)
|
|
4
14
|
}
|