vitrify 0.5.1 → 0.5.4
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/dist/app-urls.js +7 -0
- package/dist/bin/build.js +3 -2
- package/dist/bin/cli.js +3 -1
- package/dist/bin/dev.js +0 -1
- package/dist/index.js +45 -44
- package/dist/plugins/quasar.js +12 -15
- package/dist/types/app-urls.d.ts +1 -0
- package/dist/types/bin/build.d.ts +1 -0
- package/dist/types/index.d.ts +2 -1
- package/dist/types/vitrify-config.d.ts +1 -0
- package/package.json +3 -6
- package/src/node/app-urls.ts +8 -0
- package/src/node/bin/build.ts +4 -2
- package/src/node/bin/cli.ts +4 -1
- package/src/node/bin/dev.ts +0 -1
- package/src/node/index.ts +50 -51
- package/src/node/plugins/quasar.ts +14 -16
- package/src/node/vitrify-config.ts +1 -1
- package/src/vite/vue/csr/app.ts +3 -4
- package/src/vite/vue/main.ts +2 -0
- package/src/vite/vue/ssr/app.ts +3 -4
package/dist/app-urls.js
CHANGED
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
// import { resolve } from 'import-meta-resolve'
|
|
2
2
|
import { existsSync } from 'fs';
|
|
3
|
+
export const resolve = (packageName, base) => {
|
|
4
|
+
const packageUrl = new URL(`./node_modules/${packageName}/`, base);
|
|
5
|
+
if (existsSync(packageUrl.pathname)) {
|
|
6
|
+
return new URL('./', packageUrl);
|
|
7
|
+
}
|
|
8
|
+
throw new Error(`Package ${packageName} not found in ${base.pathname}.`);
|
|
9
|
+
};
|
|
3
10
|
export const getPkgJsonDir = (dir) => {
|
|
4
11
|
const pkgJsonPath = new URL('package.json', dir);
|
|
5
12
|
if (existsSync(pkgJsonPath.pathname)) {
|
package/dist/bin/build.js
CHANGED
|
@@ -8,11 +8,12 @@ export async function build(opts) {
|
|
|
8
8
|
ssr: opts?.ssr,
|
|
9
9
|
appDir: opts.appDir,
|
|
10
10
|
publicDir: opts.publicDir,
|
|
11
|
-
base: opts.base
|
|
11
|
+
base: opts.base,
|
|
12
|
+
debug: opts.debug
|
|
12
13
|
});
|
|
13
14
|
config.build = {
|
|
14
15
|
...config.build,
|
|
15
|
-
minify:
|
|
16
|
+
minify: !opts.debug,
|
|
16
17
|
outDir: opts.outDir,
|
|
17
18
|
emptyOutDir: !!opts.outDir
|
|
18
19
|
};
|
package/dist/bin/cli.js
CHANGED
|
@@ -11,6 +11,7 @@ cli
|
|
|
11
11
|
.option('--appDir [appDir]', 'App directory')
|
|
12
12
|
.option('--publicDir [publicDir]', 'Public directory')
|
|
13
13
|
.option('--productName [productName]', 'Product name')
|
|
14
|
+
.option('--debug', 'Debug build')
|
|
14
15
|
.action(async (options) => {
|
|
15
16
|
const { build } = await import('./build.js');
|
|
16
17
|
let appDir;
|
|
@@ -27,7 +28,8 @@ cli
|
|
|
27
28
|
const args = {
|
|
28
29
|
base: options.base,
|
|
29
30
|
appDir,
|
|
30
|
-
publicDir: parsePath(options.publicDir, appDir)
|
|
31
|
+
publicDir: parsePath(options.publicDir, appDir),
|
|
32
|
+
debug: options.debug
|
|
31
33
|
};
|
|
32
34
|
switch (options.mode) {
|
|
33
35
|
case 'csr':
|
package/dist/bin/dev.js
CHANGED
package/dist/index.js
CHANGED
|
@@ -6,39 +6,17 @@ import path from 'path';
|
|
|
6
6
|
import { pathToFileURL } from 'url';
|
|
7
7
|
import { readFileSync } from 'fs';
|
|
8
8
|
import builtinModules from 'builtin-modules';
|
|
9
|
-
import { resolve } from 'import-meta-resolve'
|
|
10
|
-
import {
|
|
9
|
+
// import { resolve } from 'import-meta-resolve'
|
|
10
|
+
import { visualizer } from 'rollup-plugin-visualizer';
|
|
11
|
+
import { getPkgJsonDir, resolve } from './app-urls.js';
|
|
11
12
|
const internalServerModules = [
|
|
12
|
-
// 'fs',
|
|
13
|
-
// 'path',
|
|
14
|
-
// 'url',
|
|
15
|
-
// 'module',
|
|
16
|
-
// 'crypto',
|
|
17
|
-
// 'node:fs',
|
|
18
13
|
'util',
|
|
19
|
-
'node:url',
|
|
20
|
-
'node:util',
|
|
21
|
-
'node:fs',
|
|
22
|
-
'node:process',
|
|
23
14
|
'vitrify',
|
|
24
15
|
'vitrify/dev',
|
|
25
|
-
// 'import-meta-resolve',
|
|
26
16
|
'vite',
|
|
27
17
|
'fastify',
|
|
28
|
-
'@fastify',
|
|
18
|
+
'@fastify/static',
|
|
29
19
|
'node'
|
|
30
|
-
// 'middie',
|
|
31
|
-
// 'knex',
|
|
32
|
-
// 'bcrypt',
|
|
33
|
-
// 'objection',
|
|
34
|
-
// '@fastify/formbody',
|
|
35
|
-
// '@fastify/static',
|
|
36
|
-
// '@fastify/cors',
|
|
37
|
-
// '@fastify/cookie',
|
|
38
|
-
// 'mercurius',
|
|
39
|
-
// 'jose',
|
|
40
|
-
// 'oidc-provider',
|
|
41
|
-
// 'node-fetch'
|
|
42
20
|
];
|
|
43
21
|
const configPluginMap = {
|
|
44
22
|
quasar: () => import('./plugins/quasar.js').then((module) => module.QuasarPlugin)
|
|
@@ -55,6 +33,9 @@ const manualChunks = (id) => {
|
|
|
55
33
|
if (name && manualChunkNames.includes(name))
|
|
56
34
|
return name;
|
|
57
35
|
}
|
|
36
|
+
else if (VIRTUAL_MODULES.some((virtualModule) => id.includes(virtualModule))) {
|
|
37
|
+
return VIRTUAL_MODULES.find((name) => id.includes(name));
|
|
38
|
+
}
|
|
58
39
|
else if (id.includes('node_modules')) {
|
|
59
40
|
return 'vendor';
|
|
60
41
|
}
|
|
@@ -62,7 +43,9 @@ const manualChunks = (id) => {
|
|
|
62
43
|
export const VIRTUAL_MODULES = [
|
|
63
44
|
'virtual:vitrify-hooks',
|
|
64
45
|
'virtual:global-css',
|
|
65
|
-
'virtual:static-imports'
|
|
46
|
+
'virtual:static-imports',
|
|
47
|
+
'vitrify.sass',
|
|
48
|
+
'vitrify.css'
|
|
66
49
|
];
|
|
67
50
|
async function bundleConfigFile(fileName, isESM = false) {
|
|
68
51
|
const result = await build({
|
|
@@ -112,7 +95,7 @@ async function bundleConfigFile(fileName, isESM = false) {
|
|
|
112
95
|
dependencies: result.metafile ? Object.keys(result.metafile.inputs) : []
|
|
113
96
|
};
|
|
114
97
|
}
|
|
115
|
-
export const baseConfig = async ({ ssr, appDir, publicDir, base = '/', command = 'build', mode = 'production', framework = 'vue', pwa = false }) => {
|
|
98
|
+
export const baseConfig = async ({ ssr, appDir, publicDir, base = '/', command = 'build', mode = 'production', framework = 'vue', pwa = false, debug = false }) => {
|
|
116
99
|
const { getAppDir, getCliDir, getCliViteDir, getSrcDir, getCwd } = await import('./app-urls.js');
|
|
117
100
|
if (!appDir) {
|
|
118
101
|
appDir = getAppDir();
|
|
@@ -152,7 +135,7 @@ export const baseConfig = async ({ ssr, appDir, publicDir, base = '/', command =
|
|
|
152
135
|
const packageUrls = vitrifyConfig.vitrify?.urls?.packages || {};
|
|
153
136
|
await (async () => {
|
|
154
137
|
for (const val of localPackages)
|
|
155
|
-
packageUrls[val] = getPkgJsonDir(new URL(await resolve(val, appDir
|
|
138
|
+
packageUrls[val] = getPkgJsonDir(new URL(await resolve(val, appDir)));
|
|
156
139
|
})();
|
|
157
140
|
// await (async () => {
|
|
158
141
|
// for (const val of cliPackages)
|
|
@@ -194,6 +177,7 @@ export const baseConfig = async ({ ssr, appDir, publicDir, base = '/', command =
|
|
|
194
177
|
let staticImports;
|
|
195
178
|
let sassVariables;
|
|
196
179
|
let additionalData;
|
|
180
|
+
let globalSass;
|
|
197
181
|
let serverModules = internalServerModules;
|
|
198
182
|
if (vitrifyConfig.vitrify?.ssr?.serverModules)
|
|
199
183
|
serverModules = [
|
|
@@ -234,17 +218,20 @@ export const baseConfig = async ({ ssr, appDir, publicDir, base = '/', command =
|
|
|
234
218
|
globalCss = config.vitrify?.globalCss || [];
|
|
235
219
|
staticImports = config.vitrify?.staticImports || {};
|
|
236
220
|
sassVariables = config.vitrify?.sass?.variables || {};
|
|
221
|
+
globalSass = config.vitrify?.sass?.global || [];
|
|
237
222
|
additionalData = config.vitrify?.sass?.additionalData || [];
|
|
238
223
|
return {
|
|
239
224
|
css: {
|
|
240
225
|
preprocessorOptions: {
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
226
|
+
// sass: {
|
|
227
|
+
// additionalData: [
|
|
228
|
+
// ...Object.entries(sassVariables).map(
|
|
229
|
+
// ([key, value]) => `${key}: ${value}`
|
|
230
|
+
// )
|
|
231
|
+
// // ...additionalData
|
|
232
|
+
// // config.css?.preprocessorOptions?.sass.additionalData
|
|
233
|
+
// ].join('\n')
|
|
234
|
+
// }
|
|
248
235
|
}
|
|
249
236
|
}
|
|
250
237
|
};
|
|
@@ -257,7 +244,7 @@ export const baseConfig = async ({ ssr, appDir, publicDir, base = '/', command =
|
|
|
257
244
|
},
|
|
258
245
|
resolveId(id) {
|
|
259
246
|
if (VIRTUAL_MODULES.includes(id))
|
|
260
|
-
return { id
|
|
247
|
+
return { id };
|
|
261
248
|
return;
|
|
262
249
|
},
|
|
263
250
|
transform: (code, id) => {
|
|
@@ -300,6 +287,15 @@ export const baseConfig = async ({ ssr, appDir, publicDir, base = '/', command =
|
|
|
300
287
|
.map(([key, value]) => `export { ${value.join(',')} } from '${key}';`)
|
|
301
288
|
.join('\n')}`;
|
|
302
289
|
}
|
|
290
|
+
else if (id === 'vitrify.sass') {
|
|
291
|
+
return [
|
|
292
|
+
...Object.entries(sassVariables).map(([key, value]) => `${key}: ${value}`),
|
|
293
|
+
...globalSass.map((sass) => `@import '${sass}'`)
|
|
294
|
+
].join('\n');
|
|
295
|
+
}
|
|
296
|
+
else if (id === 'vitrify.css') {
|
|
297
|
+
return `${globalCss.map((css) => `import '${css}'`).join('\n')}`;
|
|
298
|
+
}
|
|
303
299
|
return null;
|
|
304
300
|
}
|
|
305
301
|
}
|
|
@@ -357,6 +353,8 @@ export const baseConfig = async ({ ssr, appDir, publicDir, base = '/', command =
|
|
|
357
353
|
}
|
|
358
354
|
}
|
|
359
355
|
});
|
|
356
|
+
if (debug)
|
|
357
|
+
plugins.push(visualizer());
|
|
360
358
|
}
|
|
361
359
|
const alias = [
|
|
362
360
|
{ find: 'src', replacement: srcDir.pathname },
|
|
@@ -377,7 +375,7 @@ export const baseConfig = async ({ ssr, appDir, publicDir, base = '/', command =
|
|
|
377
375
|
if (command === 'test')
|
|
378
376
|
alias.push({
|
|
379
377
|
find: 'vitest',
|
|
380
|
-
replacement: new URL(await resolve('vitest', cliDir
|
|
378
|
+
replacement: new URL(await resolve('vitest', cliDir)).pathname
|
|
381
379
|
});
|
|
382
380
|
let rollupOptions = {};
|
|
383
381
|
let noExternal = [
|
|
@@ -386,6 +384,7 @@ export const baseConfig = async ({ ssr, appDir, publicDir, base = '/', command =
|
|
|
386
384
|
const external = [...builtinModules, ...serverModules];
|
|
387
385
|
if (ssr === 'server') {
|
|
388
386
|
rollupOptions = {
|
|
387
|
+
...rollupOptions,
|
|
389
388
|
input: [
|
|
390
389
|
new URL('ssr/entry-server.ts', frameworkDir).pathname,
|
|
391
390
|
new URL('ssr/prerender.ts', frameworkDir).pathname,
|
|
@@ -393,7 +392,7 @@ export const baseConfig = async ({ ssr, appDir, publicDir, base = '/', command =
|
|
|
393
392
|
],
|
|
394
393
|
external,
|
|
395
394
|
output: {
|
|
396
|
-
minifyInternalExports:
|
|
395
|
+
minifyInternalExports: !debug,
|
|
397
396
|
entryFileNames: '[name].mjs',
|
|
398
397
|
chunkFileNames: '[name].mjs',
|
|
399
398
|
format: 'es',
|
|
@@ -416,6 +415,7 @@ export const baseConfig = async ({ ssr, appDir, publicDir, base = '/', command =
|
|
|
416
415
|
}
|
|
417
416
|
else if (ssr === 'fastify') {
|
|
418
417
|
rollupOptions = {
|
|
418
|
+
...rollupOptions,
|
|
419
419
|
input: [new URL('server.ts', fastifyDir).pathname],
|
|
420
420
|
external,
|
|
421
421
|
output: {
|
|
@@ -441,13 +441,14 @@ export const baseConfig = async ({ ssr, appDir, publicDir, base = '/', command =
|
|
|
441
441
|
}
|
|
442
442
|
else {
|
|
443
443
|
rollupOptions = {
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
444
|
+
...rollupOptions,
|
|
445
|
+
// input: [
|
|
446
|
+
// new URL('index.html', frameworkDir).pathname
|
|
447
|
+
// // new URL('csr/server.ts', frameworkDir).pathname
|
|
448
|
+
// ],
|
|
448
449
|
external,
|
|
449
450
|
output: {
|
|
450
|
-
minifyInternalExports:
|
|
451
|
+
minifyInternalExports: !debug,
|
|
451
452
|
entryFileNames: '[name].mjs',
|
|
452
453
|
chunkFileNames: '[name].mjs',
|
|
453
454
|
format: 'es',
|
package/dist/plugins/quasar.js
CHANGED
|
@@ -3,8 +3,7 @@ import Components from 'unplugin-vue-components/vite';
|
|
|
3
3
|
// import { quasarDir as defaultQuasarDir } from '../app-urls.js'
|
|
4
4
|
// import { QuasarResolver } from '../resolver.js';
|
|
5
5
|
import { QuasarResolver } from 'unplugin-vue-components/resolvers';
|
|
6
|
-
import { getPkgJsonDir } from '../app-urls.js';
|
|
7
|
-
import { resolve } from 'import-meta-resolve';
|
|
6
|
+
import { getPkgJsonDir, resolve } from '../app-urls.js';
|
|
8
7
|
export const injectSsrContext = (html, ssrContext) => html
|
|
9
8
|
.replace(/(<html[^>]*)(>)/i, (found, start, end) => {
|
|
10
9
|
let matches;
|
|
@@ -59,7 +58,7 @@ export const QuasarPlugin = async ({ ssr = false, pwa = false }) => {
|
|
|
59
58
|
const localPackages = ['@quasar/extras', 'quasar'];
|
|
60
59
|
await (async () => {
|
|
61
60
|
for (const val of localPackages)
|
|
62
|
-
urls.packages[val] = getPkgJsonDir(new URL(await resolve(val, urls.app
|
|
61
|
+
urls.packages[val] = getPkgJsonDir(new URL(await resolve(val, urls.app)));
|
|
63
62
|
})();
|
|
64
63
|
const onMountedHooks = [
|
|
65
64
|
async (instance) => {
|
|
@@ -93,7 +92,8 @@ export const QuasarPlugin = async ({ ssr = false, pwa = false }) => {
|
|
|
93
92
|
onRendered: [injectSsrContext]
|
|
94
93
|
},
|
|
95
94
|
sass: {
|
|
96
|
-
|
|
95
|
+
global: ['quasar/src/css/index.sass']
|
|
96
|
+
// additionalData: [`@import 'quasar/src/css/index.sass'`]
|
|
97
97
|
}
|
|
98
98
|
}
|
|
99
99
|
};
|
|
@@ -149,20 +149,17 @@ export const QuasarPlugin = async ({ ssr = false, pwa = false }) => {
|
|
|
149
149
|
find: 'quasar/src',
|
|
150
150
|
replacement: new URL('src/', urls?.packages?.quasar).pathname
|
|
151
151
|
},
|
|
152
|
-
{
|
|
153
|
-
find: new RegExp('^quasar$'),
|
|
154
|
-
replacement: new URL('src/index.all.js', urls?.packages?.quasar)
|
|
155
|
-
.pathname
|
|
156
|
-
},
|
|
157
152
|
// {
|
|
158
|
-
// find: 'quasar',
|
|
159
|
-
// replacement: new URL('src/index.all.js', urls?.packages?.quasar)
|
|
153
|
+
// find: new RegExp('^quasar$'),
|
|
154
|
+
// replacement: new URL('src/index.all.js', urls?.packages?.quasar)
|
|
155
|
+
// .pathname
|
|
160
156
|
// },
|
|
161
157
|
{
|
|
162
158
|
find: `@quasar/extras`,
|
|
163
159
|
replacement: new URL('.', urls?.packages?.['@quasar/extras'])
|
|
164
160
|
.pathname
|
|
165
161
|
}
|
|
162
|
+
// { find: new RegExp('^quasar$'), replacement: 'virtual:quasar' }
|
|
166
163
|
]
|
|
167
164
|
},
|
|
168
165
|
define: {
|
|
@@ -184,7 +181,7 @@ export const QuasarPlugin = async ({ ssr = false, pwa = false }) => {
|
|
|
184
181
|
},
|
|
185
182
|
{
|
|
186
183
|
name: 'quasar-virtual-modules',
|
|
187
|
-
enforce: '
|
|
184
|
+
enforce: 'pre',
|
|
188
185
|
config: async (config, env) => ({
|
|
189
186
|
resolve: {
|
|
190
187
|
alias: [
|
|
@@ -196,8 +193,8 @@ export const QuasarPlugin = async ({ ssr = false, pwa = false }) => {
|
|
|
196
193
|
switch (id) {
|
|
197
194
|
case 'virtual:quasar-plugins':
|
|
198
195
|
return 'virtual:quasar-plugins';
|
|
199
|
-
case '
|
|
200
|
-
return { id: '
|
|
196
|
+
case 'quasar':
|
|
197
|
+
return { id: 'quasar', moduleSideEffects: false };
|
|
201
198
|
default:
|
|
202
199
|
return;
|
|
203
200
|
}
|
|
@@ -206,7 +203,7 @@ export const QuasarPlugin = async ({ ssr = false, pwa = false }) => {
|
|
|
206
203
|
if (id === 'virtual:quasar-plugins') {
|
|
207
204
|
return `export { ${plugins.join(',')} } from 'quasar'`;
|
|
208
205
|
}
|
|
209
|
-
else if (id === '
|
|
206
|
+
else if (id === 'quasar') {
|
|
210
207
|
return `export * from 'quasar/src/plugins.js';
|
|
211
208
|
export * from 'quasar/src/components.js';
|
|
212
209
|
export * from 'quasar/src/composables.js';
|
package/dist/types/app-urls.d.ts
CHANGED
package/dist/types/index.d.ts
CHANGED
|
@@ -3,7 +3,7 @@ import type { BootFunction, VitrifyConfig } from './vitrify-config.js';
|
|
|
3
3
|
import type { VitrifyContext } from './bin/run.js';
|
|
4
4
|
import type { VitrifyPlugin } from './plugins/index.js';
|
|
5
5
|
export declare const VIRTUAL_MODULES: string[];
|
|
6
|
-
export declare const baseConfig: ({ ssr, appDir, publicDir, base, command, mode, framework, pwa }: {
|
|
6
|
+
export declare const baseConfig: ({ ssr, appDir, publicDir, base, command, mode, framework, pwa, debug }: {
|
|
7
7
|
ssr?: "server" | "client" | "ssg" | "fastify" | undefined;
|
|
8
8
|
appDir?: URL | undefined;
|
|
9
9
|
publicDir?: URL | undefined;
|
|
@@ -12,6 +12,7 @@ export declare const baseConfig: ({ ssr, appDir, publicDir, base, command, mode,
|
|
|
12
12
|
mode?: "production" | "development" | undefined;
|
|
13
13
|
framework?: "vue" | undefined;
|
|
14
14
|
pwa?: boolean | undefined;
|
|
15
|
+
debug?: boolean | undefined;
|
|
15
16
|
}) => Promise<InlineConfig>;
|
|
16
17
|
export declare const vitrifyDir: URL;
|
|
17
18
|
export type { VitrifyConfig, VitrifyPlugin, VitrifyContext, BootFunction };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "vitrify",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.4",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"author": "Stefan van Herwijnen",
|
|
6
6
|
"description": "Pre-configured Vite CLI for your framework",
|
|
@@ -64,10 +64,10 @@
|
|
|
64
64
|
"fastify": "^4.0.0",
|
|
65
65
|
"glob": "^8.0.3",
|
|
66
66
|
"happy-dom": "^5.2.0",
|
|
67
|
-
"local-pkg": "^0.4.1",
|
|
68
67
|
"magic-string": "^0.26.2",
|
|
69
68
|
"merge-deep": "^3.0.3",
|
|
70
69
|
"readline": "^1.3.0",
|
|
70
|
+
"rollup-plugin-visualizer": "^5.6.0",
|
|
71
71
|
"sass": "1.52.3",
|
|
72
72
|
"ts-node": "^10.8.1",
|
|
73
73
|
"unplugin-vue-components": "^0.19.6",
|
|
@@ -81,7 +81,6 @@
|
|
|
81
81
|
"@types/node": "^17.0.41",
|
|
82
82
|
"@types/ws": "^8.5.3",
|
|
83
83
|
"@vue/runtime-core": "^3.2.37",
|
|
84
|
-
"import-meta-resolve": "^2.0.3",
|
|
85
84
|
"quasar": "^2.7.1",
|
|
86
85
|
"rollup": "^2.75.6",
|
|
87
86
|
"typescript": "^4.7.3",
|
|
@@ -92,11 +91,9 @@
|
|
|
92
91
|
"peerDependencies": {
|
|
93
92
|
"@fastify/static": "^6.4.0",
|
|
94
93
|
"fastify": "^4.0.0",
|
|
95
|
-
"fastify-plugin": "^3.0.1",
|
|
96
94
|
"quasar": "^2.7.1",
|
|
97
95
|
"vue": "^3.2.37",
|
|
98
|
-
"vue-router": "^4.0.15"
|
|
99
|
-
"import-meta-resolve": "^2.0.3"
|
|
96
|
+
"vue-router": "^4.0.15"
|
|
100
97
|
},
|
|
101
98
|
"publishConfig": {
|
|
102
99
|
"access": "public",
|
package/src/node/app-urls.ts
CHANGED
|
@@ -1,6 +1,14 @@
|
|
|
1
1
|
// import { resolve } from 'import-meta-resolve'
|
|
2
2
|
import { existsSync } from 'fs'
|
|
3
3
|
|
|
4
|
+
export const resolve = (packageName: string, base: URL) => {
|
|
5
|
+
const packageUrl = new URL(`./node_modules/${packageName}/`, base)
|
|
6
|
+
if (existsSync(packageUrl.pathname)) {
|
|
7
|
+
return new URL('./', packageUrl)
|
|
8
|
+
}
|
|
9
|
+
throw new Error(`Package ${packageName} not found in ${base.pathname}.`)
|
|
10
|
+
}
|
|
11
|
+
|
|
4
12
|
export const getPkgJsonDir = (dir: URL): URL => {
|
|
5
13
|
const pkgJsonPath = new URL('package.json', dir)
|
|
6
14
|
if (existsSync(pkgJsonPath.pathname)) {
|
package/src/node/bin/build.ts
CHANGED
|
@@ -8,6 +8,7 @@ export async function build(opts: {
|
|
|
8
8
|
outDir: string
|
|
9
9
|
appDir?: URL
|
|
10
10
|
publicDir?: URL
|
|
11
|
+
debug?: boolean
|
|
11
12
|
}) {
|
|
12
13
|
const config = await baseConfig({
|
|
13
14
|
command: 'build',
|
|
@@ -15,12 +16,13 @@ export async function build(opts: {
|
|
|
15
16
|
ssr: opts?.ssr,
|
|
16
17
|
appDir: opts.appDir,
|
|
17
18
|
publicDir: opts.publicDir,
|
|
18
|
-
base: opts.base
|
|
19
|
+
base: opts.base,
|
|
20
|
+
debug: opts.debug
|
|
19
21
|
})
|
|
20
22
|
|
|
21
23
|
config.build = {
|
|
22
24
|
...config.build,
|
|
23
|
-
minify:
|
|
25
|
+
minify: !opts.debug,
|
|
24
26
|
outDir: opts.outDir,
|
|
25
27
|
emptyOutDir: !!opts.outDir
|
|
26
28
|
}
|
package/src/node/bin/cli.ts
CHANGED
|
@@ -20,6 +20,7 @@ cli
|
|
|
20
20
|
.option('--appDir [appDir]', 'App directory')
|
|
21
21
|
.option('--publicDir [publicDir]', 'Public directory')
|
|
22
22
|
.option('--productName [productName]', 'Product name')
|
|
23
|
+
.option('--debug', 'Debug build')
|
|
23
24
|
.action(async (options) => {
|
|
24
25
|
const { build } = await import('./build.js')
|
|
25
26
|
let appDir: URL
|
|
@@ -38,10 +39,12 @@ cli
|
|
|
38
39
|
base: string
|
|
39
40
|
appDir?: URL
|
|
40
41
|
publicDir?: URL
|
|
42
|
+
debug?: boolean
|
|
41
43
|
} = {
|
|
42
44
|
base: options.base,
|
|
43
45
|
appDir,
|
|
44
|
-
publicDir: parsePath(options.publicDir, appDir)
|
|
46
|
+
publicDir: parsePath(options.publicDir, appDir),
|
|
47
|
+
debug: options.debug
|
|
45
48
|
}
|
|
46
49
|
|
|
47
50
|
switch (options.mode) {
|
package/src/node/bin/dev.ts
CHANGED
package/src/node/index.ts
CHANGED
|
@@ -8,7 +8,8 @@ import path from 'path'
|
|
|
8
8
|
import { pathToFileURL } from 'url'
|
|
9
9
|
import { readFileSync } from 'fs'
|
|
10
10
|
import builtinModules from 'builtin-modules'
|
|
11
|
-
import { resolve } from 'import-meta-resolve'
|
|
11
|
+
// import { resolve } from 'import-meta-resolve'
|
|
12
|
+
import { visualizer } from 'rollup-plugin-visualizer'
|
|
12
13
|
import type {
|
|
13
14
|
StaticImports,
|
|
14
15
|
BootFunction,
|
|
@@ -20,40 +21,17 @@ import type {
|
|
|
20
21
|
} from './vitrify-config.js'
|
|
21
22
|
import type { VitrifyContext } from './bin/run.js'
|
|
22
23
|
import type { VitrifyPlugin } from './plugins/index.js'
|
|
23
|
-
import { getPkgJsonDir } from './app-urls.js'
|
|
24
|
-
import type { RollupOptions } from 'rollup'
|
|
24
|
+
import { getPkgJsonDir, resolve } from './app-urls.js'
|
|
25
|
+
import type { ManualChunksOption, RollupOptions } from 'rollup'
|
|
25
26
|
|
|
26
27
|
const internalServerModules = [
|
|
27
|
-
// 'fs',
|
|
28
|
-
// 'path',
|
|
29
|
-
// 'url',
|
|
30
|
-
// 'module',
|
|
31
|
-
// 'crypto',
|
|
32
|
-
// 'node:fs',
|
|
33
28
|
'util',
|
|
34
|
-
'node:url',
|
|
35
|
-
'node:util',
|
|
36
|
-
'node:fs',
|
|
37
|
-
'node:process',
|
|
38
29
|
'vitrify',
|
|
39
30
|
'vitrify/dev',
|
|
40
|
-
// 'import-meta-resolve',
|
|
41
31
|
'vite',
|
|
42
32
|
'fastify',
|
|
43
|
-
'@fastify',
|
|
33
|
+
'@fastify/static',
|
|
44
34
|
'node'
|
|
45
|
-
// 'middie',
|
|
46
|
-
// 'knex',
|
|
47
|
-
// 'bcrypt',
|
|
48
|
-
// 'objection',
|
|
49
|
-
// '@fastify/formbody',
|
|
50
|
-
// '@fastify/static',
|
|
51
|
-
// '@fastify/cors',
|
|
52
|
-
// '@fastify/cookie',
|
|
53
|
-
// 'mercurius',
|
|
54
|
-
// 'jose',
|
|
55
|
-
// 'oidc-provider',
|
|
56
|
-
// 'node-fetch'
|
|
57
35
|
]
|
|
58
36
|
|
|
59
37
|
const configPluginMap: Record<string, () => Promise<VitrifyPlugin>> = {
|
|
@@ -67,10 +45,14 @@ const manualChunkNames = [
|
|
|
67
45
|
'fastify-csr-plugin',
|
|
68
46
|
'server'
|
|
69
47
|
]
|
|
70
|
-
const manualChunks = (id: string) => {
|
|
48
|
+
const manualChunks: ManualChunksOption = (id: string) => {
|
|
71
49
|
if (id.includes('vitrify/src/vite/')) {
|
|
72
50
|
const name = id.split('/').at(-1)?.split('.').at(0)
|
|
73
51
|
if (name && manualChunkNames.includes(name)) return name
|
|
52
|
+
} else if (
|
|
53
|
+
VIRTUAL_MODULES.some((virtualModule) => id.includes(virtualModule))
|
|
54
|
+
) {
|
|
55
|
+
return VIRTUAL_MODULES.find((name) => id.includes(name))
|
|
74
56
|
} else if (id.includes('node_modules')) {
|
|
75
57
|
return 'vendor'
|
|
76
58
|
}
|
|
@@ -79,7 +61,9 @@ const manualChunks = (id: string) => {
|
|
|
79
61
|
export const VIRTUAL_MODULES = [
|
|
80
62
|
'virtual:vitrify-hooks',
|
|
81
63
|
'virtual:global-css',
|
|
82
|
-
'virtual:static-imports'
|
|
64
|
+
'virtual:static-imports',
|
|
65
|
+
'vitrify.sass',
|
|
66
|
+
'vitrify.css'
|
|
83
67
|
]
|
|
84
68
|
|
|
85
69
|
async function bundleConfigFile(
|
|
@@ -148,7 +132,8 @@ export const baseConfig = async ({
|
|
|
148
132
|
command = 'build',
|
|
149
133
|
mode = 'production',
|
|
150
134
|
framework = 'vue',
|
|
151
|
-
pwa = false
|
|
135
|
+
pwa = false,
|
|
136
|
+
debug = false
|
|
152
137
|
}: {
|
|
153
138
|
ssr?: 'client' | 'server' | 'ssg' | 'fastify'
|
|
154
139
|
appDir?: URL
|
|
@@ -158,6 +143,7 @@ export const baseConfig = async ({
|
|
|
158
143
|
mode?: 'production' | 'development'
|
|
159
144
|
framework?: 'vue'
|
|
160
145
|
pwa?: boolean
|
|
146
|
+
debug?: boolean
|
|
161
147
|
}): Promise<InlineConfig> => {
|
|
162
148
|
const { getAppDir, getCliDir, getCliViteDir, getSrcDir, getCwd } =
|
|
163
149
|
await import('./app-urls.js')
|
|
@@ -212,9 +198,7 @@ export const baseConfig = async ({
|
|
|
212
198
|
vitrifyConfig.vitrify?.urls?.packages || {}
|
|
213
199
|
await (async () => {
|
|
214
200
|
for (const val of localPackages)
|
|
215
|
-
packageUrls[val] = getPkgJsonDir(
|
|
216
|
-
new URL(await resolve(val, appDir!.href))
|
|
217
|
-
)
|
|
201
|
+
packageUrls[val] = getPkgJsonDir(new URL(await resolve(val, appDir)))
|
|
218
202
|
})()
|
|
219
203
|
|
|
220
204
|
// await (async () => {
|
|
@@ -263,6 +247,7 @@ export const baseConfig = async ({
|
|
|
263
247
|
let staticImports: StaticImports
|
|
264
248
|
let sassVariables: Record<string, string>
|
|
265
249
|
let additionalData: string[]
|
|
250
|
+
let globalSass: string[]
|
|
266
251
|
let serverModules: string[] = internalServerModules
|
|
267
252
|
|
|
268
253
|
if (vitrifyConfig.vitrify?.ssr?.serverModules)
|
|
@@ -305,20 +290,21 @@ export const baseConfig = async ({
|
|
|
305
290
|
globalCss = config.vitrify?.globalCss || []
|
|
306
291
|
staticImports = config.vitrify?.staticImports || {}
|
|
307
292
|
sassVariables = config.vitrify?.sass?.variables || {}
|
|
293
|
+
globalSass = config.vitrify?.sass?.global || []
|
|
308
294
|
additionalData = config.vitrify?.sass?.additionalData || []
|
|
309
295
|
|
|
310
296
|
return {
|
|
311
297
|
css: {
|
|
312
298
|
preprocessorOptions: {
|
|
313
|
-
sass: {
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
}
|
|
299
|
+
// sass: {
|
|
300
|
+
// additionalData: [
|
|
301
|
+
// ...Object.entries(sassVariables).map(
|
|
302
|
+
// ([key, value]) => `${key}: ${value}`
|
|
303
|
+
// )
|
|
304
|
+
// // ...additionalData
|
|
305
|
+
// // config.css?.preprocessorOptions?.sass.additionalData
|
|
306
|
+
// ].join('\n')
|
|
307
|
+
// }
|
|
322
308
|
}
|
|
323
309
|
}
|
|
324
310
|
}
|
|
@@ -330,8 +316,7 @@ export const baseConfig = async ({
|
|
|
330
316
|
}
|
|
331
317
|
},
|
|
332
318
|
resolveId(id) {
|
|
333
|
-
if (VIRTUAL_MODULES.includes(id))
|
|
334
|
-
return { id, moduleSideEffects: false }
|
|
319
|
+
if (VIRTUAL_MODULES.includes(id)) return { id }
|
|
335
320
|
return
|
|
336
321
|
},
|
|
337
322
|
transform: (code, id) => {
|
|
@@ -379,6 +364,15 @@ export const baseConfig = async ({
|
|
|
379
364
|
([key, value]) => `export { ${value.join(',')} } from '${key}';`
|
|
380
365
|
)
|
|
381
366
|
.join('\n')}`
|
|
367
|
+
} else if (id === 'vitrify.sass') {
|
|
368
|
+
return [
|
|
369
|
+
...Object.entries(sassVariables).map(
|
|
370
|
+
([key, value]) => `${key}: ${value}`
|
|
371
|
+
),
|
|
372
|
+
...globalSass.map((sass) => `@import '${sass}'`)
|
|
373
|
+
].join('\n')
|
|
374
|
+
} else if (id === 'vitrify.css') {
|
|
375
|
+
return `${globalCss.map((css) => `import '${css}'`).join('\n')}`
|
|
382
376
|
}
|
|
383
377
|
return null
|
|
384
378
|
}
|
|
@@ -438,6 +432,8 @@ export const baseConfig = async ({
|
|
|
438
432
|
}
|
|
439
433
|
}
|
|
440
434
|
})
|
|
435
|
+
|
|
436
|
+
if (debug) plugins.push(visualizer())
|
|
441
437
|
}
|
|
442
438
|
|
|
443
439
|
const alias: Alias[] = [
|
|
@@ -460,7 +456,7 @@ export const baseConfig = async ({
|
|
|
460
456
|
if (command === 'test')
|
|
461
457
|
alias.push({
|
|
462
458
|
find: 'vitest',
|
|
463
|
-
replacement: new URL(await resolve('vitest', cliDir
|
|
459
|
+
replacement: new URL(await resolve('vitest', cliDir)).pathname
|
|
464
460
|
})
|
|
465
461
|
|
|
466
462
|
let rollupOptions: RollupOptions = {}
|
|
@@ -471,6 +467,7 @@ export const baseConfig = async ({
|
|
|
471
467
|
|
|
472
468
|
if (ssr === 'server') {
|
|
473
469
|
rollupOptions = {
|
|
470
|
+
...rollupOptions,
|
|
474
471
|
input: [
|
|
475
472
|
new URL('ssr/entry-server.ts', frameworkDir).pathname,
|
|
476
473
|
new URL('ssr/prerender.ts', frameworkDir).pathname,
|
|
@@ -478,7 +475,7 @@ export const baseConfig = async ({
|
|
|
478
475
|
],
|
|
479
476
|
external,
|
|
480
477
|
output: {
|
|
481
|
-
minifyInternalExports:
|
|
478
|
+
minifyInternalExports: !debug,
|
|
482
479
|
entryFileNames: '[name].mjs',
|
|
483
480
|
chunkFileNames: '[name].mjs',
|
|
484
481
|
format: 'es',
|
|
@@ -500,6 +497,7 @@ export const baseConfig = async ({
|
|
|
500
497
|
]
|
|
501
498
|
} else if (ssr === 'fastify') {
|
|
502
499
|
rollupOptions = {
|
|
500
|
+
...rollupOptions,
|
|
503
501
|
input: [new URL('server.ts', fastifyDir).pathname],
|
|
504
502
|
external,
|
|
505
503
|
output: {
|
|
@@ -524,13 +522,14 @@ export const baseConfig = async ({
|
|
|
524
522
|
]
|
|
525
523
|
} else {
|
|
526
524
|
rollupOptions = {
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
525
|
+
...rollupOptions,
|
|
526
|
+
// input: [
|
|
527
|
+
// new URL('index.html', frameworkDir).pathname
|
|
528
|
+
// // new URL('csr/server.ts', frameworkDir).pathname
|
|
529
|
+
// ],
|
|
531
530
|
external,
|
|
532
531
|
output: {
|
|
533
|
-
minifyInternalExports:
|
|
532
|
+
minifyInternalExports: !debug,
|
|
534
533
|
entryFileNames: '[name].mjs',
|
|
535
534
|
chunkFileNames: '[name].mjs',
|
|
536
535
|
format: 'es',
|
|
@@ -12,8 +12,9 @@ import type {
|
|
|
12
12
|
// import { QuasarResolver } from '../resolver.js';
|
|
13
13
|
import { QuasarResolver } from 'unplugin-vue-components/resolvers'
|
|
14
14
|
import type { VitrifyPlugin } from './index.js'
|
|
15
|
-
import { getPkgJsonDir } from '../app-urls.js'
|
|
16
|
-
|
|
15
|
+
import { getPkgJsonDir, resolve } from '../app-urls.js'
|
|
16
|
+
|
|
17
|
+
// import { resolve } from 'import-meta-resolve'
|
|
17
18
|
|
|
18
19
|
export interface QuasarConf {
|
|
19
20
|
ctx: Record<string, any>
|
|
@@ -122,7 +123,7 @@ export const QuasarPlugin: VitrifyPlugin = async ({
|
|
|
122
123
|
await (async () => {
|
|
123
124
|
for (const val of localPackages)
|
|
124
125
|
urls!.packages![val] = getPkgJsonDir(
|
|
125
|
-
new URL(await resolve(val, urls!.app
|
|
126
|
+
new URL(await resolve(val, urls!.app!))
|
|
126
127
|
)
|
|
127
128
|
})()
|
|
128
129
|
|
|
@@ -167,7 +168,8 @@ export const QuasarPlugin: VitrifyPlugin = async ({
|
|
|
167
168
|
onRendered: [injectSsrContext]
|
|
168
169
|
},
|
|
169
170
|
sass: {
|
|
170
|
-
|
|
171
|
+
global: ['quasar/src/css/index.sass']
|
|
172
|
+
// additionalData: [`@import 'quasar/src/css/index.sass'`]
|
|
171
173
|
}
|
|
172
174
|
}
|
|
173
175
|
}
|
|
@@ -231,7 +233,6 @@ export const QuasarPlugin: VitrifyPlugin = async ({
|
|
|
231
233
|
urls?.packages?.quasar
|
|
232
234
|
).pathname
|
|
233
235
|
},
|
|
234
|
-
|
|
235
236
|
{
|
|
236
237
|
find: 'quasar/directives',
|
|
237
238
|
replacement: new URL(
|
|
@@ -243,20 +244,17 @@ export const QuasarPlugin: VitrifyPlugin = async ({
|
|
|
243
244
|
find: 'quasar/src',
|
|
244
245
|
replacement: new URL('src/', urls?.packages?.quasar).pathname
|
|
245
246
|
},
|
|
246
|
-
{
|
|
247
|
-
find: new RegExp('^quasar$'),
|
|
248
|
-
replacement: new URL('src/index.all.js', urls?.packages?.quasar)
|
|
249
|
-
.pathname
|
|
250
|
-
},
|
|
251
247
|
// {
|
|
252
|
-
// find: 'quasar',
|
|
253
|
-
// replacement: new URL('src/index.all.js', urls?.packages?.quasar)
|
|
248
|
+
// find: new RegExp('^quasar$'),
|
|
249
|
+
// replacement: new URL('src/index.all.js', urls?.packages?.quasar)
|
|
250
|
+
// .pathname
|
|
254
251
|
// },
|
|
255
252
|
{
|
|
256
253
|
find: `@quasar/extras`,
|
|
257
254
|
replacement: new URL('.', urls?.packages?.['@quasar/extras'])
|
|
258
255
|
.pathname
|
|
259
256
|
}
|
|
257
|
+
// { find: new RegExp('^quasar$'), replacement: 'virtual:quasar' }
|
|
260
258
|
]
|
|
261
259
|
},
|
|
262
260
|
define: {
|
|
@@ -278,7 +276,7 @@ export const QuasarPlugin: VitrifyPlugin = async ({
|
|
|
278
276
|
},
|
|
279
277
|
{
|
|
280
278
|
name: 'quasar-virtual-modules',
|
|
281
|
-
enforce: '
|
|
279
|
+
enforce: 'pre',
|
|
282
280
|
config: async (config, env) => ({
|
|
283
281
|
resolve: {
|
|
284
282
|
alias: [
|
|
@@ -290,8 +288,8 @@ export const QuasarPlugin: VitrifyPlugin = async ({
|
|
|
290
288
|
switch (id) {
|
|
291
289
|
case 'virtual:quasar-plugins':
|
|
292
290
|
return 'virtual:quasar-plugins'
|
|
293
|
-
case '
|
|
294
|
-
return { id: '
|
|
291
|
+
case 'quasar':
|
|
292
|
+
return { id: 'quasar', moduleSideEffects: false }
|
|
295
293
|
default:
|
|
296
294
|
return
|
|
297
295
|
}
|
|
@@ -299,7 +297,7 @@ export const QuasarPlugin: VitrifyPlugin = async ({
|
|
|
299
297
|
load(id) {
|
|
300
298
|
if (id === 'virtual:quasar-plugins') {
|
|
301
299
|
return `export { ${plugins.join(',')} } from 'quasar'`
|
|
302
|
-
} else if (id === '
|
|
300
|
+
} else if (id === 'quasar') {
|
|
303
301
|
return `export * from 'quasar/src/plugins.js';
|
|
304
302
|
export * from 'quasar/src/components.js';
|
|
305
303
|
export * from 'quasar/src/composables.js';
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import type { FastifyInstance } from 'fastify'
|
|
2
1
|
import type { Alias, UserConfig } from 'vite'
|
|
3
2
|
import type { QuasarConf } from './plugins/quasar.js'
|
|
4
3
|
import type { ComponentInternalInstance } from '@vue/runtime-core'
|
|
@@ -72,6 +71,7 @@ export interface VitrifyConfig extends UserConfig {
|
|
|
72
71
|
sass?: {
|
|
73
72
|
variables?: Record<string, string>
|
|
74
73
|
additionalData?: string[]
|
|
74
|
+
global?: string[]
|
|
75
75
|
}
|
|
76
76
|
/**
|
|
77
77
|
* Product name of the application. Will be used for the HTML title tag
|
package/src/vite/vue/csr/app.ts
CHANGED
|
@@ -4,22 +4,21 @@ import { getAppDir } from '../../../node/app-urls.js'
|
|
|
4
4
|
import { onRendered, onSetup } from 'virtual:vitrify-hooks'
|
|
5
5
|
import { fastifyCsrPlugin } from './fastify-csr-plugin.js'
|
|
6
6
|
import type { ViteDevServer } from 'vite'
|
|
7
|
-
|
|
8
|
-
const { resolve } = imr
|
|
7
|
+
|
|
9
8
|
// const appDir = getPkgJsonDir(import.meta.url)
|
|
10
9
|
const getString = (str?: string) => str
|
|
11
10
|
let baseUrl = getString(__BASE_URL__)
|
|
12
11
|
const appDir = getAppDir()
|
|
13
12
|
|
|
14
13
|
export const setupApp = async () => {
|
|
15
|
-
const vitrifyDir = new URL('../', await resolve('vitrify', import.meta.url))
|
|
14
|
+
// const vitrifyDir = new URL('../', await resolve('vitrify', new URL(import.meta.url)))
|
|
16
15
|
return createApp({
|
|
17
16
|
onSetup,
|
|
18
17
|
appDir,
|
|
19
18
|
baseUrl,
|
|
20
19
|
onRendered,
|
|
21
20
|
fastifyPlugin: fastifyCsrPlugin,
|
|
22
|
-
vitrifyDir,
|
|
21
|
+
// vitrifyDir,
|
|
23
22
|
mode: import.meta.env.MODE
|
|
24
23
|
})
|
|
25
24
|
}
|
package/src/vite/vue/main.ts
CHANGED
package/src/vite/vue/ssr/app.ts
CHANGED
|
@@ -4,22 +4,21 @@ import { getAppDir } from '../../../node/app-urls.js'
|
|
|
4
4
|
import { onRendered, onSetup } from 'virtual:vitrify-hooks'
|
|
5
5
|
import { fastifySsrPlugin } from './fastify-ssr-plugin.js'
|
|
6
6
|
import type { ViteDevServer } from 'vite'
|
|
7
|
-
|
|
8
|
-
const { resolve } = imr
|
|
7
|
+
|
|
9
8
|
// const appDir = getPkgJsonDir(import.meta.url)
|
|
10
9
|
const getString = (str?: string) => str
|
|
11
10
|
let baseUrl = getString(__BASE_URL__)
|
|
12
11
|
const appDir = getAppDir()
|
|
13
12
|
|
|
14
13
|
export const setupApp = async () => {
|
|
15
|
-
const vitrifyDir = new URL('../', await resolve('vitrify', import.meta.url))
|
|
14
|
+
// const vitrifyDir = new URL('../', await resolve('vitrify', new URL(import.meta.url)))
|
|
16
15
|
return createApp({
|
|
17
16
|
onSetup,
|
|
18
17
|
appDir,
|
|
19
18
|
baseUrl,
|
|
20
19
|
onRendered,
|
|
21
20
|
fastifyPlugin: fastifySsrPlugin,
|
|
22
|
-
vitrifyDir,
|
|
21
|
+
// vitrifyDir,
|
|
23
22
|
mode: import.meta.env.MODE
|
|
24
23
|
})
|
|
25
24
|
}
|