@newlogic-digital/core 2.0.0-alpha.5 → 2.0.0-alpha.7

Sign up to get free protection for your applications and to get access to all the features.
package/index.js CHANGED
@@ -5,12 +5,14 @@ import postHtml from 'posthtml'
5
5
  import vituum from 'vituum'
6
6
  import posthtml from '@vituum/vite-plugin-posthtml'
7
7
  import latte from '@vituum/vite-plugin-latte'
8
+ import twig from '@vituum/vite-plugin-twig'
8
9
  import juice from '@vituum/vite-plugin-juice'
9
10
  import send from '@vituum/vite-plugin-send'
10
11
  import tailwindcss from '@vituum/vite-plugin-tailwindcss'
11
12
  import { getPackageInfo, merge } from 'vituum/utils/common.js'
12
- import minifier from 'html-minifier-terser'
13
- import highlight from './prism.js'
13
+ import parseMinifyHtml from './src/minify.js'
14
+ import highlight from './src/prism.js'
15
+ import twigOptions from './src/twig.js'
14
16
 
15
17
  const { name } = getPackageInfo(import.meta.url)
16
18
 
@@ -35,25 +37,6 @@ const posthtmlPrism = {
35
37
  }
36
38
  }
37
39
 
38
- const parseMinifyHtml = async (input, name) => {
39
- const minify = await minifier.minify(input, {
40
- collapseWhitespace: true,
41
- collapseInlineTagWhitespace: false,
42
- minifyCSS: true,
43
- removeAttributeQuotes: true,
44
- quoteCharacter: '\'',
45
- minifyJS: true
46
- })
47
-
48
- if (name) {
49
- return JSON.stringify({
50
- [name]: minify
51
- })
52
- } else {
53
- return JSON.stringify(minify)
54
- }
55
- }
56
-
57
40
  /**
58
41
  * @type {import('@newlogic-digital/core/types').PluginUserConfig}
59
42
  */
@@ -98,7 +81,8 @@ const defaultOptions = {
98
81
  code: 'node_modules/@newlogic-digital/core/latte/CodeFilter.php'
99
82
  },
100
83
  ignoredPaths: ['**/views/email/**/!(*.test).latte', '**/emails/!(*.test).latte']
101
- }
84
+ },
85
+ twig: twigOptions
102
86
  }
103
87
 
104
88
  /**
@@ -113,6 +97,7 @@ const plugin = (options = {}) => {
113
97
  tailwindcss(options.tailwindcss),
114
98
  posthtml(options.posthtml),
115
99
  latte(options.latte),
100
+ twig(options.twig),
116
101
  juice(options.juice),
117
102
  send(options.send),
118
103
  posthtmlPrism
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@newlogic-digital/core",
3
3
  "type": "module",
4
- "version": "2.0.0-alpha.5",
4
+ "version": "2.0.0-alpha.7",
5
5
  "main": "index.js",
6
6
  "author": "New Logic Studio s.r.o.",
7
7
  "description": "Set of tools that can be used to create modern web applications",
@@ -14,6 +14,7 @@
14
14
  "@vituum/vite-plugin-posthtml": "^1.0.0-alpha.3",
15
15
  "@vituum/vite-plugin-juice": "^1.0.0-alpha.2",
16
16
  "@vituum/vite-plugin-latte": "^1.0.0-alpha.5",
17
+ "@vituum/vite-plugin-twig": "^1.0.0-alpha.4",
17
18
  "@vituum/vite-plugin-tailwindcss": "^1.0.0-alpha.2",
18
19
  "@vituum/vite-plugin-send": "^1.0.0-alpha.2",
19
20
  "vituum": "^1.0.0-alpha.18",
@@ -33,7 +34,7 @@
33
34
  "files": [
34
35
  "latte",
35
36
  "index.js",
36
- "prism.js"
37
+ "src"
37
38
  ],
38
39
  "engines": {
39
40
  "node": ">=16.0.0",
package/src/minify.js ADDED
@@ -0,0 +1,22 @@
1
+ import minifier from 'html-minifier-terser'
2
+
3
+ const parseMinifyHtml = async (input, name) => {
4
+ const minify = await minifier.minify(input, {
5
+ collapseWhitespace: true,
6
+ collapseInlineTagWhitespace: false,
7
+ minifyCSS: true,
8
+ removeAttributeQuotes: true,
9
+ quoteCharacter: '\'',
10
+ minifyJS: true
11
+ })
12
+
13
+ if (name) {
14
+ return JSON.stringify({
15
+ [name]: minify
16
+ })
17
+ } else {
18
+ return JSON.stringify(minify)
19
+ }
20
+ }
21
+
22
+ export default parseMinifyHtml
package/src/twig.js ADDED
@@ -0,0 +1,174 @@
1
+ import fs from 'fs'
2
+ import { resolve } from 'path'
3
+ import parseMinifyHtml from './minify.js'
4
+
5
+ const wrapPreCode = (code, lang) => {
6
+ return `<pre class="language-${lang}"><code class="language-${lang}">${code}</code></pre>`
7
+ }
8
+
9
+ const stripIndent = (string) => {
10
+ const indent = () => {
11
+ const match = string.match(/^[ \t]*(?=\S)/gm)
12
+
13
+ if (!match) {
14
+ return 0
15
+ }
16
+
17
+ return match.reduce((r, a) => Math.min(r, a.length), Infinity)
18
+ }
19
+
20
+ if (indent() === 0) {
21
+ return string
22
+ }
23
+
24
+ const regex = new RegExp(`^[ \\t]{${indent()}}`, 'gm')
25
+
26
+ return string.replace(regex, '')
27
+ }
28
+
29
+ export default {
30
+ namespaces: {
31
+ src: resolve(process.cwd(), 'src'),
32
+ templates: resolve(process.cwd(), 'src/templates')
33
+ },
34
+ functions: {
35
+ pages: () => {
36
+ return fs.readdirSync('src/views').filter(file => fs.statSync('src/views/' + file).isFile())
37
+ },
38
+ fetch: (data) => {
39
+ if (typeof data !== 'undefined') {
40
+ if (data.indexOf('http') > -1) {
41
+ return data
42
+ } else {
43
+ let slash = data.indexOf('/') + 1
44
+ if (slash > 1) {
45
+ slash = 0
46
+ }
47
+
48
+ return fs.readFileSync(process.cwd() + '/' + data.substring(slash, data.length), 'utf8').toString()
49
+ }
50
+ }
51
+ },
52
+ randomColor: () => {
53
+ return '#' + Math.random().toString(16).slice(2, 8)
54
+ },
55
+ placeholder: (width, height) => {
56
+ const colors = ['333', '444', '666', '222', '777', '888', '111']
57
+ return 'https://via.placeholder.com/' + width + 'x' + height + '/' + colors[Math.floor(Math.random() * colors.length)] + '.webp'
58
+ },
59
+ lazy: (width, height) => {
60
+ const svg = encodeURIComponent(stripIndent('<svg width="' + width + '" height="' + height + '" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 ' + width + ' ' + height + '"></svg>'))
61
+
62
+ return 'data:image/svg+xml;charset=UTF-8,' + svg
63
+ },
64
+ ratio: (width, height) => {
65
+ return (height / width) * 100
66
+ }
67
+ },
68
+ filters: {
69
+ asset: (url) => {
70
+ return url.replace('/src/', '/')
71
+ },
72
+ rem: (value) => {
73
+ return `${value / 16}rem`
74
+ },
75
+ encode64: (path) => {
76
+ const svg = encodeURIComponent(stripIndent(path))
77
+
78
+ return 'data:image/svg+xml;charset=UTF-8,' + svg
79
+ },
80
+ exists: (path) => {
81
+ if (path.indexOf('/') === 0) {
82
+ path = path.slice(1)
83
+ }
84
+
85
+ return fs.existsSync(resolve(process.cwd(), path))
86
+ },
87
+ tel: (value) => {
88
+ return value.replace(/\s+/g, '').replace('(', '').replace(')', '')
89
+ }
90
+ },
91
+ extensions: [
92
+ (Twig) => {
93
+ Twig.exports.extendTag({
94
+ type: 'json',
95
+ regex: /^json\s+(.+)$|^json$/,
96
+ next: ['endjson'],
97
+ open: true,
98
+ compile: function (token) {
99
+ const expression = token.match[1] ?? '\'_null\''
100
+
101
+ token.stack = Reflect.apply(Twig.expression.compile, this, [{
102
+ type: Twig.expression.type.expression,
103
+ value: expression
104
+ }]).stack
105
+
106
+ delete token.match
107
+ return token
108
+ },
109
+ parse: async function (token, context, chain) {
110
+ const name = Reflect.apply(Twig.expression.parse, this, [token.stack, context])
111
+ const output = this.parse(token.output, context)
112
+
113
+ if (name === '_null') {
114
+ return {
115
+ chain,
116
+ output: await parseMinifyHtml(output)
117
+ }
118
+ } else {
119
+ return {
120
+ chain,
121
+ output: await parseMinifyHtml(output, name)
122
+ }
123
+ }
124
+ }
125
+ })
126
+ Twig.exports.extendTag({
127
+ type: 'endjson',
128
+ regex: /^endjson$/,
129
+ next: [],
130
+ open: false
131
+ })
132
+ },
133
+ (Twig) => {
134
+ Twig.exports.extendTag({
135
+ type: 'code',
136
+ regex: /^code\s+(.+)$/,
137
+ next: ['endcode'], // match the type of the end tag
138
+ open: true,
139
+ compile: function (token) {
140
+ const expression = token.match[1]
141
+
142
+ token.stack = Reflect.apply(Twig.expression.compile, this, [{
143
+ type: Twig.expression.type.expression,
144
+ value: expression
145
+ }]).stack
146
+
147
+ delete token.match
148
+ return token
149
+ },
150
+ parse: function (token, context, chain) {
151
+ let type = Reflect.apply(Twig.expression.parse, this, [token.stack, context])
152
+ const output = this.parse(token.output, context)
153
+ let mirror = false
154
+
155
+ if (type.includes(':mirror')) {
156
+ mirror = true
157
+ type = type.replace(':mirror', '')
158
+ }
159
+
160
+ return {
161
+ chain,
162
+ output: `${mirror ? output : ''}${wrapPreCode(output, type)}`
163
+ }
164
+ }
165
+ })
166
+ Twig.exports.extendTag({
167
+ type: 'endcode',
168
+ regex: /^endcode$/,
169
+ next: [],
170
+ open: false
171
+ })
172
+ }
173
+ ]
174
+ }
File without changes