@maizzle/framework 5.0.0-beta.18 → 5.0.0-beta.19

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.18",
3
+ "version": "5.0.0-beta.19",
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",
@@ -55,7 +55,7 @@ export async function process(html = '', config = {}) {
55
55
  merge(
56
56
  {
57
57
  expressions: merge(
58
- locals,
58
+ { locals },
59
59
  expressionsOptions,
60
60
  {
61
61
  missingLocal: '{local}',
@@ -77,9 +77,10 @@ export async function process(html = '', config = {}) {
77
77
  components(
78
78
  merge(
79
79
  {
80
- expressions: {
81
- locals,
82
- }
80
+ expressions: merge(
81
+ { locals },
82
+ expressionsOptions,
83
+ )
83
84
  },
84
85
  componentsUserOptions,
85
86
  defaultComponentsConfig
@@ -112,10 +112,12 @@ export default async (config = {}) => {
112
112
 
113
113
  /**
114
114
  * Dev server settings
115
- */
115
+ */
116
+ spinner.spinner = get(config, 'server.spinner', 'circleHalves')
117
+ spinner.start('Starting server...')
118
+
116
119
  const shouldScroll = get(config, 'server.scrollSync', false)
117
120
  const useHmr = get(config, 'server.hmr', true)
118
- spinner.spinner = get(config, 'server.spinner', 'circleHalves')
119
121
 
120
122
  // Add static assets root prefix so user doesn't have to
121
123
  if (!config.baseURL) {
@@ -193,20 +195,6 @@ export default async (config = {}) => {
193
195
  })
194
196
  })
195
197
 
196
- // Error-handling middleware
197
- app.use(async (error, req, res, next) => {
198
- console.error(error)
199
-
200
- const view = await fs.readFile(path.join(__dirname, 'views', 'error.html'), 'utf8')
201
- const { html } = await render(view, {
202
- method: req.method,
203
- url: req.url,
204
- error
205
- })
206
-
207
- res.status(500).send(html)
208
- })
209
-
210
198
  /**
211
199
  * Components watcher
212
200
  *
@@ -214,7 +202,19 @@ export default async (config = {}) => {
214
202
  */
215
203
  let isWatcherReady = false
216
204
  chokidar
217
- .watch([...templatePaths, ...get(config, 'components.folders', defaultComponentsConfig.folders)])
205
+ .watch(
206
+ [
207
+ ...templatePaths,
208
+ ...get(config, 'components.folders', defaultComponentsConfig.folders)
209
+ ],
210
+ {
211
+ ignoreInitial: true,
212
+ awaitWriteFinish: {
213
+ stabilityThreshold: 150,
214
+ pollInterval: 25,
215
+ },
216
+ }
217
+ )
218
218
  .on('change', async () => {
219
219
  if (viewing) {
220
220
  await renderUpdatedFile(viewing, config)
@@ -244,20 +244,33 @@ export default async (config = {}) => {
244
244
  /**
245
245
  * Global watcher
246
246
  *
247
- * Watch for changes in the config file, Tailwind CSS config, and CSS files
247
+ * Watch for changes in the config files, Tailwind CSS config, CSS files,
248
+ * configured static assets, and user-defined watch paths.
248
249
  */
249
250
  const globalWatchedPaths = new Set([
250
- 'config*.js',
251
- 'maizzle.config*.js',
252
- 'tailwind*.config.js',
251
+ 'config*.{js,cjs,ts}',
252
+ 'maizzle.config*.{js,cjs,ts}',
253
+ 'tailwind*.config.{js,ts}',
253
254
  '**/*.css',
254
- ...get(config, 'server.watch', [])
255
+ ...get(config, 'build.static.source', []),
256
+ ...get(config, 'server.watch', []),
255
257
  ])
256
258
 
257
259
  async function globalPathsHandler(file, eventType) {
260
+ // Update express.static to serve new files
261
+ if (eventType === 'add') {
262
+ app.use(express.static(path.dirname(file)))
263
+ }
264
+
265
+ // Stop serving deleted files
266
+ if (eventType === 'unlink') {
267
+ app._router.stack = app._router.stack.filter(
268
+ layer => layer.regexp.source !== path.dirname(file).replace(/\\/g, '/')
269
+ )
270
+ }
271
+
258
272
  // Not viewing a component in the browser, no need to rebuild
259
273
  if (!viewing) {
260
- spinner.info(`file ${eventType}: ${file}`)
261
274
  return
262
275
  }
263
276
 
@@ -314,7 +327,7 @@ export default async (config = {}) => {
314
327
  }
315
328
  })
316
329
  } catch (error) {
317
- spinner.fail('Failed to render template.')
330
+ spinner.fail(`Failed to render template: ${file}`)
318
331
  throw error
319
332
  }
320
333
  }
@@ -326,6 +339,10 @@ export default async (config = {}) => {
326
339
  get(config, 'build.output.path', 'build_production'),
327
340
  ],
328
341
  ignoreInitial: true,
342
+ awaitWriteFinish: {
343
+ stabilityThreshold: 150,
344
+ pollInterval: 25,
345
+ },
329
346
  })
330
347
  .on('change', async file => await globalPathsHandler(file, 'change'))
331
348
  .on('add', async file => await globalPathsHandler(file, 'add'))
@@ -333,8 +350,6 @@ export default async (config = {}) => {
333
350
 
334
351
  /**
335
352
  * Serve all folders in the cwd as static files
336
- *
337
- * TODO: change to include build.assets or build.static, which may be outside cwd
338
353
  */
339
354
  const srcFoldersList = await fg.glob(
340
355
  [
@@ -352,6 +367,16 @@ export default async (config = {}) => {
352
367
  app.use(express.static(path.join(config.cwd, folder)))
353
368
  })
354
369
 
370
+ // Error-handling middleware
371
+ app.use(async (req, res) => {
372
+ const view = await fs.readFile(path.join(__dirname, 'views', '404.html'), 'utf8')
373
+ const { html } = await render(view, {
374
+ url: req.url,
375
+ })
376
+
377
+ res.status(404).send(html)
378
+ })
379
+
355
380
  /**
356
381
  * Start the server
357
382
  */
@@ -361,8 +386,6 @@ export default async (config = {}) => {
361
386
 
362
387
  function startServer(port) {
363
388
  const serverStartTime = Date.now()
364
- spinner.start('Starting server...')
365
-
366
389
  const server = createServer(app)
367
390
 
368
391
  /**
@@ -0,0 +1,59 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>404 - Template not found</title>
7
+ <style>
8
+ html, body {
9
+ font-family: Helvetica, Arial, sans-serif;
10
+ margin: 0;
11
+ padding: 0;
12
+ box-sizing: border-box;
13
+ height: 100%;
14
+ }
15
+
16
+ .container {
17
+ box-sizing: border-box;
18
+ height: 100vh;
19
+ display: flex;
20
+ align-items: center;
21
+ justify-content: center;
22
+ position: relative;
23
+ z-index: 1;
24
+ padding: 24px;
25
+ }
26
+
27
+ .error-code {
28
+ font-size: 25rem;
29
+ font-weight: 700;
30
+ color: #f1f5f9;
31
+ position: fixed;
32
+ top: -1.5rem;
33
+ left: -3rem;
34
+ user-select: none;
35
+ }
36
+ </style>
37
+ </head>
38
+ <body>
39
+ <span class="error-code">404</span>
40
+
41
+ <div class="container">
42
+ <div style="text-align: center;">
43
+ <h1 style="font-size: 3rem; color: #0F172A; margin: 2.25rem 0">
44
+ Template Not Found
45
+ </h1>
46
+ <p style="margin: 0 0 2.25rem; font-size: 1.25rem; line-height: 1.5; color: #64748B;">
47
+ The Template you are looking for was not found:
48
+ </p>
49
+ <p style="margin: 1rem 0 0; font-size: 1rem; line-height: 1.5; font-weight: 600; color: #334155;">
50
+ {{ page.url }}
51
+ </p>
52
+ </div>
53
+ </div>
54
+
55
+ <div style="position: fixed; bottom: 0; right: 0; pointer-events: none; user-select: none;">
56
+ <svg width="883" height="536" fill="none" xmlns="http://www.w3.org/2000/svg"><mask id="a" style="mask-type:alpha" maskUnits="userSpaceOnUse" x="0" y="0" width="1100" height="536"><path fill="#D9D9D9" d="M0 .955h1100V536H0z"/></mask><g mask="url(#a)" stroke="#94A3B8" stroke-miterlimit="10"><path d="M1056.93 92.587c0-50.03-43.95-90.587-98.168-90.587-54.22 0-98.174 40.557-98.174 90.587v483.125c0 50.029 43.954 90.586 98.174 90.586 54.218 0 98.168-40.557 98.168-90.586V92.587ZM646.241 92.587C646.241 42.556 602.287 2 548.067 2c-54.219 0-98.173 40.557-98.173 90.587v483.125c0 50.029 43.954 90.586 98.173 90.586 54.22 0 98.174-40.557 98.174-90.586V92.587Z"/><path d="M1036.18 148.383c33.41-39.402 25.88-96.336-16.82-127.164C976.657-9.61 914.955-2.66 881.544 36.742L471.586 520.215c-33.411 39.402-25.879 96.336 16.824 127.164 42.702 30.829 104.404 23.879 137.815-15.523l409.955-483.473ZM625.093 148.396c33.411-39.403 25.878-96.336-16.824-127.164C565.567-9.597 503.865-2.647 470.454 36.755L60.495 520.228c-33.41 39.402-25.878 96.336 16.825 127.164 42.702 30.829 104.404 23.879 137.815-15.523l409.958-483.473Z"/></g></svg>
57
+ </div>
58
+ </body>
59
+ </html>
package/types/build.d.ts CHANGED
@@ -116,4 +116,31 @@ export default interface BuildConfig {
116
116
  * ```
117
117
  */
118
118
  summary?: boolean;
119
+
120
+ /**
121
+ * Information about the Template currently being compiled.
122
+ *
123
+ * @example
124
+ *
125
+ * ```
126
+ * {
127
+ path: {
128
+ root: 'build_production',
129
+ dir: 'build_production',
130
+ base: 'transactional.html',
131
+ ext: '.html',
132
+ name: 'transactional'
133
+ }
134
+ }
135
+ * ```
136
+ */
137
+ current?: {
138
+ path?: {
139
+ root: string;
140
+ dir: string;
141
+ base: string;
142
+ ext: string;
143
+ name: string;
144
+ };
145
+ };
119
146
  }