@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 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
- mode: null,
21
- cert: 'localhost',
22
- format: ['latte'],
23
- manualChunks: {},
24
- input: {
25
- assets: [
26
- './src/styles/*.{css,pcss,scss,sass,less,styl,stylus}',
27
- './src/scripts/*.{js,ts,mjs}'
28
- ],
29
- pages: [
30
- './src/pages/**/*.{json,latte,twig,liquid,njk,hbs,pug,html}',
31
- '!./src/pages/**/*.{latte,twig,liquid,njk,hbs,pug,html}.json',
32
- '!./src/pages/email/**/*'
33
- ],
34
- emails: [
35
- './src/pages/email/**/*.{json,latte,twig,liquid,njk,hbs,pug,html}',
36
- './src/styles/emails/*.{css,pcss,scss,sass,less,styl,stylus}',
37
- '!./src/pages/email/**/*.{latte,twig,liquid,njk,hbs,pug,html}.json'
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
- vituum: {
41
- imports: {
42
- paths: ['./src/styles/*/**', '!./src/styles/emails/*', './src/scripts/*/**']
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
- juice: {
46
- paths: ['src/pages/email'],
47
- postcss: {
48
- globalData: {
49
- files: ['./src/styles/emails/theme/config.css']
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
- css: {
54
- transformer: 'postcss',
55
- lightningcss: {}
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
- tailwindcss: {},
58
- send: {},
59
- latte: {
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
- twig: twigOptions
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
- options = merge(defaultOptions, options)
84
-
85
- const templatesPlugins = []
86
- const tailwindcssPlugin = []
84
+ options = merge(defaultOptions, options)
87
85
 
88
- if (options.format.includes('twig')) {
89
- const twig = (await import('@vituum/vite-plugin-twig')).default
86
+ const templatesPlugins = []
87
+ const tailwindcssPlugin = []
90
88
 
91
- templatesPlugins.push(twig(options.twig))
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
- if (options.css.transformer === 'postcss') {
99
- const tailwindcss = (await import('@vituum/vite-plugin-tailwindcss')).default
92
+ templatesPlugins.push(twig(options.twig))
93
+ }
100
94
 
101
- tailwindcssPlugin.push(tailwindcss(options.tailwindcss))
102
- }
95
+ if (options.format.includes('latte')) {
96
+ templatesPlugins.push(latte(options.latte))
97
+ }
103
98
 
104
- if (options.css.transformer === 'lightningcss') {
105
- if (!fs.existsSync(resolve(process.cwd(), 'src/+.css'))) {
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
- // @ts-ignore
110
- const tailwindcss = (await import('@tailwindcss/vite')).default
102
+ tailwindcssPlugin.push(tailwindcss(options.tailwindcss))
103
+ }
111
104
 
112
- tailwindcssPlugin.push(tailwindcss(options.tailwindcss))
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
- const plugins = [
116
- vituum(options.vituum),
117
- ...tailwindcssPlugin,
118
- ...templatesPlugins,
119
- juice(options.juice),
120
- send(options.send)
121
- ]
122
-
123
- return [{
124
- name,
125
- enforce: 'pre',
126
- config(userConfig, userEnv) {
127
- const isHttps = userConfig?.server?.https !== false
128
- && fs.existsSync(join(os.homedir(), `.ssh/${options.cert}.pem`))
129
- && fs.existsSync(join(os.homedir(), `.ssh/${options.cert}-key.pem`))
130
-
131
- let defaultInput = [
132
- ...(options?.input?.assets ?? [])
133
- ]
134
-
135
- if (!options.mode) {
136
- options.mode = userEnv.mode
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
- if (options.mode === 'development') {
140
- defaultInput = [
141
- ...(options?.input?.pages ?? []),
142
- ...(options?.input?.assets ?? [])
143
- ]
144
- }
152
+ if (userEnv.command === 'build') {
153
+ userConfig.publicDir = userConfig.publicDir ?? false
154
+ }
145
155
 
146
- if (userEnv.command === 'build') {
147
- userConfig.publicDir = userConfig.publicDir ?? false
148
- }
156
+ const outDir = resolve(userConfig.root ?? process.cwd(), 'public')
149
157
 
150
- const outDir = resolve(userConfig.root ?? process.cwd(), 'public')
158
+ if (userConfig.build && !userConfig.build.outDir) {
159
+ userConfig.build.outDir = outDir
160
+ }
151
161
 
152
- if (userConfig.build && !userConfig.build.outDir) {
153
- userConfig.build.outDir = outDir
154
- }
162
+ userConfig.optimizeDeps = Object.assign({
163
+ entries: [],
164
+ }, userConfig.optimizeDeps ?? {})
155
165
 
156
- userConfig.optimizeDeps = Object.assign({
157
- entries: []
158
- }, userConfig.optimizeDeps ?? {})
159
-
160
- userConfig.css = Object.assign({
161
- transformer: options.css.transformer
162
- }, userConfig.css ?? {})
163
-
164
- userConfig.css.lightningcss = Object.assign({
165
- targets: browserslistToTargets(browserslist()),
166
- exclude: (options.mode !== 'emails') ? LightningCssFeatures.Nesting : 0,
167
- drafts: {
168
- customMedia: true
169
- }
170
- }, userConfig.css.lightningcss ?? {})
171
-
172
- userConfig.build = Object.assign({
173
- target: browserslistToEsbuild(),
174
- manifest: (options.mode === 'emails') ? false : 'manifest.json',
175
- emptyOutDir: false,
176
- modulePreload: false,
177
- assetsInlineLimit: 0,
178
- outDir
179
- }, userConfig.build ?? {})
180
-
181
- if (options.mode === 'emails') {
182
- userEnv.mode = 'production'
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
- userConfig.server = Object.assign({
208
- host: true,
209
- cors: true,
210
- fsServe: {
211
- strict: false
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
- https: isHttps
214
- ? {
215
- key: fs.readFileSync(join(os.homedir(), `.ssh/${options.cert}-key.pem`)),
216
- cert: fs.readFileSync(join(os.homedir(), `.ssh/${options.cert}.pem`))
217
- }
218
- : false
219
- }, userConfig.server ?? {})
220
- }
221
- }, ...plugins]
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
@@ -1,7 +1,7 @@
1
1
  import parseMinifyHtml from '../src/minify.js'
2
2
 
3
3
  const json = async (input, name) => {
4
- return await parseMinifyHtml(input, name)
4
+ return await parseMinifyHtml(input, name)
5
5
  }
6
6
 
7
7
  export default json
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@newlogic-digital/core",
3
3
  "type": "module",
4
- "version": "3.1.1",
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
- "@tailwindcss/vite": "^4.1.4",
16
- "@vituum/vite-plugin-juice": "^1.4.0",
17
- "@vituum/vite-plugin-latte": "^1.3.0",
18
- "@vituum/vite-plugin-posthtml": "^1.1.0",
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
- "fast-glob": "^3.3.3",
23
- "fs-extra": "^11.3.0",
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
- "@types/node": "^22.15.3",
35
- "eslint": "^9.25.1",
36
- "neostandard": "^0.12.1",
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": "^6",
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
- const minify = await minifier.minify(input, {
5
- collapseWhitespace: true,
6
- collapseInlineTagWhitespace: false,
7
- minifyCSS: true,
8
- removeAttributeQuotes: true,
9
- quoteCharacter: '\'',
10
- minifyJS: true
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
- if (name) {
14
- return JSON.stringify({
15
- [name]: minify
16
- })
17
- } else {
18
- return JSON.stringify(minify)
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
- return `<pre class="language-${lang}"><code class="language-${lang}">${code}</code></pre>`
7
+ return `<pre class="language-${lang}"><code class="language-${lang}">${code}</code></pre>`
7
8
  }
8
9
 
9
10
  const stripIndent = (string) => {
10
- const indent = () => {
11
- const match = string.match(/^[ \t]*(?=\S)/gm)
11
+ const indent = () => {
12
+ const match = string.match(/^[ \t]*(?=\S)/gm)
12
13
 
13
- if (!match) {
14
- return 0
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
- if (indent() === 0) {
21
- return string
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
- const regex = new RegExp(`^[ \\t]{${indent()}}`, 'gm')
25
+ const regex = new RegExp(`^[ \\t]{${indent()}}`, 'gm')
25
26
 
26
- return string.replace(regex, '')
27
+ return string.replace(regex, '')
27
28
  }
28
29
 
29
30
  export default {
30
- namespaces: {
31
- src: resolve(process.cwd(), 'src'),
32
- templates: resolve(process.cwd(), 'src/templates')
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
- 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>'))
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
- return 'data:image/svg+xml;charset=UTF-8,' + svg
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
- filters: {
69
- asset: (url) => {
70
- return url
71
- },
72
- rem: (value) => {
73
- return `${value / 16}rem`
74
- },
75
- encode64: (path) => {
76
- const svg = encodeURIComponent(stripIndent(path))
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
- return 'data:image/svg+xml;charset=UTF-8,' + svg
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
- exists: (path) => {
81
- if (path.indexOf('/') === 0) {
82
- path = path.slice(1)
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
- return fs.existsSync(resolve(process.cwd(), path))
120
+ }
121
+ else {
122
+ return {
123
+ chain,
124
+ output: await parseMinifyHtml(output, name),
125
+ }
126
+ }
86
127
  },
87
- tel: (value) => {
88
- return value.replace(/\s+/g, '').replace('(', '').replace(')', '')
89
- }
128
+ })
129
+ Twig.exports.extendTag({
130
+ type: 'endjson',
131
+ regex: /^endjson$/,
132
+ next: [],
133
+ open: false,
134
+ })
90
135
  },
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
- })
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
- (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
- ]
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
- manualChunks?: import('rollup').ManualChunksOption
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/types').PluginUserConfig
16
- juice?: import('@vituum/vite-plugin-juice/types').PluginUserConfig
17
- send?: import('@vituum/vite-plugin-send/types').PluginUserConfig
18
- tailwindcss?: import('@vituum/vite-plugin-tailwindcss/types').PluginUserConfig
19
- latte?: import('@vituum/vite-plugin-latte/types').PluginUserConfig
20
- twig?: import('@vituum/vite-plugin-twig/types').PluginUserConfig
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