@newlogic-digital/core 2.0.0-alpha.6 → 2.0.0-alpha.7
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 +2 -2
- package/src/minify.js +22 -0
- package/src/twig.js +174 -0
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.
|
|
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",
|
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
"files": [
|
|
35
35
|
"latte",
|
|
36
36
|
"index.js",
|
|
37
|
-
"src
|
|
37
|
+
"src"
|
|
38
38
|
],
|
|
39
39
|
"engines": {
|
|
40
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
|
+
}
|