vuetify-nuxt-module 1.0.0-beta.1 → 1.0.0-beta.11
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/README.md +16 -19
- package/configuration.d.ts +3 -0
- package/dist/module.d.mts +55 -1
- package/dist/module.json +1 -1
- package/dist/module.mjs +320 -379
- package/dist/runtime/plugins/first-request-reload-guard.d.ts +13 -0
- package/dist/runtime/plugins/first-request-reload-guard.js +11 -0
- package/dist/runtime/plugins/i18n.js +6 -1
- package/dist/runtime/plugins/vuetify-client-hints.client.js +21 -7
- package/dist/runtime/plugins/vuetify-client-hints.server.js +14 -2
- package/package.json +16 -14
package/dist/module.mjs
CHANGED
|
@@ -1,24 +1,19 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { existsSync, statSync, readFileSync } from 'node:fs';
|
|
2
|
+
import { pathToFileURL, fileURLToPath } from 'node:url';
|
|
3
|
+
import { addPluginTemplate, resolvePath, addTemplate, extendWebpackConfig, isNuxtMajorVersion, addImports, addPlugin, addVitePlugin, useLogger, defineNuxtModule, getNuxtVersion, findPath, hasNuxtModule, createResolver } from '@nuxt/kit';
|
|
4
|
+
import { isAbsolute, resolve, dirname } from 'pathe';
|
|
3
5
|
import semver from 'semver';
|
|
4
6
|
import { createFilter, version as version$1 } from 'vite';
|
|
5
|
-
import fs, { existsSync, statSync, readFileSync, readdirSync, rmSync, mkdirSync, writeFileSync } from 'node:fs';
|
|
6
|
-
import { isAbsolute, resolve, relative } from 'pathe';
|
|
7
7
|
import defu from 'defu';
|
|
8
|
-
import { transformAssetUrls } from '
|
|
9
|
-
import
|
|
10
|
-
import {
|
|
11
|
-
import destr from 'destr';
|
|
8
|
+
import { transformAssetUrls, generateImports } from '@vuetify/loader-shared';
|
|
9
|
+
import Styles from '@vuetify/unplugin-styles/vite';
|
|
10
|
+
import { isPackageExists } from 'local-pkg';
|
|
12
11
|
import { parseQuery, parseURL } from 'ufo';
|
|
13
|
-
import
|
|
14
|
-
import path from 'upath';
|
|
15
|
-
import { resolve as resolve$1, dirname, join, relative as relative$1 } from 'node:path';
|
|
16
|
-
import { debounce } from 'perfect-debounce';
|
|
12
|
+
import { readFile } from 'node:fs/promises';
|
|
17
13
|
import process from 'node:process';
|
|
18
14
|
import { createConfigLoader } from 'unconfig';
|
|
19
|
-
import { createHash } from 'node:crypto';
|
|
20
15
|
|
|
21
|
-
const version = "1.0.0-beta.
|
|
16
|
+
const version = "1.0.0-beta.11";
|
|
22
17
|
|
|
23
18
|
const VIRTUAL_VUETIFY_CONFIGURATION = "virtual:vuetify-configuration";
|
|
24
19
|
const RESOLVED_VIRTUAL_VUETIFY_CONFIGURATION = `\0${VIRTUAL_VUETIFY_CONFIGURATION}`;
|
|
@@ -128,6 +123,18 @@ function normalizeTransformAssetUrlsAttrs(attrs) {
|
|
|
128
123
|
return [...result];
|
|
129
124
|
}
|
|
130
125
|
|
|
126
|
+
function resolveVuetifyConfigFile(configFile, nuxt) {
|
|
127
|
+
if (typeof configFile === "string" && !isAbsolute(configFile)) {
|
|
128
|
+
for (const layer of nuxt.options._layers) {
|
|
129
|
+
const resolved = resolve(layer.config.srcDir, configFile);
|
|
130
|
+
if (existsSync(resolved)) {
|
|
131
|
+
return resolved;
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
return configFile;
|
|
136
|
+
}
|
|
137
|
+
|
|
131
138
|
function addVuetifyNuxtPlugins(nuxt, ctx) {
|
|
132
139
|
addVuetifyNuxtPlugin(nuxt, ctx, "client");
|
|
133
140
|
addVuetifyNuxtPlugin(nuxt, ctx, "server");
|
|
@@ -198,17 +205,6 @@ export default defineNuxtPlugin({
|
|
|
198
205
|
function getTemplate(source, settings) {
|
|
199
206
|
return [settings ? `@use '${settings}';` : "", `@use '${source}';`].filter(Boolean).join("\n");
|
|
200
207
|
}
|
|
201
|
-
function resolveVuetifyConfigFile(configFile, nuxt) {
|
|
202
|
-
if (typeof configFile === "string" && !isAbsolute(configFile)) {
|
|
203
|
-
for (const layer of nuxt.options._layers) {
|
|
204
|
-
const resolved = resolve(layer.config.rootDir, configFile);
|
|
205
|
-
if (existsSync(resolved)) {
|
|
206
|
-
return resolved;
|
|
207
|
-
}
|
|
208
|
-
}
|
|
209
|
-
}
|
|
210
|
-
return configFile;
|
|
211
|
-
}
|
|
212
208
|
async function configureNuxt(configKey, nuxt, ctx) {
|
|
213
209
|
const {
|
|
214
210
|
styles,
|
|
@@ -223,9 +219,14 @@ async function configureNuxt(configKey, nuxt, ctx) {
|
|
|
223
219
|
nuxt.options.css ??= [];
|
|
224
220
|
if (typeof styles === "object" && "configFile" in styles) {
|
|
225
221
|
const configFile = resolveVuetifyConfigFile(styles.configFile, nuxt);
|
|
222
|
+
ctx.stylesConfigFile = await resolvePath(configFile);
|
|
226
223
|
const a = addTemplate({
|
|
227
|
-
|
|
228
|
-
|
|
224
|
+
// Write to disk: without `write` Nuxt serves the template from its
|
|
225
|
+
// virtual FS, which 404s on Windows/SSR when the browser requests the
|
|
226
|
+
// real file (#363). Nest under `vuetify/` to match unplugin-styles.
|
|
227
|
+
write: true,
|
|
228
|
+
filename: "vuetify/vuetify.settings.scss",
|
|
229
|
+
getContents: async () => getTemplate("vuetify/styles", ctx.stylesConfigFile)
|
|
229
230
|
});
|
|
230
231
|
nuxt.options.css.push(a.dst);
|
|
231
232
|
} else if (ctx.vuetifyGte("4.0.0")) {
|
|
@@ -352,6 +353,11 @@ function vuetifyConfigurationPlugin(ctx) {
|
|
|
352
353
|
},
|
|
353
354
|
async load(id) {
|
|
354
355
|
if (id === RESOLVED_VIRTUAL_VUETIFY_CONFIGURATION) {
|
|
356
|
+
if (ctx.isDev && ctx.canHmrConfig) {
|
|
357
|
+
for (const file of ctx.vuetifyFilesToWatch) {
|
|
358
|
+
this.addWatchFile(file);
|
|
359
|
+
}
|
|
360
|
+
}
|
|
355
361
|
const {
|
|
356
362
|
directives: _directives,
|
|
357
363
|
date: _date,
|
|
@@ -373,7 +379,12 @@ function vuetifyConfigurationPlugin(ctx) {
|
|
|
373
379
|
}
|
|
374
380
|
const result = await buildConfiguration(ctx);
|
|
375
381
|
const deepCopy = result.messages.length > 0;
|
|
376
|
-
|
|
382
|
+
let configDepImports = "";
|
|
383
|
+
if (ctx.isDev && ctx.canHmrConfig && this.environment?.name === "ssr") {
|
|
384
|
+
configDepImports = ctx.vuetifyFilesToWatch.map((file) => `import ${JSON.stringify(file)}`).join("\n");
|
|
385
|
+
}
|
|
386
|
+
return `${configDepImports}
|
|
387
|
+
${result.imports}
|
|
377
388
|
|
|
378
389
|
export const isDev = ${ctx.isDev}
|
|
379
390
|
export function vuetifyConfiguration() {
|
|
@@ -592,6 +603,70 @@ ${useLocales.map((locale) => {
|
|
|
592
603
|
};
|
|
593
604
|
}
|
|
594
605
|
|
|
606
|
+
const VUETIFY_TO_DATE_FNS = {
|
|
607
|
+
en: "enUS",
|
|
608
|
+
fa: "faIR",
|
|
609
|
+
no: "nb",
|
|
610
|
+
srCyrl: "sr",
|
|
611
|
+
zhHans: "zhCN",
|
|
612
|
+
zhHant: "zhTW"
|
|
613
|
+
};
|
|
614
|
+
const DATE_FNS_SUPPORTED = /* @__PURE__ */ new Set([
|
|
615
|
+
"af",
|
|
616
|
+
"ar",
|
|
617
|
+
"az",
|
|
618
|
+
"bg",
|
|
619
|
+
"ca",
|
|
620
|
+
"ckb",
|
|
621
|
+
"cs",
|
|
622
|
+
"da",
|
|
623
|
+
"de",
|
|
624
|
+
"el",
|
|
625
|
+
"enUS",
|
|
626
|
+
"es",
|
|
627
|
+
"et",
|
|
628
|
+
"faIR",
|
|
629
|
+
"fi",
|
|
630
|
+
"fr",
|
|
631
|
+
"he",
|
|
632
|
+
"hr",
|
|
633
|
+
"hu",
|
|
634
|
+
"id",
|
|
635
|
+
"it",
|
|
636
|
+
"ja",
|
|
637
|
+
"km",
|
|
638
|
+
"ko",
|
|
639
|
+
"lt",
|
|
640
|
+
"lv",
|
|
641
|
+
"nb",
|
|
642
|
+
"nl",
|
|
643
|
+
"pl",
|
|
644
|
+
"pt",
|
|
645
|
+
"ro",
|
|
646
|
+
"ru",
|
|
647
|
+
"sk",
|
|
648
|
+
"sl",
|
|
649
|
+
"sr",
|
|
650
|
+
"srLatn",
|
|
651
|
+
"sv",
|
|
652
|
+
"th",
|
|
653
|
+
"tr",
|
|
654
|
+
"uk",
|
|
655
|
+
"vi",
|
|
656
|
+
"zhCN",
|
|
657
|
+
"zhTW"
|
|
658
|
+
]);
|
|
659
|
+
function resolveDateFnsLocaleName(code) {
|
|
660
|
+
if (!code) {
|
|
661
|
+
return { name: "enUS", fallback: true };
|
|
662
|
+
}
|
|
663
|
+
const candidate = VUETIFY_TO_DATE_FNS[code] ?? code;
|
|
664
|
+
if (DATE_FNS_SUPPORTED.has(candidate)) {
|
|
665
|
+
return { name: candidate, fallback: false };
|
|
666
|
+
}
|
|
667
|
+
return { name: "enUS", fallback: true };
|
|
668
|
+
}
|
|
669
|
+
|
|
595
670
|
function vuetifyDateConfigurationPlugin(ctx) {
|
|
596
671
|
return {
|
|
597
672
|
name: "vuetify:date-configuration:nuxt",
|
|
@@ -603,6 +678,11 @@ function vuetifyDateConfigurationPlugin(ctx) {
|
|
|
603
678
|
},
|
|
604
679
|
async load(id) {
|
|
605
680
|
if (id === RESOLVED_VIRTUAL_VUETIFY_DATE_CONFIGURATION) {
|
|
681
|
+
if (ctx.isDev && ctx.canHmrConfig) {
|
|
682
|
+
for (const file of ctx.vuetifyFilesToWatch) {
|
|
683
|
+
this.addWatchFile(file);
|
|
684
|
+
}
|
|
685
|
+
}
|
|
606
686
|
if (!ctx.dateAdapter) {
|
|
607
687
|
return `
|
|
608
688
|
export const enabled = false
|
|
@@ -615,34 +695,41 @@ export function dateConfiguration() {
|
|
|
615
695
|
`;
|
|
616
696
|
}
|
|
617
697
|
const { adapter: _adapter, ...newDateOptions } = ctx.vuetifyOptions.date ?? {};
|
|
618
|
-
|
|
698
|
+
let dateFnsLocale;
|
|
699
|
+
if (ctx.dateAdapter === "date-fns") {
|
|
700
|
+
const resolved = resolveDateFnsLocaleName(ctx.vuetifyOptions.locale?.locale);
|
|
701
|
+
dateFnsLocale = resolved.name;
|
|
702
|
+
if (resolved.fallback) {
|
|
703
|
+
ctx.logger.warn(`[vuetify-nuxt-module] date-fns locale for "${ctx.vuetifyOptions.locale?.locale ?? "(unset)"}" not found, falling back to "enUS". Set "vuetifyOptions.locale.locale" to a supported locale.`);
|
|
704
|
+
}
|
|
705
|
+
}
|
|
706
|
+
return `${buildImports(dateFnsLocale)}
|
|
619
707
|
export const enabled = true
|
|
620
708
|
export const isDev = ${ctx.isDev}
|
|
621
709
|
export const i18n = ${ctx.i18n}
|
|
622
710
|
export const adapter = '${ctx.dateAdapter}'
|
|
623
711
|
export function dateConfiguration() {
|
|
624
712
|
const options = JSON.parse('${JSON.stringify(newDateOptions)}')
|
|
625
|
-
${buildAdapter()}
|
|
713
|
+
${buildAdapter(dateFnsLocale)}
|
|
626
714
|
return options
|
|
627
715
|
}
|
|
628
716
|
`;
|
|
629
717
|
}
|
|
630
718
|
}
|
|
631
719
|
};
|
|
632
|
-
function buildAdapter() {
|
|
720
|
+
function buildAdapter(dateFnsLocale) {
|
|
633
721
|
if (ctx.dateAdapter === "custom" || ctx.dateAdapter === "vuetify" && ctx.vuetifyGte("3.4.0")) {
|
|
634
722
|
return "";
|
|
635
723
|
}
|
|
636
724
|
if (ctx.dateAdapter === "vuetify") {
|
|
637
725
|
return "options.adapter = VuetifyDateAdapter";
|
|
638
726
|
}
|
|
639
|
-
const locale = ctx.vuetifyOptions.locale?.locale ?? "en";
|
|
640
727
|
if (ctx.dateAdapter === "date-fns") {
|
|
641
|
-
return `options.adapter = new Adapter({ locale: ${
|
|
728
|
+
return `options.adapter = new Adapter({ locale: ${dateFnsLocale} })`;
|
|
642
729
|
}
|
|
643
730
|
return "options.adapter = Adapter";
|
|
644
731
|
}
|
|
645
|
-
function buildImports() {
|
|
732
|
+
function buildImports(dateFnsLocale) {
|
|
646
733
|
if (ctx.dateAdapter === "custom" || ctx.dateAdapter === "vuetify" && ctx.vuetifyGte("3.4.0")) {
|
|
647
734
|
return "";
|
|
648
735
|
}
|
|
@@ -651,7 +738,7 @@ export function dateConfiguration() {
|
|
|
651
738
|
}
|
|
652
739
|
const imports = [`import Adapter from '@date-io/${ctx.dateAdapter}'`];
|
|
653
740
|
if (ctx.dateAdapter === "date-fns") {
|
|
654
|
-
imports.push(`import { ${
|
|
741
|
+
imports.push(`import { ${dateFnsLocale} } from 'date-fns/locale'`);
|
|
655
742
|
}
|
|
656
743
|
return imports.join("\n");
|
|
657
744
|
}
|
|
@@ -668,6 +755,11 @@ function vuetifyIconsPlugin(ctx) {
|
|
|
668
755
|
},
|
|
669
756
|
async load(id) {
|
|
670
757
|
if (id === RESOLVED_VIRTUAL_VUETIFY_ICONS_CONFIGURATION) {
|
|
758
|
+
if (ctx.isDev && ctx.canHmrConfig) {
|
|
759
|
+
for (const file of ctx.vuetifyFilesToWatch) {
|
|
760
|
+
this.addWatchFile(file);
|
|
761
|
+
}
|
|
762
|
+
}
|
|
671
763
|
const {
|
|
672
764
|
enabled,
|
|
673
765
|
unocss,
|
|
@@ -837,10 +929,24 @@ function parseId2(id) {
|
|
|
837
929
|
id = id.replace(/^(virtual:nuxt:|virtual:)/, "");
|
|
838
930
|
return parseURL(decodeURIComponent(isAbsolute(id) ? pathToFileURL(id).href : id));
|
|
839
931
|
}
|
|
932
|
+
function reviver(key, value) {
|
|
933
|
+
if (key === "__proto__" || key === "constructor") {
|
|
934
|
+
return void 0;
|
|
935
|
+
}
|
|
936
|
+
return value;
|
|
937
|
+
}
|
|
938
|
+
function parseProps(value) {
|
|
939
|
+
try {
|
|
940
|
+
const parsed = JSON.parse(value, reviver);
|
|
941
|
+
return parsed && typeof parsed === "object" ? parsed : void 0;
|
|
942
|
+
} catch {
|
|
943
|
+
return void 0;
|
|
944
|
+
}
|
|
945
|
+
}
|
|
840
946
|
function parseId(id) {
|
|
841
947
|
const { search, pathname } = parseId2(id);
|
|
842
948
|
const query = parseQuery(search);
|
|
843
|
-
const urlProps = query.props ?
|
|
949
|
+
const urlProps = query.props ? parseProps(query.props) : void 0;
|
|
844
950
|
return {
|
|
845
951
|
query: urlProps,
|
|
846
952
|
path: pathname ?? id
|
|
@@ -901,122 +1007,7 @@ function vuetifySSRClientHintsPlugin(ctx) {
|
|
|
901
1007
|
};
|
|
902
1008
|
}
|
|
903
1009
|
|
|
904
|
-
function
|
|
905
|
-
let configFile;
|
|
906
|
-
const options = { styles: ctx.moduleOptions.styles };
|
|
907
|
-
const vuetifyBase = resolveVuetifyBase();
|
|
908
|
-
const noneFiles = /* @__PURE__ */ new Set();
|
|
909
|
-
let isNone = false;
|
|
910
|
-
let sassVariables = false;
|
|
911
|
-
let fileImport = false;
|
|
912
|
-
const PREFIX = "vuetify-styles/";
|
|
913
|
-
const SSR_PREFIX = `/@${PREFIX}`;
|
|
914
|
-
const resolveCss = resolveCssFactory();
|
|
915
|
-
const toPath = (file) => fileImport ? pathToFileURL(file).href : normalizePath(file);
|
|
916
|
-
return {
|
|
917
|
-
name: "vuetify:styles:nuxt",
|
|
918
|
-
enforce: "pre",
|
|
919
|
-
async configResolved(config) {
|
|
920
|
-
if (config.plugins.some((plugin) => plugin.name === "vuetify:styles")) {
|
|
921
|
-
throw new Error("Remove vite-plugin-vuetify from your Nuxt config file, this module registers a modified version.");
|
|
922
|
-
}
|
|
923
|
-
if (isObject(options.styles) && "configFile" in options.styles) {
|
|
924
|
-
sassVariables = true;
|
|
925
|
-
fileImport = semver.gt(ctx.viteVersion, "5.4.2");
|
|
926
|
-
configFile = await resolvePath(options.styles.configFile);
|
|
927
|
-
} else {
|
|
928
|
-
isNone = options.styles === "none";
|
|
929
|
-
}
|
|
930
|
-
},
|
|
931
|
-
async resolveId(source, importer, { custom, ssr }) {
|
|
932
|
-
if (!sassVariables) {
|
|
933
|
-
return;
|
|
934
|
-
}
|
|
935
|
-
if (source.startsWith(PREFIX) || source.startsWith(SSR_PREFIX)) {
|
|
936
|
-
if (/\.s[ca]ss$/.test(source)) {
|
|
937
|
-
return source;
|
|
938
|
-
}
|
|
939
|
-
const idx = source.indexOf("?");
|
|
940
|
-
return idx === -1 ? source : source.slice(0, idx);
|
|
941
|
-
}
|
|
942
|
-
if (importer && source.endsWith(".css") && isSubdir(vuetifyBase, path.isAbsolute(source) ? source : importer)) {
|
|
943
|
-
let resolutionId;
|
|
944
|
-
if (source.startsWith(".")) {
|
|
945
|
-
resolutionId = path.resolve(path.dirname(importer), source);
|
|
946
|
-
} else if (path.isAbsolute(source)) {
|
|
947
|
-
resolutionId = source;
|
|
948
|
-
} else {
|
|
949
|
-
const resolution = await this.resolve(source, importer, { skipSelf: true, custom });
|
|
950
|
-
if (resolution) {
|
|
951
|
-
resolutionId = resolution.id;
|
|
952
|
-
}
|
|
953
|
-
}
|
|
954
|
-
if (!resolutionId) {
|
|
955
|
-
return;
|
|
956
|
-
}
|
|
957
|
-
const target = await resolveCss(resolutionId);
|
|
958
|
-
if (isNone) {
|
|
959
|
-
noneFiles.add(target);
|
|
960
|
-
return target;
|
|
961
|
-
}
|
|
962
|
-
if (ctx.stylesCachePath) {
|
|
963
|
-
const relative = path.relative(vuetifyBase, target);
|
|
964
|
-
const cacheFile = path.resolve(ctx.stylesCachePath, relative.replace(/\.s[ac]ss$/, ".css"));
|
|
965
|
-
if (fs.existsSync(cacheFile)) {
|
|
966
|
-
return cacheFile;
|
|
967
|
-
}
|
|
968
|
-
}
|
|
969
|
-
return `${ssr ? SSR_PREFIX : PREFIX}${path.relative(vuetifyBase, target)}`;
|
|
970
|
-
}
|
|
971
|
-
return void 0;
|
|
972
|
-
},
|
|
973
|
-
load(id) {
|
|
974
|
-
if (sassVariables) {
|
|
975
|
-
const target = id.startsWith(PREFIX) ? path.resolve(vuetifyBase, id.slice(PREFIX.length)) : id.startsWith(SSR_PREFIX) ? path.resolve(vuetifyBase, id.slice(SSR_PREFIX.length)) : void 0;
|
|
976
|
-
if (target) {
|
|
977
|
-
const suffix = /\.scss/.test(target) ? ";\n" : "\n";
|
|
978
|
-
return {
|
|
979
|
-
code: `@use "${toPath(configFile)}"${suffix}@use "${toPath(target)}"${suffix}`,
|
|
980
|
-
map: {
|
|
981
|
-
mappings: ""
|
|
982
|
-
}
|
|
983
|
-
};
|
|
984
|
-
}
|
|
985
|
-
}
|
|
986
|
-
return isNone && noneFiles.has(id) ? "" : void 0;
|
|
987
|
-
}
|
|
988
|
-
};
|
|
989
|
-
}
|
|
990
|
-
function resolveCssFactory() {
|
|
991
|
-
const mappings = /* @__PURE__ */ new Map();
|
|
992
|
-
return async (source) => {
|
|
993
|
-
let mapping = mappings.get(source);
|
|
994
|
-
if (!mapping) {
|
|
995
|
-
try {
|
|
996
|
-
mapping = source.replace(/\.css$/, ".sass");
|
|
997
|
-
await fsp.access(mapping, fs.constants.R_OK);
|
|
998
|
-
} catch (error) {
|
|
999
|
-
if (!(error instanceof Error && "code" in error && error.code === "ENOENT")) {
|
|
1000
|
-
throw error;
|
|
1001
|
-
}
|
|
1002
|
-
try {
|
|
1003
|
-
mapping = source.replace(/\.css$/, ".scss");
|
|
1004
|
-
await fsp.access(mapping, fs.constants.R_OK);
|
|
1005
|
-
} catch {
|
|
1006
|
-
mapping = source;
|
|
1007
|
-
}
|
|
1008
|
-
}
|
|
1009
|
-
mappings.set(source, mapping);
|
|
1010
|
-
}
|
|
1011
|
-
return mapping;
|
|
1012
|
-
};
|
|
1013
|
-
}
|
|
1014
|
-
function isSubdir(root, test) {
|
|
1015
|
-
const relative$1 = relative(root, test);
|
|
1016
|
-
return relative$1 && !relative$1.startsWith("..") && !isAbsolute(relative$1);
|
|
1017
|
-
}
|
|
1018
|
-
|
|
1019
|
-
function detectDate() {
|
|
1010
|
+
function detectDate(paths) {
|
|
1020
1011
|
const result = [];
|
|
1021
1012
|
for (const adapter of [
|
|
1022
1013
|
"date-fns",
|
|
@@ -1028,12 +1019,15 @@ function detectDate() {
|
|
|
1028
1019
|
"jalaali",
|
|
1029
1020
|
"hijri"
|
|
1030
1021
|
]) {
|
|
1031
|
-
if (isPackageExists(`@date-io/${adapter}
|
|
1022
|
+
if (isPackageExists(`@date-io/${adapter}`, { paths })) {
|
|
1032
1023
|
result.push(adapter);
|
|
1033
1024
|
}
|
|
1034
1025
|
}
|
|
1035
1026
|
return result;
|
|
1036
1027
|
}
|
|
1028
|
+
function multipleDateAdaptersError(adapters) {
|
|
1029
|
+
return `Multiple date adapters found: ${adapters.map((adapter) => `@date-io/${adapter}`).join(", ")}, please specify the adapter to use in the "vuetifyOptions.date.adapter" option.`;
|
|
1030
|
+
}
|
|
1037
1031
|
function cleanupBlueprint(vuetifyOptions) {
|
|
1038
1032
|
const blueprint = vuetifyOptions.blueprint;
|
|
1039
1033
|
if (blueprint) {
|
|
@@ -1056,12 +1050,10 @@ function checkVuetifyPlugins(config) {
|
|
|
1056
1050
|
throw new Error("Remove vite-plugin-vuetify plugin from Vite Plugins entry in Nuxt config file!");
|
|
1057
1051
|
}
|
|
1058
1052
|
}
|
|
1059
|
-
function resolveVuetifyComponents(resolver) {
|
|
1060
|
-
const vuetifyBase = resolveVuetifyBase();
|
|
1053
|
+
function resolveVuetifyComponents(resolver, vuetifyBase) {
|
|
1061
1054
|
const componentsPromise = importMapResolver();
|
|
1062
1055
|
const labComponentsPromise = importMapLabResolver();
|
|
1063
1056
|
return {
|
|
1064
|
-
vuetifyBase,
|
|
1065
1057
|
componentsPromise,
|
|
1066
1058
|
labComponentsPromise
|
|
1067
1059
|
};
|
|
@@ -1073,6 +1065,9 @@ function resolveVuetifyComponents(resolver) {
|
|
|
1073
1065
|
}
|
|
1074
1066
|
}
|
|
1075
1067
|
|
|
1068
|
+
function resolveStylesCache(stylesOption) {
|
|
1069
|
+
return stylesOption.cache ?? stylesOption.experimental?.cache;
|
|
1070
|
+
}
|
|
1076
1071
|
function configureVite(configKey, nuxt, ctx) {
|
|
1077
1072
|
nuxt.hook("vite:extend", ({ config }) => checkVuetifyPlugins(config));
|
|
1078
1073
|
nuxt.hook("vite:extendConfig", (viteInlineConfig) => {
|
|
@@ -1081,7 +1076,7 @@ function configureVite(configKey, nuxt, ctx) {
|
|
|
1081
1076
|
if (!ctx.moduleOptions.disableModernSassCompiler) {
|
|
1082
1077
|
const enableModernSassCompiler = semver.gte(ctx.viteVersion, "5.4.0") && semver.lt(ctx.viteVersion, "7.0.0-0");
|
|
1083
1078
|
if (enableModernSassCompiler) {
|
|
1084
|
-
const sassEmbedded = isPackageExists("sass-embedded");
|
|
1079
|
+
const sassEmbedded = isPackageExists("sass-embedded", { paths: ctx.resolvePaths });
|
|
1085
1080
|
if (sassEmbedded) {
|
|
1086
1081
|
viteInlineConfig.css ??= {};
|
|
1087
1082
|
viteInlineConfig.css.preprocessorOptions ??= {};
|
|
@@ -1125,8 +1120,18 @@ function configureVite(configKey, nuxt, ctx) {
|
|
|
1125
1120
|
autoImport.ignore = Array.isArray(ignoreDirectives) ? ignoreDirectives : [ignoreDirectives];
|
|
1126
1121
|
}
|
|
1127
1122
|
viteInlineConfig.plugins.push(vuetifyImportPlugin({ autoImport }));
|
|
1128
|
-
|
|
1129
|
-
|
|
1123
|
+
const stylesOption = ctx.moduleOptions.styles;
|
|
1124
|
+
if (stylesOption === "none") {
|
|
1125
|
+
viteInlineConfig.plugins.push(Styles({ styles: "none" }));
|
|
1126
|
+
} else if (typeof stylesOption === "object" && stylesOption !== null && "configFile" in stylesOption) {
|
|
1127
|
+
if (!ctx.stylesConfigFile) {
|
|
1128
|
+
throw new Error("vuetify-nuxt-module: styles.configFile could not be resolved");
|
|
1129
|
+
}
|
|
1130
|
+
const cache = resolveStylesCache(stylesOption);
|
|
1131
|
+
viteInlineConfig.plugins.push(Styles({
|
|
1132
|
+
settings: ctx.stylesConfigFile,
|
|
1133
|
+
...cache === void 0 ? {} : { cache }
|
|
1134
|
+
}));
|
|
1130
1135
|
}
|
|
1131
1136
|
viteInlineConfig.plugins.push(vuetifyConfigurationPlugin(ctx), vuetifyIconsPlugin(ctx), vuetifyDateConfigurationPlugin(ctx));
|
|
1132
1137
|
if (ctx.ssrClientHints.enabled) {
|
|
@@ -1165,7 +1170,8 @@ const disabledResolvedIcons = Object.freeze({
|
|
|
1165
1170
|
local: [],
|
|
1166
1171
|
svg: {}
|
|
1167
1172
|
});
|
|
1168
|
-
function prepareIcons(unocssPresent, logger, vuetifyOptions) {
|
|
1173
|
+
function prepareIcons(unocssPresent, logger, vuetifyOptions, paths) {
|
|
1174
|
+
const iconPackageExists = (name) => isPackageExists(name, { paths });
|
|
1169
1175
|
if (vuetifyOptions.icons === false) {
|
|
1170
1176
|
return disabledResolvedIcons;
|
|
1171
1177
|
}
|
|
@@ -1209,7 +1215,7 @@ function prepareIcons(unocssPresent, logger, vuetifyOptions) {
|
|
|
1209
1215
|
}
|
|
1210
1216
|
resolvedIcons.imports.push(`import {${name === defaultSet ? "aliases," : ""}${name}} from 'vuetify/iconsets/${name}'`);
|
|
1211
1217
|
resolvedIcons.sets.push(name);
|
|
1212
|
-
if (
|
|
1218
|
+
if (iconPackageExists(iconsPackageNames[name].name)) {
|
|
1213
1219
|
resolvedIcons.local.push(iconsPackageNames[name].css);
|
|
1214
1220
|
} else {
|
|
1215
1221
|
resolvedIcons.cdn.push([name, cdn ?? iconsCDN[name]]);
|
|
@@ -1228,18 +1234,18 @@ function prepareIcons(unocssPresent, logger, vuetifyOptions) {
|
|
|
1228
1234
|
if (!faSvg) {
|
|
1229
1235
|
faSvg = {};
|
|
1230
1236
|
}
|
|
1231
|
-
let faSvgExists =
|
|
1237
|
+
let faSvgExists = iconPackageExists("@fortawesome/fontawesome-svg-core");
|
|
1232
1238
|
if (!faSvgExists) {
|
|
1233
1239
|
logger.warn("Missing @fortawesome/fontawesome-svg-core dependency, install it!");
|
|
1234
1240
|
}
|
|
1235
|
-
faSvgExists =
|
|
1241
|
+
faSvgExists = iconPackageExists("@fortawesome/vue-fontawesome");
|
|
1236
1242
|
if (faSvgExists) {
|
|
1237
1243
|
if (!faSvg.libraries?.length) {
|
|
1238
1244
|
faSvg.libraries = [[false, "fas", "@fortawesome/free-solid-svg-icons"]];
|
|
1239
1245
|
}
|
|
1240
1246
|
for (const p in faSvg.libraries) {
|
|
1241
1247
|
const [_defaultExport, _name, library] = faSvg.libraries[p];
|
|
1242
|
-
if (!
|
|
1248
|
+
if (!iconPackageExists(library)) {
|
|
1243
1249
|
faSvgExists = false;
|
|
1244
1250
|
logger.warn(`Missing library ${library} dependency, install it!`);
|
|
1245
1251
|
}
|
|
@@ -1266,7 +1272,7 @@ function prepareIcons(unocssPresent, logger, vuetifyOptions) {
|
|
|
1266
1272
|
if (!mdiSvg) {
|
|
1267
1273
|
mdiSvg = {};
|
|
1268
1274
|
}
|
|
1269
|
-
const mdiSvgExists =
|
|
1275
|
+
const mdiSvgExists = iconPackageExists("@mdi/js");
|
|
1270
1276
|
if (mdiSvgExists) {
|
|
1271
1277
|
resolvedIcons.svg.mdi = true;
|
|
1272
1278
|
resolvedIcons.aliasesImportPresent ||= defaultSet === "mdi-svg";
|
|
@@ -1314,7 +1320,7 @@ async function loadVuetifyConfiguration(cwd = process.cwd(), configOrPath = cwd,
|
|
|
1314
1320
|
inlineConfig = configOrPath;
|
|
1315
1321
|
configOrPath = process.cwd();
|
|
1316
1322
|
}
|
|
1317
|
-
const resolved = resolve
|
|
1323
|
+
const resolved = resolve(cwd, configOrPath);
|
|
1318
1324
|
let isFile = false;
|
|
1319
1325
|
if (existsSync(resolved) && statSync(resolved).isFile()) {
|
|
1320
1326
|
isFile = true;
|
|
@@ -1362,6 +1368,29 @@ async function loadVuetifyConfiguration(cwd = process.cwd(), configOrPath = cwd,
|
|
|
1362
1368
|
return result;
|
|
1363
1369
|
}
|
|
1364
1370
|
|
|
1371
|
+
const MODULE_DEFAULTS = {
|
|
1372
|
+
moduleOptions: {
|
|
1373
|
+
importComposables: true,
|
|
1374
|
+
includeTransformAssetsUrls: true,
|
|
1375
|
+
styles: true,
|
|
1376
|
+
rulesConfiguration: {
|
|
1377
|
+
fromLabs: true
|
|
1378
|
+
}
|
|
1379
|
+
},
|
|
1380
|
+
vuetifyOptions: {
|
|
1381
|
+
labComponents: false,
|
|
1382
|
+
directives: false
|
|
1383
|
+
}
|
|
1384
|
+
};
|
|
1385
|
+
function finalizeConfiguration(moduleOptions) {
|
|
1386
|
+
if (moduleOptions.length > 1) {
|
|
1387
|
+
const [app, ...rest] = moduleOptions;
|
|
1388
|
+
const configuration = defu(app, ...rest, MODULE_DEFAULTS);
|
|
1389
|
+
dedupeIcons(configuration, moduleOptions.toReversed());
|
|
1390
|
+
return configuration;
|
|
1391
|
+
}
|
|
1392
|
+
return defu(moduleOptions[0] ?? {}, MODULE_DEFAULTS);
|
|
1393
|
+
}
|
|
1365
1394
|
async function mergeVuetifyModules(options, nuxt) {
|
|
1366
1395
|
const moduleOptions = [];
|
|
1367
1396
|
const vuetifyConfigurationFilesToWatch = /* @__PURE__ */ new Set();
|
|
@@ -1389,37 +1418,18 @@ async function mergeVuetifyModules(options, nuxt) {
|
|
|
1389
1418
|
options.vuetifyOptions
|
|
1390
1419
|
);
|
|
1391
1420
|
if (nuxt.options.dev && resolvedOptions.sources.length > 0) {
|
|
1392
|
-
|
|
1393
|
-
|
|
1394
|
-
nuxt.options.watch.push(s.replace(/\\/g, "/"));
|
|
1395
|
-
}
|
|
1396
|
-
} else {
|
|
1397
|
-
for (const s of resolvedOptions.sources) {
|
|
1398
|
-
vuetifyConfigurationFilesToWatch.add(s.replace(/\\/g, "/"));
|
|
1399
|
-
}
|
|
1421
|
+
for (const s of resolvedOptions.sources) {
|
|
1422
|
+
vuetifyConfigurationFilesToWatch.add(s.replace(/\\/g, "/"));
|
|
1400
1423
|
}
|
|
1401
1424
|
}
|
|
1402
1425
|
moduleOptions.unshift({
|
|
1403
1426
|
moduleOptions: options.moduleOptions,
|
|
1404
1427
|
vuetifyOptions: resolvedOptions.config
|
|
1405
1428
|
});
|
|
1406
|
-
|
|
1407
|
-
|
|
1408
|
-
|
|
1409
|
-
|
|
1410
|
-
return {
|
|
1411
|
-
configuration,
|
|
1412
|
-
vuetifyConfigurationFilesToWatch
|
|
1413
|
-
};
|
|
1414
|
-
} else {
|
|
1415
|
-
return {
|
|
1416
|
-
configuration: {
|
|
1417
|
-
moduleOptions: options.moduleOptions,
|
|
1418
|
-
vuetifyOptions: resolvedOptions.config
|
|
1419
|
-
},
|
|
1420
|
-
vuetifyConfigurationFilesToWatch
|
|
1421
|
-
};
|
|
1422
|
-
}
|
|
1429
|
+
return {
|
|
1430
|
+
configuration: finalizeConfiguration(moduleOptions),
|
|
1431
|
+
vuetifyConfigurationFilesToWatch
|
|
1432
|
+
};
|
|
1423
1433
|
}
|
|
1424
1434
|
function dedupeIcons(configuration, moduleOptions) {
|
|
1425
1435
|
const vuetifyOptions = configuration.vuetifyOptions;
|
|
@@ -1452,6 +1462,28 @@ const disabledClientHints = Object.freeze({
|
|
|
1452
1462
|
prefersColorScheme: false,
|
|
1453
1463
|
prefersReducedMotion: false
|
|
1454
1464
|
});
|
|
1465
|
+
function resolveColorSchemeCookie(options, logger) {
|
|
1466
|
+
if (options.cookieName !== void 0) {
|
|
1467
|
+
logger.warn("[vuetify-nuxt-module] `prefersColorSchemeOptions.cookieName` is deprecated, use `prefersColorSchemeOptions.cookie.name` instead.");
|
|
1468
|
+
}
|
|
1469
|
+
const cookieSameSite = options.cookie?.sameSite ?? "lax";
|
|
1470
|
+
return {
|
|
1471
|
+
cookieName: options.cookie?.name ?? options.cookieName ?? "color-scheme",
|
|
1472
|
+
cookieDomain: options.cookie?.domain,
|
|
1473
|
+
cookieSecure: cookieSameSite === "none" ? true : options.cookie?.secure,
|
|
1474
|
+
cookieSameSite
|
|
1475
|
+
};
|
|
1476
|
+
}
|
|
1477
|
+
function resolveDefaultTheme(defaultTheme, themes, lightThemeName, logger) {
|
|
1478
|
+
if (defaultTheme === "system") {
|
|
1479
|
+
logger.warn(`Vuetify "system" theme cannot be resolved during SSR; using "${lightThemeName}" as the server-side fallback. The browser preference is applied on the client via prefersColorScheme client hints. To avoid a flash of the wrong theme, set explicit dark/light themes and enable moduleOptions.ssrClientHints.prefersColorSchemeOptions.useBrowserThemeOnly.`);
|
|
1480
|
+
return lightThemeName;
|
|
1481
|
+
}
|
|
1482
|
+
if (!themes[defaultTheme]) {
|
|
1483
|
+
throw new Error(`Missing default theme ${defaultTheme} in the Vuetify themes!`);
|
|
1484
|
+
}
|
|
1485
|
+
return defaultTheme;
|
|
1486
|
+
}
|
|
1455
1487
|
function prepareSSRClientHints(baseUrl, ctx) {
|
|
1456
1488
|
if (!ctx.isSSR || ctx.isNuxtGenerate) {
|
|
1457
1489
|
return disabledClientHints;
|
|
@@ -1478,9 +1510,6 @@ function prepareSSRClientHints(baseUrl, ctx) {
|
|
|
1478
1510
|
if (!defaultTheme) {
|
|
1479
1511
|
throw new Error("Vuetify default theme is missing in theme!");
|
|
1480
1512
|
}
|
|
1481
|
-
if (!themes[defaultTheme]) {
|
|
1482
|
-
throw new Error(`Missing default theme ${defaultTheme} in the Vuetify themes!`);
|
|
1483
|
-
}
|
|
1484
1513
|
const darkThemeName = ssrClientHintsConfiguration.prefersColorSchemeOptions?.darkThemeName ?? "dark";
|
|
1485
1514
|
if (!themes[darkThemeName]) {
|
|
1486
1515
|
throw new Error(`Missing theme ${darkThemeName} in the Vuetify themes!`);
|
|
@@ -1492,138 +1521,22 @@ function prepareSSRClientHints(baseUrl, ctx) {
|
|
|
1492
1521
|
if (darkThemeName === lightThemeName) {
|
|
1493
1522
|
throw new Error("Vuetify dark theme and light theme are the same, change darkThemeName or lightThemeName!");
|
|
1494
1523
|
}
|
|
1524
|
+
const pcsOptions = ssrClientHintsConfiguration.prefersColorSchemeOptions;
|
|
1525
|
+
const effectiveDefaultTheme = resolveDefaultTheme(defaultTheme, themes, lightThemeName, ctx.logger);
|
|
1495
1526
|
clientHints.prefersColorSchemeOptions = {
|
|
1496
1527
|
baseUrl,
|
|
1497
|
-
defaultTheme,
|
|
1528
|
+
defaultTheme: effectiveDefaultTheme,
|
|
1498
1529
|
themeNames: Array.from(Object.keys(themes)),
|
|
1499
|
-
|
|
1530
|
+
...resolveColorSchemeCookie(pcsOptions, ctx.logger),
|
|
1500
1531
|
darkThemeName,
|
|
1501
1532
|
lightThemeName,
|
|
1502
|
-
useBrowserThemeOnly:
|
|
1533
|
+
useBrowserThemeOnly: pcsOptions?.useBrowserThemeOnly ?? false
|
|
1503
1534
|
};
|
|
1504
1535
|
}
|
|
1505
1536
|
return clientHints;
|
|
1506
1537
|
}
|
|
1507
1538
|
|
|
1508
|
-
async function
|
|
1509
|
-
const stylesConfig = ctx.moduleOptions.styles;
|
|
1510
|
-
if (!isObject(stylesConfig) || !("configFile" in stylesConfig)) {
|
|
1511
|
-
return;
|
|
1512
|
-
}
|
|
1513
|
-
if (stylesConfig.experimental?.cache === false) {
|
|
1514
|
-
return;
|
|
1515
|
-
}
|
|
1516
|
-
const vuetifyBase = resolveVuetifyBase();
|
|
1517
|
-
let configFile;
|
|
1518
|
-
let configContent = "";
|
|
1519
|
-
if (stylesConfig.configFile) {
|
|
1520
|
-
configFile = await resolvePath(stylesConfig.configFile);
|
|
1521
|
-
if (existsSync(configFile)) {
|
|
1522
|
-
configContent = readFileSync(configFile, "utf8");
|
|
1523
|
-
if (!ctx.vuetifyFilesToWatch.includes(configFile)) {
|
|
1524
|
-
ctx.vuetifyFilesToWatch.push(configFile);
|
|
1525
|
-
}
|
|
1526
|
-
}
|
|
1527
|
-
}
|
|
1528
|
-
if (!configFile) {
|
|
1529
|
-
return;
|
|
1530
|
-
}
|
|
1531
|
-
const hash = createHash("sha256").update(ctx.vuetifyVersion).update(ctx.viteVersion).update(configContent).update(configFile).digest("hex").slice(0, 8);
|
|
1532
|
-
const stylesDir = resolve$1(nuxt.options.rootDir, "node_modules/.cache/vuetify-nuxt-module/styles");
|
|
1533
|
-
const cacheDir = join(stylesDir, hash);
|
|
1534
|
-
ctx.stylesCachePath = cacheDir;
|
|
1535
|
-
if (existsSync(stylesDir)) {
|
|
1536
|
-
const dirents = readdirSync(stylesDir, { withFileTypes: true });
|
|
1537
|
-
for (const dirent of dirents) {
|
|
1538
|
-
if (dirent.isDirectory() && dirent.name !== hash) {
|
|
1539
|
-
rmSync(join(stylesDir, dirent.name), { recursive: true, force: true });
|
|
1540
|
-
}
|
|
1541
|
-
}
|
|
1542
|
-
}
|
|
1543
|
-
if (existsSync(cacheDir)) {
|
|
1544
|
-
return;
|
|
1545
|
-
}
|
|
1546
|
-
ctx.logger.info("Compiling Vuetify styles...");
|
|
1547
|
-
let sass;
|
|
1548
|
-
try {
|
|
1549
|
-
sass = await import('sass');
|
|
1550
|
-
} catch {
|
|
1551
|
-
try {
|
|
1552
|
-
sass = await import('sass-embedded');
|
|
1553
|
-
} catch {
|
|
1554
|
-
ctx.logger.warn('Could not load "sass" or "sass-embedded". Skipping styles pre-compilation.');
|
|
1555
|
-
return;
|
|
1556
|
-
}
|
|
1557
|
-
}
|
|
1558
|
-
const files = [];
|
|
1559
|
-
findCssFiles(join(vuetifyBase, "lib/components"), files);
|
|
1560
|
-
findCssFiles(join(vuetifyBase, "lib/styles"), files);
|
|
1561
|
-
for (const file of files) {
|
|
1562
|
-
const relativePath = relative$1(vuetifyBase, file);
|
|
1563
|
-
const cacheFile = join(cacheDir, relativePath);
|
|
1564
|
-
const sassFile = file.replace(/\.css$/, ".sass");
|
|
1565
|
-
const scssFile = file.replace(/\.css$/, ".scss");
|
|
1566
|
-
let targetFile;
|
|
1567
|
-
if (existsSync(sassFile)) {
|
|
1568
|
-
targetFile = sassFile;
|
|
1569
|
-
} else if (existsSync(scssFile)) {
|
|
1570
|
-
targetFile = scssFile;
|
|
1571
|
-
}
|
|
1572
|
-
if (targetFile) {
|
|
1573
|
-
const dir = dirname(cacheFile);
|
|
1574
|
-
if (!existsSync(dir)) {
|
|
1575
|
-
mkdirSync(dir, { recursive: true });
|
|
1576
|
-
}
|
|
1577
|
-
const content = `@use "${normalizePath(configFile)}";
|
|
1578
|
-
@use "${normalizePath(targetFile)}";
|
|
1579
|
-
`;
|
|
1580
|
-
try {
|
|
1581
|
-
const result = sass.compileString(content, {
|
|
1582
|
-
loadPaths: [
|
|
1583
|
-
dirname(configFile),
|
|
1584
|
-
dirname(targetFile),
|
|
1585
|
-
resolve$1(vuetifyBase, ".."),
|
|
1586
|
-
resolve$1(vuetifyBase, "../.."),
|
|
1587
|
-
// In case of monorepo/hoisting issues, but standard is enough
|
|
1588
|
-
vuetifyBase
|
|
1589
|
-
],
|
|
1590
|
-
url: new URL(pathToFileURL(cacheFile).href)
|
|
1591
|
-
});
|
|
1592
|
-
writeFileSync(cacheFile, result.css, "utf8");
|
|
1593
|
-
} catch (error) {
|
|
1594
|
-
ctx.logger.error(`Failed to compile ${targetFile}:`, error);
|
|
1595
|
-
}
|
|
1596
|
-
}
|
|
1597
|
-
}
|
|
1598
|
-
const metadata = {
|
|
1599
|
-
hash,
|
|
1600
|
-
vuetifyVersion: ctx.vuetifyVersion,
|
|
1601
|
-
viteVersion: ctx.viteVersion,
|
|
1602
|
-
configFile,
|
|
1603
|
-
createdAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
1604
|
-
};
|
|
1605
|
-
writeFileSync(join(cacheDir, "metadata.json"), JSON.stringify(metadata, null, 2), "utf8");
|
|
1606
|
-
}
|
|
1607
|
-
function findCssFiles(dir, fileList = []) {
|
|
1608
|
-
if (!existsSync(dir)) {
|
|
1609
|
-
return fileList;
|
|
1610
|
-
}
|
|
1611
|
-
const files = readdirSync(dir);
|
|
1612
|
-
for (const file of files) {
|
|
1613
|
-
const filePath = join(dir, file);
|
|
1614
|
-
const stat = statSync(filePath);
|
|
1615
|
-
if (stat.isDirectory()) {
|
|
1616
|
-
findCssFiles(filePath, fileList);
|
|
1617
|
-
} else {
|
|
1618
|
-
if (file.endsWith(".css")) {
|
|
1619
|
-
fileList.push(filePath);
|
|
1620
|
-
}
|
|
1621
|
-
}
|
|
1622
|
-
}
|
|
1623
|
-
return fileList;
|
|
1624
|
-
}
|
|
1625
|
-
|
|
1626
|
-
async function load(options, nuxt, ctx) {
|
|
1539
|
+
async function load(options, nuxt, ctx, reload = false) {
|
|
1627
1540
|
const {
|
|
1628
1541
|
configuration,
|
|
1629
1542
|
vuetifyConfigurationFilesToWatch
|
|
@@ -1632,7 +1545,7 @@ async function load(options, nuxt, ctx) {
|
|
|
1632
1545
|
const {
|
|
1633
1546
|
componentsPromise,
|
|
1634
1547
|
labComponentsPromise
|
|
1635
|
-
} = resolveVuetifyComponents(ctx.resolver);
|
|
1548
|
+
} = resolveVuetifyComponents(ctx.resolver, ctx.vuetifyBase);
|
|
1636
1549
|
ctx.componentsPromise = componentsPromise;
|
|
1637
1550
|
ctx.labComponentsPromise = labComponentsPromise;
|
|
1638
1551
|
}
|
|
@@ -1648,9 +1561,9 @@ async function load(options, nuxt, ctx) {
|
|
|
1648
1561
|
const dateOptions = vuetifyOptions.date;
|
|
1649
1562
|
if (dateOptions) {
|
|
1650
1563
|
const adapter = dateOptions.adapter;
|
|
1651
|
-
const date = detectDate();
|
|
1564
|
+
const date = detectDate(ctx.resolvePaths);
|
|
1652
1565
|
if (!adapter && date.length > 1) {
|
|
1653
|
-
throw new Error(
|
|
1566
|
+
throw new Error(multipleDateAdaptersError(date));
|
|
1654
1567
|
}
|
|
1655
1568
|
if (adapter) {
|
|
1656
1569
|
if (adapter === "vuetify" || adapter === "custom") {
|
|
@@ -1668,18 +1581,23 @@ async function load(options, nuxt, ctx) {
|
|
|
1668
1581
|
ctx.dateAdapter = date[0];
|
|
1669
1582
|
}
|
|
1670
1583
|
}
|
|
1671
|
-
|
|
1672
|
-
|
|
1673
|
-
|
|
1584
|
+
if (!reload) {
|
|
1585
|
+
const oldIcons = ctx.icons;
|
|
1586
|
+
if (oldIcons && oldIcons.cdn?.length && nuxt.options.app.head.link) {
|
|
1587
|
+
nuxt.options.app.head.link = nuxt.options.app.head.link.filter((link) => !link.key || !oldIcons.cdn.some(([key]) => link.key === key));
|
|
1588
|
+
}
|
|
1674
1589
|
}
|
|
1675
1590
|
ctx.moduleOptions = configuration.moduleOptions;
|
|
1676
1591
|
ctx.vuetifyOptions = configuration.vuetifyOptions;
|
|
1677
1592
|
ctx.enableRules = ctx.moduleOptions.enableRules;
|
|
1678
1593
|
ctx.rulesConfiguration = ctx.moduleOptions.rulesConfiguration;
|
|
1679
1594
|
ctx.vuetifyFilesToWatch = Array.from(vuetifyConfigurationFilesToWatch);
|
|
1680
|
-
ctx.icons = prepareIcons(ctx.unocss, ctx.logger, vuetifyAppOptions);
|
|
1595
|
+
ctx.icons = prepareIcons(ctx.unocss, ctx.logger, vuetifyAppOptions, ctx.resolvePaths);
|
|
1681
1596
|
ctx.ssrClientHints = prepareSSRClientHints(nuxt.options.app.baseURL ?? "/", ctx);
|
|
1682
|
-
if (ctx.
|
|
1597
|
+
if (ctx.isSSR && !ctx.ssrClientHints.prefersColorScheme && ctx.vuetifyOptions.theme && typeof ctx.vuetifyOptions.theme === "object" && ctx.vuetifyOptions.theme.defaultTheme === "system") {
|
|
1598
|
+
ctx.logger.warn('`theme.defaultTheme: "system"` cannot be resolved during SSR/SSG: the server has no access to the OS color-scheme preference, so the first paint defaults to light and may flash on dark systems. Set explicit dark/light themes and enable `moduleOptions.ssrClientHints.prefersColorScheme` (optionally `prefersColorSchemeOptions.useBrowserThemeOnly`). See the SSR guide.');
|
|
1599
|
+
}
|
|
1600
|
+
if (!reload && ctx.icons.enabled) {
|
|
1683
1601
|
if (ctx.icons.local) {
|
|
1684
1602
|
for (const css of ctx.icons.local) {
|
|
1685
1603
|
nuxt.options.css.push(css);
|
|
@@ -1698,45 +1616,68 @@ async function load(options, nuxt, ctx) {
|
|
|
1698
1616
|
}
|
|
1699
1617
|
}
|
|
1700
1618
|
}
|
|
1701
|
-
await prepareVuetifyStyles(nuxt, ctx);
|
|
1702
1619
|
}
|
|
1703
|
-
function
|
|
1704
|
-
|
|
1705
|
-
|
|
1706
|
-
|
|
1707
|
-
|
|
1708
|
-
|
|
1709
|
-
return nuxt.callHook("restart");
|
|
1620
|
+
function bindInvalidator(graph) {
|
|
1621
|
+
return () => {
|
|
1622
|
+
for (const id of RESOLVED_VIRTUAL_MODULES) {
|
|
1623
|
+
const mod = graph.getModuleById(id);
|
|
1624
|
+
if (mod) {
|
|
1625
|
+
graph.invalidateModule(mod);
|
|
1710
1626
|
}
|
|
1711
|
-
}
|
|
1712
|
-
|
|
1713
|
-
|
|
1714
|
-
|
|
1715
|
-
|
|
1716
|
-
|
|
1717
|
-
|
|
1718
|
-
|
|
1719
|
-
|
|
1720
|
-
|
|
1721
|
-
|
|
1722
|
-
|
|
1723
|
-
|
|
1724
|
-
|
|
1725
|
-
|
|
1726
|
-
|
|
1727
|
-
|
|
1728
|
-
|
|
1729
|
-
|
|
1730
|
-
|
|
1731
|
-
|
|
1732
|
-
|
|
1733
|
-
|
|
1734
|
-
|
|
1735
|
-
|
|
1736
|
-
|
|
1627
|
+
}
|
|
1628
|
+
};
|
|
1629
|
+
}
|
|
1630
|
+
function registerWatcher(options, nuxt, ctx) {
|
|
1631
|
+
if (!nuxt.options.dev) {
|
|
1632
|
+
return;
|
|
1633
|
+
}
|
|
1634
|
+
if (!ctx.canHmrConfig) {
|
|
1635
|
+
for (const file of ctx.vuetifyFilesToWatch) {
|
|
1636
|
+
nuxt.options.watch.push(file);
|
|
1637
|
+
}
|
|
1638
|
+
return;
|
|
1639
|
+
}
|
|
1640
|
+
let clientServer;
|
|
1641
|
+
let invalidateSsrModules;
|
|
1642
|
+
nuxt.hook("vite:serverCreated", (server, { isClient }) => {
|
|
1643
|
+
if (!isClient) {
|
|
1644
|
+
invalidateSsrModules = bindInvalidator(server.moduleGraph);
|
|
1645
|
+
return;
|
|
1646
|
+
}
|
|
1647
|
+
if (!server.ws) {
|
|
1648
|
+
return;
|
|
1649
|
+
}
|
|
1650
|
+
clientServer = server;
|
|
1651
|
+
const ssrEnv = server.environments?.ssr;
|
|
1652
|
+
if (ssrEnv) {
|
|
1653
|
+
invalidateSsrModules ??= bindInvalidator(ssrEnv.moduleGraph);
|
|
1654
|
+
}
|
|
1655
|
+
server.watcher.add(ctx.vuetifyFilesToWatch);
|
|
1656
|
+
});
|
|
1657
|
+
async function reloadConfig() {
|
|
1658
|
+
await load(options, nuxt, ctx, true);
|
|
1659
|
+
invalidateSsrModules?.();
|
|
1660
|
+
clientServer?.ws.send({ type: "full-reload" });
|
|
1661
|
+
}
|
|
1662
|
+
addVitePlugin({
|
|
1663
|
+
name: "vuetify:configuration:watch",
|
|
1664
|
+
enforce: "pre",
|
|
1665
|
+
async handleHotUpdate({ file }) {
|
|
1666
|
+
if (clientServer && ctx.vuetifyFilesToWatch.includes(file)) {
|
|
1667
|
+
await reloadConfig();
|
|
1668
|
+
return [];
|
|
1737
1669
|
}
|
|
1738
|
-
}
|
|
1670
|
+
}
|
|
1671
|
+
});
|
|
1672
|
+
}
|
|
1673
|
+
|
|
1674
|
+
const MIN_NUXT_VERSION_FOR_SSR_CONFIG_HMR = "3.18.0";
|
|
1675
|
+
function supportsSsrConfigHmr(nuxtVersion) {
|
|
1676
|
+
const parsed = semver.parse(nuxtVersion) ?? semver.coerce(nuxtVersion);
|
|
1677
|
+
if (!parsed) {
|
|
1678
|
+
return false;
|
|
1739
1679
|
}
|
|
1680
|
+
return semver.gte(parsed.version, MIN_NUXT_VERSION_FOR_SSR_CONFIG_HMR);
|
|
1740
1681
|
}
|
|
1741
1682
|
|
|
1742
1683
|
const CONFIG_KEY = "vuetify";
|
|
@@ -1750,24 +1691,6 @@ const module$1 = defineNuxtModule({
|
|
|
1750
1691
|
},
|
|
1751
1692
|
version
|
|
1752
1693
|
},
|
|
1753
|
-
/**
|
|
1754
|
-
* Default configuration options of the Nuxt module
|
|
1755
|
-
*/
|
|
1756
|
-
defaults: () => ({
|
|
1757
|
-
vuetifyOptions: {
|
|
1758
|
-
labComponents: false,
|
|
1759
|
-
directives: false
|
|
1760
|
-
},
|
|
1761
|
-
moduleOptions: {
|
|
1762
|
-
importComposables: true,
|
|
1763
|
-
includeTransformAssetsUrls: true,
|
|
1764
|
-
styles: true,
|
|
1765
|
-
disableVuetifyStyles: false,
|
|
1766
|
-
rulesConfiguration: {
|
|
1767
|
-
fromLabs: true
|
|
1768
|
-
}
|
|
1769
|
-
}
|
|
1770
|
-
}),
|
|
1771
1694
|
/**
|
|
1772
1695
|
* Sets up the Vuetify Nuxt module.
|
|
1773
1696
|
*
|
|
@@ -1778,8 +1701,23 @@ const module$1 = defineNuxtModule({
|
|
|
1778
1701
|
if (isNuxtMajorVersion(2, nuxt)) {
|
|
1779
1702
|
logger.error(`Cannot support nuxt version: ${getNuxtVersion(nuxt)}`);
|
|
1780
1703
|
}
|
|
1781
|
-
|
|
1782
|
-
|
|
1704
|
+
let vuetifyPkgPath = await findPath("vuetify/package.json");
|
|
1705
|
+
if (!vuetifyPkgPath) {
|
|
1706
|
+
const metaResolve = import.meta.resolve;
|
|
1707
|
+
if (metaResolve) {
|
|
1708
|
+
try {
|
|
1709
|
+
vuetifyPkgPath = fileURLToPath(metaResolve("vuetify/package.json"));
|
|
1710
|
+
} catch {
|
|
1711
|
+
}
|
|
1712
|
+
}
|
|
1713
|
+
}
|
|
1714
|
+
if (!vuetifyPkgPath) {
|
|
1715
|
+
throw new Error(
|
|
1716
|
+
'[vuetify-nuxt-module] Could not resolve "vuetify". Please add it as a dependency of your project (e.g. `npm add vuetify`).'
|
|
1717
|
+
);
|
|
1718
|
+
}
|
|
1719
|
+
const vuetifyBase = dirname(vuetifyPkgPath);
|
|
1720
|
+
const currentVersion = JSON.parse(readFileSync(vuetifyPkgPath, "utf8")).version;
|
|
1783
1721
|
const vuetifyGte = (version2) => !!currentVersion && semver.gte(currentVersion, version2);
|
|
1784
1722
|
const viteVersion = version$1;
|
|
1785
1723
|
const ctx = {
|
|
@@ -1788,6 +1726,7 @@ const module$1 = defineNuxtModule({
|
|
|
1788
1726
|
moduleOptions: void 0,
|
|
1789
1727
|
vuetifyOptions: void 0,
|
|
1790
1728
|
vuetifyFilesToWatch: [],
|
|
1729
|
+
canHmrConfig: !nuxt.options.ssr || supportsSsrConfigHmr(getNuxtVersion(nuxt)),
|
|
1791
1730
|
isSSR: nuxt.options.ssr,
|
|
1792
1731
|
isDev: nuxt.options.dev,
|
|
1793
1732
|
isNuxtGenerate: !!nuxt.options.nitro.static,
|
|
@@ -1799,6 +1738,8 @@ const module$1 = defineNuxtModule({
|
|
|
1799
1738
|
labComponentsPromise: void 0,
|
|
1800
1739
|
vuetifyGte,
|
|
1801
1740
|
vuetifyVersion: currentVersion || "0.0.0",
|
|
1741
|
+
vuetifyBase,
|
|
1742
|
+
resolvePaths: [nuxt.options.rootDir, ...nuxt.options.modulesDir],
|
|
1802
1743
|
viteVersion
|
|
1803
1744
|
};
|
|
1804
1745
|
await load(options, nuxt, ctx);
|