@maizzle/framework 3.7.2 → 4.0.0-alpha.10

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 (84) hide show
  1. package/.github/workflows/nodejs.yml +28 -29
  2. package/bin/maizzle +3 -0
  3. package/package.json +91 -84
  4. package/src/commands/build.js +32 -0
  5. package/src/commands/serve.js +156 -0
  6. package/src/functions/plaintext.js +5 -0
  7. package/src/functions/render.js +5 -0
  8. package/src/generators/output/to-disk.js +120 -79
  9. package/src/generators/output/to-string.js +7 -8
  10. package/src/generators/plaintext.js +49 -52
  11. package/src/generators/postcss.js +29 -0
  12. package/src/generators/posthtml.js +66 -60
  13. package/src/generators/tailwindcss.js +116 -84
  14. package/src/index.js +14 -160
  15. package/src/transformers/{attribute-to-style.js → attributeToStyle.js} +0 -0
  16. package/src/transformers/baseUrl.js +69 -0
  17. package/src/transformers/{extra-attributes.js → extraAttributes.js} +0 -0
  18. package/src/transformers/filters/defaultFilters.js +126 -0
  19. package/src/transformers/filters/index.js +55 -0
  20. package/src/transformers/index.js +63 -57
  21. package/src/transformers/{inline.js → inlineCss.js} +1 -14
  22. package/src/transformers/minify.js +1 -1
  23. package/src/transformers/{posthtml-mso.js → posthtmlMso.js} +0 -0
  24. package/src/transformers/prettify.js +16 -9
  25. package/src/transformers/{prevent-widows.js → preventWidows.js} +0 -0
  26. package/src/transformers/{remove-attributes.js → removeAttributes.js} +1 -1
  27. package/src/transformers/{remove-inline-bgcolor.js → removeInlineBackgroundColor.js} +1 -1
  28. package/src/transformers/{remove-inline-sizes.js → removeInlineSizes.js} +0 -0
  29. package/src/transformers/removeInlinedSelectors.js +70 -0
  30. package/src/transformers/removeUnusedCss.js +40 -0
  31. package/src/transformers/{replace-strings.js → replaceStrings.js} +0 -0
  32. package/src/transformers/{safe-class-names.js → safeClassNames.js} +8 -2
  33. package/src/transformers/shorthandInlineCSS.js +19 -0
  34. package/src/transformers/sixHex.js +33 -0
  35. package/src/transformers/{url-params.js → urlParameters.js} +0 -0
  36. package/src/utils/helpers.js +2 -8
  37. package/test/expected/posthtml/component.html +13 -0
  38. package/test/expected/{inheritance.html → posthtml/extend-template.html} +2 -2
  39. package/test/expected/posthtml/fetch.html +5 -0
  40. package/test/expected/posthtml/layout.html +3 -0
  41. package/test/expected/transformers/atimport-in-style.html +15 -0
  42. package/test/expected/transformers/base-url.html +99 -0
  43. package/test/expected/transformers/filters.html +81 -0
  44. package/test/expected/transformers/preserve-transform-css.html +36 -0
  45. package/test/expected/useConfig.html +9 -0
  46. package/test/fixtures/basic.html +9 -9
  47. package/test/fixtures/posthtml/component.html +19 -0
  48. package/test/fixtures/{inheritance.html → posthtml/extend-template.html} +7 -7
  49. package/test/fixtures/posthtml/fetch.html +9 -0
  50. package/test/fixtures/posthtml/layout.html +11 -0
  51. package/test/fixtures/transformers/atimport-in-style.html +11 -0
  52. package/test/fixtures/transformers/base-url.html +101 -0
  53. package/test/fixtures/transformers/filters.html +87 -0
  54. package/test/fixtures/transformers/preserve-transform-css.html +25 -0
  55. package/test/fixtures/useConfig.html +9 -0
  56. package/test/stubs/components/component.html +5 -0
  57. package/test/stubs/data.json +14 -0
  58. package/test/stubs/layouts/basic.html +1 -0
  59. package/test/stubs/{layout.html → layouts/full.html} +0 -0
  60. package/test/stubs/{layout-basic.html → layouts/template.html} +5 -5
  61. package/test/stubs/post.css +6 -0
  62. package/test/stubs/tailwind/content-source.html +1 -0
  63. package/test/stubs/tailwind/tailwind.css +3 -0
  64. package/test/stubs/template.html +10 -10
  65. package/test/stubs/templates/1.html +1 -1
  66. package/test/stubs/templates/2.test +1 -0
  67. package/test/test-config.js +19 -19
  68. package/test/test-misc.js +8 -8
  69. package/test/test-postcss.js +8 -0
  70. package/test/test-posthtml.js +72 -0
  71. package/test/test-tailwindcss.js +117 -0
  72. package/test/test-todisk.js +142 -49
  73. package/test/test-tostring.js +148 -124
  74. package/test/test-transformers.js +510 -320
  75. package/xo.config.js +22 -19
  76. package/src/transformers/base-image-url.js +0 -9
  77. package/src/transformers/remove-unused-css.js +0 -20
  78. package/src/transformers/six-hex.js +0 -10
  79. package/src/transformers/transform.js +0 -24
  80. package/test/expected/transformers/base-image-url.html +0 -7
  81. package/test/fixtures/transformers/base-image-url.html +0 -7
  82. package/test/stubs/templates/2.html +0 -1
  83. package/test/stubs/templates/3.mzl +0 -1
  84. package/test/test-tailwind.js +0 -73
@@ -1,29 +1,28 @@
1
- # This workflow will do a clean install of node dependencies, build the source code and run tests across different versions of node
2
- # For more information see: https://help.github.com/actions/language-and-framework-guides/using-nodejs-with-github-actions
3
-
4
- name: Node.js CI
5
-
6
- on:
7
- push:
8
- branches: [master]
9
- pull_request:
10
- branches: [master]
11
-
12
- jobs:
13
- build:
14
- runs-on: ubuntu-latest
15
-
16
- strategy:
17
- matrix:
18
- node-version: [12, 14, 16]
19
-
20
- steps:
21
- - uses: actions/checkout@v2
22
- - name: Use Node.js ${{ matrix.node-version }}
23
- uses: actions/setup-node@v1
24
- with:
25
- node-version: ${{ matrix.node-version }}
26
- - run: npm install
27
- - run: npm test
28
- env:
29
- CI: true
1
+ # This workflow will do a clean install of node dependencies, build the source code and run tests across different versions of node
2
+ # For more information see: https://help.github.com/actions/language-and-framework-guides/using-nodejs-with-github-actions
3
+
4
+ name: Node.js CI
5
+
6
+ on:
7
+ push:
8
+ branches: [master]
9
+ pull_request:
10
+
11
+ jobs:
12
+ build:
13
+ runs-on: ubuntu-latest
14
+
15
+ strategy:
16
+ matrix:
17
+ node-version: [14, 16, 17]
18
+
19
+ steps:
20
+ - uses: actions/checkout@v2
21
+ - name: Use Node.js ${{ matrix.node-version }}
22
+ uses: actions/setup-node@v1
23
+ with:
24
+ node-version: ${{ matrix.node-version }}
25
+ - run: npm install
26
+ - run: npm test
27
+ env:
28
+ CI: true
package/bin/maizzle ADDED
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+
3
+ require('@maizzle/cli')
package/package.json CHANGED
@@ -1,84 +1,91 @@
1
- {
2
- "name": "@maizzle/framework",
3
- "version": "3.7.2",
4
- "description": "Maizzle is a framework that helps you quickly build HTML emails with Tailwind CSS.",
5
- "license": "MIT",
6
- "main": "src/index.js",
7
- "repository": {
8
- "type": "git",
9
- "url": "https://github.com/maizzle/framework.git"
10
- },
11
- "bugs": "https://github.com/maizzle/framework/issues",
12
- "homepage": "https://maizzle.com",
13
- "author": "Cosmin Popovici (https://github.com/cossssmin)",
14
- "keywords": [
15
- "maizzle",
16
- "tailwindcss",
17
- "responsive-email",
18
- "email-framework",
19
- "email-template",
20
- "email-marketing",
21
- "email-campaigns",
22
- "email-newsletter",
23
- "email-boilerplate",
24
- "html-emails"
25
- ],
26
- "publishConfig": {
27
- "access": "public"
28
- },
29
- "scripts": {
30
- "test": "xo && nyc ava -s",
31
- "style": "xo",
32
- "release": "np"
33
- },
34
- "dependencies": {
35
- "browser-sync": "^2.26.13",
36
- "color-shorthand-hex-to-six-digit": "^3.0.2",
37
- "email-comb": "^5.0.0",
38
- "front-matter": "^4.0.0",
39
- "fs-extra": "^10.0.0",
40
- "glob-promise": "^4.1.0",
41
- "html-crush": "^4.0.0",
42
- "juice": "^8.0.0",
43
- "lodash": "^4.17.20",
44
- "ora": "^5.1.0",
45
- "postcss": "^8.2.14",
46
- "postcss-import": "^14.0.0",
47
- "postcss-merge-longhand": "^5.0.1",
48
- "posthtml": "^0.16.4",
49
- "posthtml-attrs-parser": "^0.1.1",
50
- "posthtml-content": "^0.0.3",
51
- "posthtml-expressions": "^1.8.1",
52
- "posthtml-extend": "^0.6.0",
53
- "posthtml-extra-attributes": "^1.0.0",
54
- "posthtml-fetch": "^2.0.0",
55
- "posthtml-markdownit": "^1.2.2",
56
- "posthtml-modules": "^0.7.4",
57
- "posthtml-mso": "^1.0.2",
58
- "posthtml-postcss-merge-longhand": "^1.0.2",
59
- "posthtml-remove-attributes": "^1.0.0",
60
- "posthtml-safe-class-names": "^1.0.4",
61
- "posthtml-url-parameters": "^1.0.4",
62
- "pretty": "^2.0.0",
63
- "prevent-widows": "^1.0.2",
64
- "query-string": "^7.0.0",
65
- "string-strip-html": "^8.2.0",
66
- "tailwindcss": "^2.2.2",
67
- "tailwindcss-box-shadow": "^1.0.0"
68
- },
69
- "devDependencies": {
70
- "autoprefixer": "^10.0.2",
71
- "ava": "^3.13.0",
72
- "np": "*",
73
- "nyc": "^15.1.0",
74
- "xo": "0.39.1"
75
- },
76
- "engines": {
77
- "node": ">=12.13.0"
78
- },
79
- "ava": {
80
- "files": [
81
- "test/**/test*.js"
82
- ]
83
- }
84
- }
1
+ {
2
+ "name": "@maizzle/framework",
3
+ "version": "4.0.0-alpha.10",
4
+ "description": "Maizzle is a framework that helps you quickly build HTML emails with Tailwind CSS.",
5
+ "license": "MIT",
6
+ "main": "src/index.js",
7
+ "bin": {
8
+ "maizzle": "bin/maizzle"
9
+ },
10
+ "repository": {
11
+ "type": "git",
12
+ "url": "https://github.com/maizzle/framework.git"
13
+ },
14
+ "bugs": "https://github.com/maizzle/framework/issues",
15
+ "homepage": "https://maizzle.com",
16
+ "author": "Cosmin Popovici (https://github.com/cossssmin)",
17
+ "keywords": [
18
+ "maizzle",
19
+ "tailwindcss",
20
+ "responsive-email",
21
+ "email-framework",
22
+ "email-template",
23
+ "email-marketing",
24
+ "email-campaigns",
25
+ "email-newsletter",
26
+ "email-boilerplate",
27
+ "html-emails"
28
+ ],
29
+ "publishConfig": {
30
+ "access": "public"
31
+ },
32
+ "scripts": {
33
+ "test": "c8 ava -s",
34
+ "pretest": "xo",
35
+ "style": "xo",
36
+ "release": "np"
37
+ },
38
+ "dependencies": {
39
+ "@maizzle/cli": "^1.4.0",
40
+ "autoprefixer": "^10.4.0",
41
+ "browser-sync": "^2.26.13",
42
+ "color-shorthand-hex-to-six-digit": "^3.0.2",
43
+ "email-comb": "^5.2.0",
44
+ "front-matter": "^4.0.0",
45
+ "fs-extra": "^10.0.0",
46
+ "glob-promise": "^4.1.0",
47
+ "html-crush": "^4.0.0",
48
+ "is-url-superb": "^5.0.0",
49
+ "juice": "^8.0.0",
50
+ "lodash": "^4.17.20",
51
+ "ora": "^5.1.0",
52
+ "postcss": "^8.4.4",
53
+ "postcss-import": "^14.0.0",
54
+ "postcss-merge-longhand": "^5.0.1",
55
+ "posthtml": "^0.16.6",
56
+ "posthtml-attrs-parser": "^0.1.1",
57
+ "posthtml-base-url": "^1.0.1",
58
+ "posthtml-content": "^0.1.0",
59
+ "posthtml-expressions": "^1.8.1",
60
+ "posthtml-extend": "^0.6.0",
61
+ "posthtml-extra-attributes": "^1.0.0",
62
+ "posthtml-fetch": "^2.2.0",
63
+ "posthtml-markdownit": "^1.3.0",
64
+ "posthtml-match-helper": "^1.0.3",
65
+ "posthtml-modules": "^0.9.0",
66
+ "posthtml-mso": "^1.0.4",
67
+ "posthtml-postcss-merge-longhand": "^1.0.2",
68
+ "posthtml-remove-attributes": "^1.0.0",
69
+ "posthtml-safe-class-names": "^1.0.8",
70
+ "posthtml-url-parameters": "^1.0.4",
71
+ "pretty": "^2.0.0",
72
+ "prevent-widows": "^1.0.2",
73
+ "query-string": "^7.1.0",
74
+ "string-strip-html": "^8.2.0",
75
+ "tailwindcss": "^3.0.0"
76
+ },
77
+ "devDependencies": {
78
+ "ava": "^4.0.1",
79
+ "c8": "^7.11.0",
80
+ "np": "*",
81
+ "xo": "0.39.1"
82
+ },
83
+ "engines": {
84
+ "node": ">=14.0.0"
85
+ },
86
+ "ava": {
87
+ "files": [
88
+ "test/**/test*.js"
89
+ ]
90
+ }
91
+ }
@@ -0,0 +1,32 @@
1
+ const ora = require('ora')
2
+ const {get} = require('lodash')
3
+ const Output = require('../generators/output')
4
+ const {clearConsole} = require('../utils/helpers')
5
+
6
+ const build = async (env = 'local', config = {}) => {
7
+ const start = new Date()
8
+ const spinner = ora('Building emails...').start()
9
+
10
+ try {
11
+ const {files, parsed} = await Output.toDisk(env, spinner, config)
12
+
13
+ const elapsedSeconds = (Date.now() - start) / 1000
14
+
15
+ if (get(config, 'build.command') === 'serve') {
16
+ if (get(config, 'build.console.clear')) {
17
+ clearConsole()
18
+ }
19
+
20
+ spinner.succeed(`Re-built ${parsed.length} templates in ${elapsedSeconds}s`)
21
+ } else {
22
+ spinner.succeed(`Built ${parsed.length} templates in ${elapsedSeconds}s`)
23
+ }
24
+
25
+ return {files}
26
+ } catch (error) {
27
+ spinner.fail(error.message)
28
+ throw error
29
+ }
30
+ }
31
+
32
+ module.exports = build
@@ -0,0 +1,156 @@
1
+ const ora = require('ora')
2
+ const path = require('path')
3
+ const fs = require('fs-extra')
4
+
5
+ const Config = require('../generators/config')
6
+ const buildToFile = require('../commands/build')
7
+ const renderToString = require('../functions/render')
8
+
9
+ const {get, merge, isObject} = require('lodash')
10
+ const {clearConsole} = require('../utils/helpers')
11
+
12
+ const browsersync = () => {
13
+ if (!global.cachedBrowserSync) {
14
+ const bs = require('browser-sync')
15
+ global.cachedBrowserSync = bs.create()
16
+ }
17
+
18
+ return global.cachedBrowserSync
19
+ }
20
+
21
+ const serve = async (env = 'local', config = {}) => {
22
+ config = merge(
23
+ config,
24
+ await Config.getMerged(env),
25
+ {
26
+ build: {
27
+ command: 'serve'
28
+ }
29
+ }
30
+ )
31
+
32
+ const spinner = ora()
33
+
34
+ try {
35
+ await buildToFile(env, config)
36
+
37
+ let templates = get(config, 'build.templates')
38
+ templates = Array.isArray(templates) ? templates : [templates]
39
+
40
+ const templatePaths = [...new Set(templates.map(config => `${get(config, 'source', 'src')}/**`))]
41
+ const globalPaths = [
42
+ 'src/**',
43
+ get(config, 'build.tailwind.config', 'tailwind.config.js'),
44
+ ...new Set(get(config, 'build.browsersync.watch', []))
45
+ ]
46
+
47
+ // Watch for Template file changes
48
+ browsersync()
49
+ .watch(templatePaths)
50
+ .on('change', async file => {
51
+ if (config.events && typeof config.events.beforeCreate === 'function') {
52
+ await config.events.beforeCreate(config)
53
+ }
54
+
55
+ // Don't render if file type is not configured
56
+ // eslint-disable-next-line
57
+ const filetypes = templates.reduce((acc, template) => {
58
+ return [...acc, ...get(template, 'filetypes', ['html'])]
59
+ }, [])
60
+
61
+ if (!filetypes.includes(path.extname(file).slice(1))) {
62
+ return
63
+ }
64
+
65
+ if (get(config, 'build.console.clear')) {
66
+ clearConsole()
67
+ }
68
+
69
+ const start = new Date()
70
+
71
+ spinner.start('Building email...')
72
+
73
+ file = file.replace(/\\/g, '/')
74
+
75
+ const renderOptions = {
76
+ maizzle: config,
77
+ ...config.events
78
+ }
79
+
80
+ renderToString(
81
+ await fs.readFile(file, 'utf8'),
82
+ renderOptions
83
+ )
84
+ .then(async ({html, config}) => {
85
+ let source = ''
86
+ let dest = ''
87
+ let ext = ''
88
+
89
+ if (Array.isArray(config.build.templates)) {
90
+ const match = config.build.templates.find(template => template.source === path.parse(file).dir)
91
+ source = get(match, 'source')
92
+ dest = get(match, 'destination.path', 'build_local')
93
+ ext = get(match, 'destination.ext', 'html')
94
+ } else if (isObject(config.build.templates)) {
95
+ source = get(config, 'build.templates.source')
96
+ dest = get(config, 'build.templates.destination.path', 'build_local')
97
+ ext = get(config, 'build.templates.destination.ext', 'html')
98
+ }
99
+
100
+ const fileDir = path.parse(file).dir.replace(source, '')
101
+ const finalDestination = path.join(dest, fileDir, `${path.parse(file).name}.${ext}`)
102
+
103
+ await fs.outputFile(config.permalink || finalDestination, html)
104
+ })
105
+ .then(() => {
106
+ browsersync().reload()
107
+ spinner.succeed(`Compiled in ${(Date.now() - start) / 1000}s [${file}]`)
108
+ })
109
+ .catch(() => spinner.warn(`Received empty HTML, please save your file again [${file}]`))
110
+ })
111
+
112
+ // Watch for changes in all other files
113
+ browsersync()
114
+ .watch(globalPaths, {ignored: templatePaths})
115
+ .on('change', () => buildToFile(env, config).then(() => browsersync().reload()))
116
+ .on('unlink', () => buildToFile(env, config).then(() => browsersync().reload()))
117
+
118
+ // Watch for changes in config files
119
+ browsersync()
120
+ .watch('config*.js')
121
+ .on('change', async file => {
122
+ const parsedEnv = path.parse(file).name.split('.')[1] || 'local'
123
+
124
+ Config
125
+ .getMerged(parsedEnv)
126
+ .then(config => buildToFile(parsedEnv, config).then(() => browsersync().reload()))
127
+ })
128
+
129
+ // Browsersync options
130
+ const baseDir = templates.map(t => t.destination.path)
131
+
132
+ // Initialize Browsersync
133
+ browsersync()
134
+ .init(
135
+ merge(
136
+ {
137
+ notify: false,
138
+ open: false,
139
+ port: 3000,
140
+ server: {
141
+ baseDir,
142
+ directory: true
143
+ },
144
+ tunnel: false,
145
+ ui: {port: 3001},
146
+ logFileChanges: false
147
+ },
148
+ get(config, 'build.browsersync', {})
149
+ ), () => {})
150
+ } catch (error) {
151
+ spinner.fail(error)
152
+ throw error
153
+ }
154
+ }
155
+
156
+ module.exports = serve
@@ -0,0 +1,5 @@
1
+ const Plaintext = require('../generators/plaintext')
2
+
3
+ const toPlaintext = async (html, config = {}) => Plaintext.generate(html, false, config)
4
+
5
+ module.exports = toPlaintext
@@ -0,0 +1,5 @@
1
+ const Output = require('../generators/output')
2
+
3
+ const render = async (html, options) => Output.toString(html, options)
4
+
5
+ module.exports = render