@newlogic-digital/core 3.1.1 → 4.0.0-next.2
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/index.js +192 -174
- package/latte/JsonFilter.js +1 -1
- package/package.json +13 -21
- package/src/minify.js +16 -15
- package/src/twig.js +150 -147
- package/types/index.d.ts +7 -7
- package/src/prism.js +0 -90
package/index.js
CHANGED
|
@@ -10,6 +10,7 @@ import twigOptions from './src/twig.js'
|
|
|
10
10
|
import browserslistToEsbuild from 'browserslist-to-esbuild'
|
|
11
11
|
import browserslist from 'browserslist'
|
|
12
12
|
import { Features as LightningCssFeatures, browserslistToTargets } from 'lightningcss'
|
|
13
|
+
import process from 'node:process'
|
|
13
14
|
|
|
14
15
|
const { name } = getPackageInfo(import.meta.url)
|
|
15
16
|
|
|
@@ -17,62 +18,62 @@ const { name } = getPackageInfo(import.meta.url)
|
|
|
17
18
|
* @type {import('@newlogic-digital/core/types').PluginUserConfig}
|
|
18
19
|
*/
|
|
19
20
|
const defaultOptions = {
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
21
|
+
mode: null,
|
|
22
|
+
cert: 'localhost',
|
|
23
|
+
format: ['latte'],
|
|
24
|
+
advancedChunks: {},
|
|
25
|
+
input: {
|
|
26
|
+
assets: [
|
|
27
|
+
'./src/styles/*.{css,pcss,scss,sass,less,styl,stylus}',
|
|
28
|
+
'./src/scripts/*.{js,ts,mjs}',
|
|
29
|
+
],
|
|
30
|
+
pages: [
|
|
31
|
+
'./src/pages/**/*.{json,latte,twig,liquid,njk,hbs,pug,html}',
|
|
32
|
+
'!./src/pages/**/*.{latte,twig,liquid,njk,hbs,pug,html}.json',
|
|
33
|
+
'!./src/pages/email/**/*',
|
|
34
|
+
],
|
|
35
|
+
emails: [
|
|
36
|
+
'./src/pages/email/**/*.{json,latte,twig,liquid,njk,hbs,pug,html}',
|
|
37
|
+
'./src/styles/emails/*.{css,pcss,scss,sass,less,styl,stylus}',
|
|
38
|
+
'!./src/pages/email/**/*.{latte,twig,liquid,njk,hbs,pug,html}.json',
|
|
39
|
+
],
|
|
40
|
+
},
|
|
41
|
+
vituum: {
|
|
42
|
+
imports: {
|
|
43
|
+
paths: ['./src/styles/*/**', '!./src/styles/emails/*', './src/scripts/*/**'],
|
|
39
44
|
},
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
45
|
+
},
|
|
46
|
+
juice: {
|
|
47
|
+
paths: ['src/pages/email'],
|
|
48
|
+
postcss: {
|
|
49
|
+
globalData: {
|
|
50
|
+
files: ['./src/styles/emails/theme/config.css'],
|
|
51
|
+
},
|
|
44
52
|
},
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
53
|
+
},
|
|
54
|
+
css: {
|
|
55
|
+
transformer: 'postcss',
|
|
56
|
+
lightningcss: {},
|
|
57
|
+
},
|
|
58
|
+
tailwindcss: {},
|
|
59
|
+
send: {},
|
|
60
|
+
latte: {
|
|
61
|
+
globals: {
|
|
62
|
+
srcPath: resolve(process.cwd(), 'src'),
|
|
63
|
+
templatesPath: resolve(process.cwd(), 'src/templates'),
|
|
64
|
+
template: './src/templates/layouts/default.latte',
|
|
52
65
|
},
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
66
|
+
functions: {
|
|
67
|
+
pages: () => {
|
|
68
|
+
return fs.readdirSync(resolve(process.cwd(), 'src/pages')).filter(file => fs.statSync(resolve(process.cwd(), 'src/pages/' + file)).isFile())
|
|
69
|
+
},
|
|
56
70
|
},
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
globals: {
|
|
61
|
-
srcPath: resolve(process.cwd(), 'src'),
|
|
62
|
-
templatesPath: resolve(process.cwd(), 'src/templates'),
|
|
63
|
-
template: './src/templates/layouts/default.latte'
|
|
64
|
-
},
|
|
65
|
-
functions: {
|
|
66
|
-
pages: () => {
|
|
67
|
-
return fs.readdirSync(resolve(process.cwd(), 'src/pages')).filter(file => fs.statSync(resolve(process.cwd(), 'src/pages/' + file)).isFile())
|
|
68
|
-
}
|
|
69
|
-
},
|
|
70
|
-
filters: {
|
|
71
|
-
json: resolve(process.cwd(), 'node_modules/@newlogic-digital/core/latte/JsonFilter.js'),
|
|
72
|
-
code: 'node_modules/@newlogic-digital/core/latte/CodeFilter.php'
|
|
73
|
-
}
|
|
71
|
+
filters: {
|
|
72
|
+
json: resolve(process.cwd(), 'node_modules/@newlogic-digital/core/latte/JsonFilter.js'),
|
|
73
|
+
code: 'node_modules/@newlogic-digital/core/latte/CodeFilter.php',
|
|
74
74
|
},
|
|
75
|
-
|
|
75
|
+
},
|
|
76
|
+
twig: twigOptions,
|
|
76
77
|
}
|
|
77
78
|
|
|
78
79
|
/**
|
|
@@ -80,145 +81,162 @@ const defaultOptions = {
|
|
|
80
81
|
* @returns [import('vite').Plugin]
|
|
81
82
|
*/
|
|
82
83
|
const plugin = async (options = {}) => {
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
const templatesPlugins = []
|
|
86
|
-
const tailwindcssPlugin = []
|
|
84
|
+
options = merge(defaultOptions, options)
|
|
87
85
|
|
|
88
|
-
|
|
89
|
-
|
|
86
|
+
const templatesPlugins = []
|
|
87
|
+
const tailwindcssPlugin = []
|
|
90
88
|
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
if (options.format.includes('latte')) {
|
|
95
|
-
templatesPlugins.push(latte(options.latte))
|
|
96
|
-
}
|
|
89
|
+
if (options.format.includes('twig')) {
|
|
90
|
+
const twig = (await import('@vituum/vite-plugin-twig')).default
|
|
97
91
|
|
|
98
|
-
|
|
99
|
-
|
|
92
|
+
templatesPlugins.push(twig(options.twig))
|
|
93
|
+
}
|
|
100
94
|
|
|
101
|
-
|
|
102
|
-
|
|
95
|
+
if (options.format.includes('latte')) {
|
|
96
|
+
templatesPlugins.push(latte(options.latte))
|
|
97
|
+
}
|
|
103
98
|
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
fs.writeFileSync(resolve(process.cwd(), 'src/+.css'), '@import "./styles/main.css";')
|
|
107
|
-
}
|
|
99
|
+
if (options.css.transformer === 'postcss') {
|
|
100
|
+
const tailwindcss = (await import('@vituum/vite-plugin-tailwindcss')).default
|
|
108
101
|
|
|
109
|
-
|
|
110
|
-
|
|
102
|
+
tailwindcssPlugin.push(tailwindcss(options.tailwindcss))
|
|
103
|
+
}
|
|
111
104
|
|
|
112
|
-
|
|
105
|
+
if (options.css.transformer === 'lightningcss') {
|
|
106
|
+
if (!fs.existsSync(resolve(process.cwd(), 'src/+.css'))) {
|
|
107
|
+
fs.writeFileSync(resolve(process.cwd(), 'src/+.css'), '@import "./styles/main.css";')
|
|
113
108
|
}
|
|
114
109
|
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
110
|
+
// @ts-ignore
|
|
111
|
+
const tailwindcss = (await import('@tailwindcss/vite')).default
|
|
112
|
+
|
|
113
|
+
tailwindcssPlugin.push(tailwindcss(options.tailwindcss))
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
const plugins = [
|
|
117
|
+
vituum(options.vituum),
|
|
118
|
+
...tailwindcssPlugin,
|
|
119
|
+
...templatesPlugins,
|
|
120
|
+
juice(options.juice),
|
|
121
|
+
send(options.send),
|
|
122
|
+
]
|
|
123
|
+
|
|
124
|
+
return [{
|
|
125
|
+
name,
|
|
126
|
+
enforce: 'pre',
|
|
127
|
+
/**
|
|
128
|
+
* @param {import('vite').UserConfig} userConfig
|
|
129
|
+
* @param {import('vite').ConfigEnv} userEnv
|
|
130
|
+
*/
|
|
131
|
+
config(userConfig, userEnv) {
|
|
132
|
+
// @ts-ignore
|
|
133
|
+
const isHttps = userConfig?.server?.https !== false
|
|
134
|
+
&& fs.existsSync(join(os.homedir(), `.ssh/${options.cert}.pem`))
|
|
135
|
+
&& fs.existsSync(join(os.homedir(), `.ssh/${options.cert}-key.pem`))
|
|
136
|
+
|
|
137
|
+
let defaultInput = [
|
|
138
|
+
...(options?.input?.assets ?? []),
|
|
139
|
+
]
|
|
140
|
+
|
|
141
|
+
if (!options.mode) {
|
|
142
|
+
options.mode = userEnv.mode
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
if (options.mode === 'development') {
|
|
146
|
+
defaultInput = [
|
|
147
|
+
...(options?.input?.pages ?? []),
|
|
148
|
+
...(options?.input?.assets ?? []),
|
|
149
|
+
]
|
|
150
|
+
}
|
|
138
151
|
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
...(options?.input?.assets ?? [])
|
|
143
|
-
]
|
|
144
|
-
}
|
|
152
|
+
if (userEnv.command === 'build') {
|
|
153
|
+
userConfig.publicDir = userConfig.publicDir ?? false
|
|
154
|
+
}
|
|
145
155
|
|
|
146
|
-
|
|
147
|
-
userConfig.publicDir = userConfig.publicDir ?? false
|
|
148
|
-
}
|
|
156
|
+
const outDir = resolve(userConfig.root ?? process.cwd(), 'public')
|
|
149
157
|
|
|
150
|
-
|
|
158
|
+
if (userConfig.build && !userConfig.build.outDir) {
|
|
159
|
+
userConfig.build.outDir = outDir
|
|
160
|
+
}
|
|
151
161
|
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
162
|
+
userConfig.optimizeDeps = Object.assign({
|
|
163
|
+
entries: [],
|
|
164
|
+
}, userConfig.optimizeDeps ?? {})
|
|
155
165
|
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
defaultInput = [
|
|
185
|
-
...(options?.input?.emails ?? [])
|
|
186
|
-
]
|
|
187
|
-
|
|
188
|
-
userConfig.build.rollupOptions = Object.assign({
|
|
189
|
-
input: defaultInput,
|
|
190
|
-
output: {
|
|
191
|
-
assetFileNames: 'assets/email/[name].[ext]'
|
|
192
|
-
}
|
|
193
|
-
}, userConfig.build.rollupOptions ?? {})
|
|
194
|
-
} else {
|
|
195
|
-
userConfig.build.rollupOptions = Object.assign({
|
|
196
|
-
input: defaultInput,
|
|
197
|
-
output: {
|
|
198
|
-
manualChunks: options.manualChunks ?? {
|
|
199
|
-
swup: ['swup'],
|
|
200
|
-
stimulus: ['@hotwired/stimulus'],
|
|
201
|
-
naja: ['naja']
|
|
202
|
-
}
|
|
203
|
-
}
|
|
204
|
-
}, userConfig.build.rollupOptions ?? {})
|
|
205
|
-
}
|
|
166
|
+
userConfig.css = Object.assign({
|
|
167
|
+
transformer: options.css.transformer,
|
|
168
|
+
}, userConfig.css ?? {})
|
|
169
|
+
|
|
170
|
+
userConfig.css.lightningcss = Object.assign({
|
|
171
|
+
targets: browserslistToTargets(browserslist()),
|
|
172
|
+
exclude: (options.mode !== 'emails') ? LightningCssFeatures.Nesting : 0,
|
|
173
|
+
drafts: {
|
|
174
|
+
customMedia: true,
|
|
175
|
+
},
|
|
176
|
+
}, userConfig.css.lightningcss ?? {})
|
|
177
|
+
|
|
178
|
+
userConfig.build = Object.assign({
|
|
179
|
+
target: browserslistToEsbuild(),
|
|
180
|
+
manifest: (options.mode === 'emails') ? false : 'manifest.json',
|
|
181
|
+
emptyOutDir: false,
|
|
182
|
+
modulePreload: false,
|
|
183
|
+
assetsInlineLimit: 0,
|
|
184
|
+
outDir,
|
|
185
|
+
}, userConfig.build ?? {})
|
|
186
|
+
|
|
187
|
+
if (options.mode === 'emails') {
|
|
188
|
+
userEnv.mode = 'production'
|
|
189
|
+
|
|
190
|
+
defaultInput = [
|
|
191
|
+
...(options?.input?.emails ?? []),
|
|
192
|
+
]
|
|
206
193
|
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
194
|
+
userConfig.build.rolldownOptions = Object.assign({
|
|
195
|
+
input: defaultInput,
|
|
196
|
+
output: {
|
|
197
|
+
assetFileNames: 'assets/email/[name].[ext]',
|
|
198
|
+
},
|
|
199
|
+
}, userConfig.build.rolldownOptions ?? {})
|
|
200
|
+
}
|
|
201
|
+
else {
|
|
202
|
+
userConfig.build.rolldownOptions = Object.assign({
|
|
203
|
+
input: defaultInput,
|
|
204
|
+
output: {
|
|
205
|
+
advancedChunks: options.advancedChunks ?? {
|
|
206
|
+
groups: [
|
|
207
|
+
{
|
|
208
|
+
name: 'swup',
|
|
209
|
+
test: /swup/,
|
|
210
|
+
},
|
|
211
|
+
{
|
|
212
|
+
name: '@hotwired/stimulus',
|
|
213
|
+
test: /@hotwired\/stimulus/,
|
|
214
|
+
},
|
|
215
|
+
{
|
|
216
|
+
name: 'naja',
|
|
217
|
+
test: /naja/,
|
|
212
218
|
},
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
219
|
+
],
|
|
220
|
+
},
|
|
221
|
+
},
|
|
222
|
+
}, userConfig.build.rolldownOptions ?? {})
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
userConfig.server = Object.assign({
|
|
226
|
+
host: true,
|
|
227
|
+
cors: true,
|
|
228
|
+
fsServe: {
|
|
229
|
+
strict: false,
|
|
230
|
+
},
|
|
231
|
+
https: isHttps
|
|
232
|
+
? {
|
|
233
|
+
key: fs.readFileSync(join(os.homedir(), `.ssh/${options.cert}-key.pem`)),
|
|
234
|
+
cert: fs.readFileSync(join(os.homedir(), `.ssh/${options.cert}.pem`)),
|
|
235
|
+
}
|
|
236
|
+
: false,
|
|
237
|
+
}, userConfig.server ?? {})
|
|
238
|
+
},
|
|
239
|
+
}, ...plugins]
|
|
222
240
|
}
|
|
223
241
|
|
|
224
242
|
export default plugin
|
package/latte/JsonFilter.js
CHANGED
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@newlogic-digital/core",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "
|
|
4
|
+
"version": "4.0.0-next.2",
|
|
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",
|
|
@@ -12,30 +12,22 @@
|
|
|
12
12
|
"publish-next": "npm publish --tag next"
|
|
13
13
|
},
|
|
14
14
|
"dependencies": {
|
|
15
|
-
"@
|
|
16
|
-
"@vituum/vite-plugin-
|
|
17
|
-
"@vituum/vite-plugin-
|
|
18
|
-
"
|
|
19
|
-
"@vituum/vite-plugin-send": "^1.1.0",
|
|
20
|
-
"browserslist": "^4.24.4",
|
|
15
|
+
"@vituum/vite-plugin-juice": "^2.0.0-next.1",
|
|
16
|
+
"@vituum/vite-plugin-latte": "^2.0.0-next.2",
|
|
17
|
+
"@vituum/vite-plugin-send": "^2.0.0-next.1",
|
|
18
|
+
"browserslist": "^4.28.1",
|
|
21
19
|
"browserslist-to-esbuild": "^2.1.1",
|
|
22
|
-
"
|
|
23
|
-
"
|
|
24
|
-
"html-minifier-terser": "^7.2.0",
|
|
25
|
-
"lightningcss": "^1.29.3",
|
|
26
|
-
"lodash": "^4.17.21",
|
|
27
|
-
"picocolors": "^1.1.1",
|
|
28
|
-
"posthtml": "^0.16.6",
|
|
29
|
-
"posthtml-prism": "^2.0.1",
|
|
30
|
-
"prismjs": "^1.30.0",
|
|
31
|
-
"vituum": "^1.2.0"
|
|
20
|
+
"lightningcss": "^1.30.2",
|
|
21
|
+
"vituum": "^2.0.0-next.5"
|
|
32
22
|
},
|
|
33
23
|
"devDependencies": {
|
|
34
|
-
"@
|
|
35
|
-
"eslint": "^
|
|
36
|
-
"
|
|
24
|
+
"@eslint/js": "^9.39",
|
|
25
|
+
"@stylistic/eslint-plugin": "^5.6",
|
|
26
|
+
"@types/node": "^25.0.3",
|
|
27
|
+
"eslint": "^9.39.2",
|
|
28
|
+
"rolldown": "^1.0.0-beta.55",
|
|
37
29
|
"typescript": "^5",
|
|
38
|
-
"vite": "^
|
|
30
|
+
"vite": "^8.0.0-beta.3",
|
|
39
31
|
"@vituum/vite-plugin-tailwindcss": "^1.2.0",
|
|
40
32
|
"@vituum/vite-plugin-twig": "^1.1.0"
|
|
41
33
|
},
|
package/src/minify.js
CHANGED
|
@@ -1,22 +1,23 @@
|
|
|
1
1
|
import minifier from 'html-minifier-terser'
|
|
2
2
|
|
|
3
3
|
const parseMinifyHtml = async (input, name) => {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
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
12
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
13
|
+
if (name) {
|
|
14
|
+
return JSON.stringify({
|
|
15
|
+
[name]: minify,
|
|
16
|
+
})
|
|
17
|
+
}
|
|
18
|
+
else {
|
|
19
|
+
return JSON.stringify(minify)
|
|
20
|
+
}
|
|
20
21
|
}
|
|
21
22
|
|
|
22
23
|
export default parseMinifyHtml
|
package/src/twig.js
CHANGED
|
@@ -1,174 +1,177 @@
|
|
|
1
1
|
import fs from 'fs'
|
|
2
2
|
import { resolve } from 'path'
|
|
3
3
|
import parseMinifyHtml from './minify.js'
|
|
4
|
+
import process from 'node:process'
|
|
4
5
|
|
|
5
6
|
const wrapPreCode = (code, lang) => {
|
|
6
|
-
|
|
7
|
+
return `<pre class="language-${lang}"><code class="language-${lang}">${code}</code></pre>`
|
|
7
8
|
}
|
|
8
9
|
|
|
9
10
|
const stripIndent = (string) => {
|
|
10
|
-
|
|
11
|
-
|
|
11
|
+
const indent = () => {
|
|
12
|
+
const match = string.match(/^[ \t]*(?=\S)/gm)
|
|
12
13
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
return match.reduce((r, a) => Math.min(r, a.length), Infinity)
|
|
14
|
+
if (!match) {
|
|
15
|
+
return 0
|
|
18
16
|
}
|
|
19
17
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
18
|
+
return match.reduce((r, a) => Math.min(r, a.length), Infinity)
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
if (indent() === 0) {
|
|
22
|
+
return string
|
|
23
|
+
}
|
|
23
24
|
|
|
24
|
-
|
|
25
|
+
const regex = new RegExp(`^[ \\t]{${indent()}}`, 'gm')
|
|
25
26
|
|
|
26
|
-
|
|
27
|
+
return string.replace(regex, '')
|
|
27
28
|
}
|
|
28
29
|
|
|
29
30
|
export default {
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
31
|
+
namespaces: {
|
|
32
|
+
src: resolve(process.cwd(), 'src'),
|
|
33
|
+
templates: resolve(process.cwd(), 'src/templates'),
|
|
34
|
+
},
|
|
35
|
+
functions: {
|
|
36
|
+
pages: () => {
|
|
37
|
+
return fs.readdirSync('src/views').filter(file => fs.statSync('src/views/' + file).isFile())
|
|
33
38
|
},
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
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>'))
|
|
39
|
+
fetch: (data) => {
|
|
40
|
+
if (typeof data !== 'undefined') {
|
|
41
|
+
if (data.indexOf('http') > -1) {
|
|
42
|
+
return data
|
|
43
|
+
}
|
|
44
|
+
else {
|
|
45
|
+
let slash = data.indexOf('/') + 1
|
|
46
|
+
if (slash > 1) {
|
|
47
|
+
slash = 0
|
|
48
|
+
}
|
|
61
49
|
|
|
62
|
-
|
|
63
|
-
},
|
|
64
|
-
ratio: (width, height) => {
|
|
65
|
-
return (height / width) * 100
|
|
50
|
+
return fs.readFileSync(process.cwd() + '/' + data.substring(slash, data.length), 'utf8').toString()
|
|
66
51
|
}
|
|
52
|
+
}
|
|
67
53
|
},
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
54
|
+
randomColor: () => {
|
|
55
|
+
return '#' + Math.random().toString(16).slice(2, 8)
|
|
56
|
+
},
|
|
57
|
+
placeholder: (width, height) => {
|
|
58
|
+
const colors = ['333', '444', '666', '222', '777', '888', '111']
|
|
59
|
+
return 'https://via.placeholder.com/' + width + 'x' + height + '/' + colors[Math.floor(Math.random() * colors.length)] + '.webp'
|
|
60
|
+
},
|
|
61
|
+
lazy: (width, height) => {
|
|
62
|
+
const svg = encodeURIComponent(stripIndent('<svg width="' + width + '" height="' + height + '" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 ' + width + ' ' + height + '"></svg>'))
|
|
77
63
|
|
|
78
|
-
|
|
64
|
+
return 'data:image/svg+xml;charset=UTF-8,' + svg
|
|
65
|
+
},
|
|
66
|
+
ratio: (width, height) => {
|
|
67
|
+
return (height / width) * 100
|
|
68
|
+
},
|
|
69
|
+
},
|
|
70
|
+
filters: {
|
|
71
|
+
asset: (url) => {
|
|
72
|
+
return url
|
|
73
|
+
},
|
|
74
|
+
rem: (value) => {
|
|
75
|
+
return `${value / 16}rem`
|
|
76
|
+
},
|
|
77
|
+
encode64: (path) => {
|
|
78
|
+
const svg = encodeURIComponent(stripIndent(path))
|
|
79
|
+
|
|
80
|
+
return 'data:image/svg+xml;charset=UTF-8,' + svg
|
|
81
|
+
},
|
|
82
|
+
exists: (path) => {
|
|
83
|
+
if (path.indexOf('/') === 0) {
|
|
84
|
+
path = path.slice(1)
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
return fs.existsSync(resolve(process.cwd(), path))
|
|
88
|
+
},
|
|
89
|
+
tel: (value) => {
|
|
90
|
+
return value.replace(/\s+/g, '').replace('(', '').replace(')', '')
|
|
91
|
+
},
|
|
92
|
+
},
|
|
93
|
+
extensions: [
|
|
94
|
+
(Twig) => {
|
|
95
|
+
Twig.exports.extendTag({
|
|
96
|
+
type: 'json',
|
|
97
|
+
regex: /^json\s+(.+)$|^json$/,
|
|
98
|
+
next: ['endjson'],
|
|
99
|
+
open: true,
|
|
100
|
+
compile: function (token) {
|
|
101
|
+
const expression = token.match[1] ?? '\'_null\''
|
|
102
|
+
|
|
103
|
+
token.stack = Reflect.apply(Twig.expression.compile, this, [{
|
|
104
|
+
type: Twig.expression.type.expression,
|
|
105
|
+
value: expression,
|
|
106
|
+
}]).stack
|
|
107
|
+
|
|
108
|
+
delete token.match
|
|
109
|
+
return token
|
|
79
110
|
},
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
111
|
+
parse: async function (token, context, chain) {
|
|
112
|
+
const name = Reflect.apply(Twig.expression.parse, this, [token.stack, context])
|
|
113
|
+
const output = this.parse(token.output, context)
|
|
114
|
+
|
|
115
|
+
if (name === '_null') {
|
|
116
|
+
return {
|
|
117
|
+
chain,
|
|
118
|
+
output: await parseMinifyHtml(output),
|
|
83
119
|
}
|
|
84
|
-
|
|
85
|
-
|
|
120
|
+
}
|
|
121
|
+
else {
|
|
122
|
+
return {
|
|
123
|
+
chain,
|
|
124
|
+
output: await parseMinifyHtml(output, name),
|
|
125
|
+
}
|
|
126
|
+
}
|
|
86
127
|
},
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
128
|
+
})
|
|
129
|
+
Twig.exports.extendTag({
|
|
130
|
+
type: 'endjson',
|
|
131
|
+
regex: /^endjson$/,
|
|
132
|
+
next: [],
|
|
133
|
+
open: false,
|
|
134
|
+
})
|
|
90
135
|
},
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
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
|
-
})
|
|
136
|
+
(Twig) => {
|
|
137
|
+
Twig.exports.extendTag({
|
|
138
|
+
type: 'code',
|
|
139
|
+
regex: /^code\s+(.+)$/,
|
|
140
|
+
next: ['endcode'], // match the type of the end tag
|
|
141
|
+
open: true,
|
|
142
|
+
compile: function (token) {
|
|
143
|
+
const expression = token.match[1]
|
|
144
|
+
|
|
145
|
+
token.stack = Reflect.apply(Twig.expression.compile, this, [{
|
|
146
|
+
type: Twig.expression.type.expression,
|
|
147
|
+
value: expression,
|
|
148
|
+
}]).stack
|
|
149
|
+
|
|
150
|
+
delete token.match
|
|
151
|
+
return token
|
|
132
152
|
},
|
|
133
|
-
(
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
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
|
-
]
|
|
153
|
+
parse: function (token, context, chain) {
|
|
154
|
+
let type = Reflect.apply(Twig.expression.parse, this, [token.stack, context])
|
|
155
|
+
const output = this.parse(token.output, context)
|
|
156
|
+
let mirror = false
|
|
157
|
+
|
|
158
|
+
if (type.includes(':mirror')) {
|
|
159
|
+
mirror = true
|
|
160
|
+
type = type.replace(':mirror', '')
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
return {
|
|
164
|
+
chain,
|
|
165
|
+
output: `${mirror ? output : ''}${wrapPreCode(output, type)}`,
|
|
166
|
+
}
|
|
167
|
+
},
|
|
168
|
+
})
|
|
169
|
+
Twig.exports.extendTag({
|
|
170
|
+
type: 'endcode',
|
|
171
|
+
regex: /^endcode$/,
|
|
172
|
+
next: [],
|
|
173
|
+
open: false,
|
|
174
|
+
})
|
|
175
|
+
},
|
|
176
|
+
],
|
|
174
177
|
}
|
package/types/index.d.ts
CHANGED
|
@@ -9,13 +9,13 @@ export interface PluginUserConfig {
|
|
|
9
9
|
format?: string[]
|
|
10
10
|
input?: Input
|
|
11
11
|
cert?: string
|
|
12
|
-
|
|
12
|
+
advancedChunks?: import('rolldown').OutputOptions['advancedChunks']
|
|
13
13
|
vituum?: import('vituum').UserConfig,
|
|
14
14
|
css?: import('vite').CSSOptions
|
|
15
|
-
posthtml?: import('@vituum/vite-plugin-posthtml
|
|
16
|
-
juice?: import('@vituum/vite-plugin-juice
|
|
17
|
-
send?: import('@vituum/vite-plugin-send
|
|
18
|
-
tailwindcss?: import('@vituum/vite-plugin-tailwindcss
|
|
19
|
-
latte?: import('@vituum/vite-plugin-latte
|
|
20
|
-
twig?: import('@vituum/vite-plugin-twig
|
|
15
|
+
posthtml?: import('@vituum/vite-plugin-posthtml').PluginUserConfig
|
|
16
|
+
juice?: import('@vituum/vite-plugin-juice').PluginUserConfig
|
|
17
|
+
send?: import('@vituum/vite-plugin-send').PluginUserConfig
|
|
18
|
+
tailwindcss?: import('@vituum/vite-plugin-tailwindcss').PluginUserConfig
|
|
19
|
+
latte?: import('@vituum/vite-plugin-latte').PluginUserConfig
|
|
20
|
+
twig?: import('@vituum/vite-plugin-twig').PluginUserConfig
|
|
21
21
|
}
|
package/src/prism.js
DELETED
|
@@ -1,90 +0,0 @@
|
|
|
1
|
-
import Prism from 'prismjs'
|
|
2
|
-
import { render } from 'posthtml-render'
|
|
3
|
-
import loadLanguages from 'prismjs/components/index.js'
|
|
4
|
-
import NormalizeWhitespace from 'prismjs/plugins/normalize-whitespace/prism-normalize-whitespace.js'
|
|
5
|
-
|
|
6
|
-
const Normalize = new NormalizeWhitespace({
|
|
7
|
-
'remove-trailing': true,
|
|
8
|
-
'remove-indent': true,
|
|
9
|
-
'left-trim': true,
|
|
10
|
-
'right-trim': true
|
|
11
|
-
})
|
|
12
|
-
|
|
13
|
-
const createPrismPlugin = (options) => {
|
|
14
|
-
return (tree) => {
|
|
15
|
-
const highlightCodeTags = node => tree.match.call(node, { tag: 'code' }, highlightNode)
|
|
16
|
-
|
|
17
|
-
if (options.inline) {
|
|
18
|
-
highlightCodeTags(tree)
|
|
19
|
-
} else {
|
|
20
|
-
tree.match({ tag: 'pre' }, highlightCodeTags)
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
const highlightNode = (node) => {
|
|
26
|
-
const attrs = node.attrs || {}
|
|
27
|
-
const classList = `${attrs.class || ''}`.trimStart()
|
|
28
|
-
|
|
29
|
-
if ('prism-ignore' in attrs) {
|
|
30
|
-
delete node.attrs['prism-ignore']
|
|
31
|
-
|
|
32
|
-
return node
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
if (classList.includes('prism-ignore')) {
|
|
36
|
-
node.attrs.class = node.attrs.class.replace('prism-ignore', '').trim()
|
|
37
|
-
|
|
38
|
-
return node
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
const lang = getExplicitLanguage(classList)
|
|
42
|
-
|
|
43
|
-
if (lang && !classList.includes(`language-${lang}`)) {
|
|
44
|
-
attrs.class = `${classList || ''} language-${lang}`.trimStart()
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
node.attrs = attrs
|
|
48
|
-
|
|
49
|
-
if (node.content) {
|
|
50
|
-
const html = (node.content[0].tag && !node.content[0].content) ? `<${node.content[0].tag}>` : render(node.content)
|
|
51
|
-
|
|
52
|
-
node.content = mapStringOrNode(html, lang)
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
return node
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
const mapStringOrNode = (stringOrNode, lang = null) => {
|
|
59
|
-
if (typeof stringOrNode === 'string') {
|
|
60
|
-
if (lang) {
|
|
61
|
-
if (!Object.keys(Prism.languages).includes(lang)) {
|
|
62
|
-
loadLanguages.silent = true
|
|
63
|
-
loadLanguages([lang])
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
return Prism.highlight(Normalize.normalize(stringOrNode), Prism.languages[lang], lang)
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
return Prism.highlight(Normalize.normalize(stringOrNode), Prism.languages.markup, 'markup')
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
highlightNode(stringOrNode)
|
|
73
|
-
|
|
74
|
-
return stringOrNode
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
const getExplicitLanguage = (classList) => {
|
|
78
|
-
const matches = classList.match(/(?:lang|language)-(\w*)/)
|
|
79
|
-
|
|
80
|
-
return matches === null ? null : matches[1]
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
const plugin = (options) => {
|
|
84
|
-
options = options || {}
|
|
85
|
-
options.inline = options.inline || false
|
|
86
|
-
|
|
87
|
-
return tree => createPrismPlugin(options)(tree)
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
export default plugin
|