vuetify-nuxt-module 0.4.12 → 0.5.1

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/module.mjs CHANGED
@@ -1,12 +1,429 @@
1
- import { useLogger, defineNuxtModule, isNuxt3, getNuxtVersion, createResolver, hasNuxtModule, extendWebpackConfig, addImports, addPlugin } from '@nuxt/kit';
1
+ import { addVitePlugin, extendWebpackConfig, addImports, addPlugin, useLogger, defineNuxtModule, isNuxt3, getNuxtVersion, createResolver, hasNuxtModule } from '@nuxt/kit';
2
2
  import defu from 'defu';
3
- import { utimes, readFile } from 'node:fs/promises';
3
+ import { debounce } from 'perfect-debounce';
4
+ import { existsSync, statSync } from 'node:fs';
5
+ import { resolve, dirname } from 'node:path';
6
+ import { createConfigLoader } from 'unconfig';
7
+ import { readFile, utimes } from 'node:fs/promises';
8
+ import { isPackageExists } from 'local-pkg';
4
9
  import { resolveVuetifyBase, normalizePath, writeStyles, cacheDir } from '@vuetify/loader-shared';
5
10
  import { isAbsolute, join, relative } from 'pathe';
6
11
  import { normalizePath as normalizePath$1 } from 'vite';
7
- import { isPackageExists } from 'local-pkg';
8
12
 
9
- const version = "0.4.12";
13
+ const version = "0.5.1";
14
+
15
+ const VIRTUAL_VUETIFY_CONFIGURATION = "virtual:vuetify-configuration";
16
+ const RESOLVED_VIRTUAL_VUETIFY_CONFIGURATION = `/@nuxt-vuetify-configuration/${VIRTUAL_VUETIFY_CONFIGURATION.slice("virtual:".length)}`;
17
+ const VIRTUAL_VUETIFY_DATE_CONFIGURATION = "virtual:vuetify-date-configuration";
18
+ const RESOLVED_VIRTUAL_VUETIFY_DATE_CONFIGURATION = `/@nuxt-vuetify-configuration/${VIRTUAL_VUETIFY_DATE_CONFIGURATION.slice("virtual:".length)}`;
19
+ const VIRTUAL_VUETIFY_ICONS_CONFIGURATION = "virtual:vuetify-icons-configuration";
20
+ const RESOLVED_VIRTUAL_VUETIFY_ICONS_CONFIGURATION = `/@nuxt-vuetify-configuration/${VIRTUAL_VUETIFY_ICONS_CONFIGURATION.slice("virtual:".length)}`;
21
+ const RESOLVED_VIRTUAL_MODULES = [
22
+ RESOLVED_VIRTUAL_VUETIFY_DATE_CONFIGURATION,
23
+ RESOLVED_VIRTUAL_VUETIFY_ICONS_CONFIGURATION,
24
+ RESOLVED_VIRTUAL_VUETIFY_CONFIGURATION
25
+ ];
26
+
27
+ async function loadVuetifyConfiguration(cwd = process.cwd(), configOrPath = cwd, defaults = {}, extraConfigSources = []) {
28
+ let inlineConfig = {};
29
+ if (typeof configOrPath !== "string") {
30
+ inlineConfig = configOrPath;
31
+ configOrPath = process.cwd();
32
+ }
33
+ const resolved = resolve(cwd, configOrPath);
34
+ let isFile = false;
35
+ if (existsSync(resolved) && statSync(resolved).isFile()) {
36
+ isFile = true;
37
+ cwd = dirname(resolved).replace(/\\/g, "/");
38
+ }
39
+ const rewrite = (config) => {
40
+ if (typeof config === "function")
41
+ return config();
42
+ return config;
43
+ };
44
+ const loader = createConfigLoader({
45
+ sources: isFile ? [
46
+ {
47
+ files: resolved,
48
+ extensions: [],
49
+ rewrite
50
+ }
51
+ ] : [
52
+ {
53
+ files: [
54
+ "vuetify.config"
55
+ ],
56
+ // we don't want `package.json` to be loaded
57
+ extensions: ["mts", "cts", "ts", "mjs", "cjs", "js"],
58
+ rewrite
59
+ },
60
+ ...extraConfigSources
61
+ ],
62
+ cwd,
63
+ defaults: inlineConfig,
64
+ merge: false
65
+ });
66
+ const result = await loader.load();
67
+ if (result.config?.config === false)
68
+ result.config = Object.assign(defaults, inlineConfig);
69
+ else
70
+ result.config = Object.assign(defaults, result.config || inlineConfig);
71
+ delete result.config.config;
72
+ return result;
73
+ }
74
+
75
+ async function mergeVuetifyModules(options, nuxt) {
76
+ const moduleOptions = [];
77
+ const vuetifyConfigurationFilesToWatch = /* @__PURE__ */ new Set();
78
+ await nuxt.callHook("vuetify:registerModule", (layerModuleOptions) => moduleOptions.push(layerModuleOptions));
79
+ if (nuxt.options._layers.length > 1) {
80
+ for (let i = 1; i < nuxt.options._layers.length; i++) {
81
+ const layer = nuxt.options._layers[i];
82
+ const resolvedOptions2 = await loadVuetifyConfiguration(
83
+ layer.config.rootDir,
84
+ layer.config.vuetify?.vuetifyOptions
85
+ );
86
+ if (resolvedOptions2.sources.length)
87
+ resolvedOptions2.sources.forEach((s) => vuetifyConfigurationFilesToWatch.add(s.replace(/\\/g, "/")));
88
+ moduleOptions.push({
89
+ moduleOptions: layer.config.vuetify?.moduleOptions,
90
+ vuetifyOptions: resolvedOptions2.config
91
+ });
92
+ }
93
+ }
94
+ const resolvedOptions = await loadVuetifyConfiguration(
95
+ nuxt.options.rootDir,
96
+ options.vuetifyOptions
97
+ );
98
+ if (resolvedOptions.sources.length)
99
+ resolvedOptions.sources.forEach((s) => vuetifyConfigurationFilesToWatch.add(s.replace(/\\/g, "/")));
100
+ moduleOptions.push({
101
+ moduleOptions: options.moduleOptions,
102
+ vuetifyOptions: resolvedOptions.config
103
+ });
104
+ if (moduleOptions.length > 1) {
105
+ const [base, ...rest] = moduleOptions;
106
+ return {
107
+ configuration: defu(base, ...rest),
108
+ vuetifyConfigurationFilesToWatch
109
+ };
110
+ } else {
111
+ return {
112
+ configuration: {
113
+ moduleOptions: options.moduleOptions,
114
+ vuetifyOptions: resolvedOptions.config
115
+ },
116
+ vuetifyConfigurationFilesToWatch
117
+ };
118
+ }
119
+ }
120
+
121
+ function detectDate() {
122
+ const result = [];
123
+ [
124
+ "date-fns",
125
+ "moment",
126
+ "luxon",
127
+ "dayjs",
128
+ "js-joda",
129
+ "date-fns-jalali",
130
+ "jalaali",
131
+ "hijri"
132
+ ].forEach((adapter) => {
133
+ if (isPackageExists(`@date-io/${adapter}`))
134
+ result.push(adapter);
135
+ });
136
+ return result;
137
+ }
138
+ function cleanupBlueprint(vuetifyOptions) {
139
+ const blueprint = vuetifyOptions.blueprint;
140
+ if (blueprint) {
141
+ delete blueprint.ssr;
142
+ delete blueprint.components;
143
+ delete blueprint.directives;
144
+ delete blueprint.locale;
145
+ delete blueprint.date;
146
+ delete blueprint.icons;
147
+ vuetifyOptions.blueprint = blueprint;
148
+ }
149
+ }
150
+ function checkVuetifyPlugins(config) {
151
+ let plugin = config.plugins?.find((p) => p && typeof p === "object" && "name" in p && p.name === "vuetify:import");
152
+ if (plugin)
153
+ throw new Error("Remove vite-plugin-vuetify plugin from Vite Plugins entry in Nuxt config file!");
154
+ plugin = config.plugins?.find((p) => p && typeof p === "object" && "name" in p && p.name === "vuetify:styles");
155
+ if (plugin)
156
+ throw new Error("Remove vite-plugin-vuetify plugin from Vite Plugins entry in Nuxt config file!");
157
+ }
158
+ function resolveVuetifyComponents(resolver) {
159
+ const vuetifyBase = resolveVuetifyBase();
160
+ const componentsPromise = importMapResolver();
161
+ const labComponentsPromise = importMapLabResolver();
162
+ return {
163
+ vuetifyBase,
164
+ componentsPromise,
165
+ labComponentsPromise
166
+ };
167
+ async function importMapResolver() {
168
+ return JSON.parse(await readFile(resolver.resolve(vuetifyBase, "dist/json/importMap.json"), "utf-8")).components;
169
+ }
170
+ async function importMapLabResolver() {
171
+ return JSON.parse(await readFile(resolver.resolve(vuetifyBase, "dist/json/importMap-labs.json"), "utf-8")).components;
172
+ }
173
+ }
174
+
175
+ const cssFonts = ["unocss-mdi", "mdi", "md", "fa", "fa4"];
176
+ const iconsPackageNames = {
177
+ "unocss-mdi": { name: "@mdi/font", css: "" },
178
+ "mdi": { name: "@mdi/font", css: "@mdi/font/css/materialdesignicons.css" },
179
+ "md": { name: "material-design-icons-iconfont", css: "@mdi/font/css/materialdesignicons.css" },
180
+ "fa": { name: "@fortawesome/fontawesome-free", css: "@fortawesome/fontawesome-free/css/all.css" },
181
+ "fa4": { name: "font-awesome@4.7.0", css: "font-awesome/css/font-awesome.min.css" }
182
+ };
183
+ const iconsCDN = {
184
+ "unocss-mdi": "",
185
+ "mdi": "https://cdn.jsdelivr.net/npm/@mdi/font@5.x/css/materialdesignicons.min.css",
186
+ "md": "https://fonts.googleapis.com/css?family=Material+Icons",
187
+ "fa": "https://cdn.jsdelivr.net/npm/@fortawesome/fontawesome-free@latest/css/all.min.css",
188
+ "fa4": "https://cdn.jsdelivr.net/npm/font-awesome@4.x/css/font-awesome.min.css"
189
+ };
190
+ const disabledResolvedIcons = Object.freeze({
191
+ enabled: false,
192
+ unocss: false,
193
+ unocssAliases: false,
194
+ unocssIconPrefix: "i-",
195
+ imports: [],
196
+ aliases: [],
197
+ sets: [],
198
+ cdn: [],
199
+ local: [],
200
+ svg: {}
201
+ });
202
+ function prepareIcons(unocssPresent, logger, vuetifyOptions) {
203
+ if (vuetifyOptions.icons === false)
204
+ return disabledResolvedIcons;
205
+ const icons = vuetifyOptions.icons || {};
206
+ let { defaultSet = "mdi", sets } = icons;
207
+ if (!defaultSet)
208
+ defaultSet = icons.defaultSet = "mdi";
209
+ if (!sets && defaultSet !== "mdi-svg" && defaultSet !== "fa-svg" && defaultSet !== "custom")
210
+ sets = [{ name: defaultSet || "mdi" }];
211
+ sets = sets ? convertFontSetsToObjectNotation(sets) : [];
212
+ const resolvedIcons = {
213
+ enabled: true,
214
+ unocss: unocssPresent && (defaultSet === "unocss-mdi" || sets.some((s) => s.name === "unocss-mdi")),
215
+ unocssAliases: defaultSet === "unocss-mdi",
216
+ unocssIconPrefix: icons.unocssIconPrefix ?? "i-",
217
+ defaultSet,
218
+ sets: [],
219
+ aliases: [],
220
+ imports: [],
221
+ cdn: [],
222
+ local: [],
223
+ svg: {
224
+ mdi: false
225
+ }
226
+ };
227
+ if (sets) {
228
+ if (!unocssPresent && defaultSet === "unocss-mdi") {
229
+ logger.warn("Configured unocss-mdi as default icon set and @unocss/nuxt is not installed, reverting configuration to use mdi icon set: install @unocss/nuxt module or change the default icon set!");
230
+ defaultSet = "mdi";
231
+ sets = sets.filter((s) => s.name !== "unocss-mdi");
232
+ }
233
+ sets.filter((s) => cssFonts.includes(s.name)).forEach(({ name, cdn }) => {
234
+ if (name === "unocss-mdi")
235
+ return;
236
+ resolvedIcons.imports.push(`import {${name === defaultSet ? "aliases," : ""}${name}} from 'vuetify/iconsets/${name}'`);
237
+ resolvedIcons.sets.push(name);
238
+ if (isPackageExists(iconsPackageNames[name].name))
239
+ resolvedIcons.local.push(iconsPackageNames[name].css);
240
+ else
241
+ resolvedIcons.cdn.push([name, cdn ?? iconsCDN[name]]);
242
+ });
243
+ if (resolvedIcons.unocss && defaultSet === "unocss-mdi") {
244
+ if (!resolvedIcons.sets.includes("mdi")) {
245
+ resolvedIcons.sets.push("mdi");
246
+ resolvedIcons.imports.push("import {mdi} from 'vuetify/iconsets/mdi'");
247
+ }
248
+ resolvedIcons.defaultSet = "mdi";
249
+ }
250
+ }
251
+ let faSvg = icons.svg?.fa;
252
+ if (defaultSet === "fa-svg" || faSvg) {
253
+ if (!faSvg)
254
+ faSvg = {};
255
+ let faSvgExists = isPackageExists("@fortawesome/fontawesome-svg-core");
256
+ if (!faSvgExists)
257
+ logger.warn("Missing @fortawesome/fontawesome-svg-core dependency, install it!");
258
+ faSvgExists = isPackageExists("@fortawesome/vue-fontawesome");
259
+ if (faSvgExists) {
260
+ if (!faSvg.libraries?.length)
261
+ faSvg.libraries = [[false, "fas", "@fortawesome/free-solid-svg-icons"]];
262
+ for (const p in faSvg.libraries) {
263
+ const [_defaultExport, _name, library] = faSvg.libraries[p];
264
+ if (!isPackageExists(library)) {
265
+ faSvgExists = false;
266
+ logger.warn(`Missing library ${library} dependency, install it!`);
267
+ }
268
+ }
269
+ } else {
270
+ logger.warn("Missing @fortawesome/vue-fontawesome dependency, install it!");
271
+ }
272
+ if (faSvgExists) {
273
+ resolvedIcons.imports.push(`import {${defaultSet === "fa-svg" ? "aliases," : ""}fa} from 'vuetify/iconsets/fa-svg'`);
274
+ resolvedIcons.imports.push("import { library } from '@fortawesome/fontawesome-svg-core'");
275
+ resolvedIcons.imports.push("import { FontAwesomeIcon } from '@fortawesome/vue-fontawesome'");
276
+ resolvedIcons.imports.push("import { useNuxtApp } from '#app'");
277
+ resolvedIcons.svg.fa = ["useNuxtApp().vueApp.component('font-awesome-icon', FontAwesomeIcon)"];
278
+ faSvg.libraries.forEach(([defaultExport, name, library]) => {
279
+ resolvedIcons.imports.push(`import ${defaultExport ? name : `{${name}}`} from '${library}'`);
280
+ resolvedIcons.svg.fa.push(`library.add(${name})`);
281
+ });
282
+ resolvedIcons.sets.push("fa");
283
+ if (defaultSet === "fa-svg")
284
+ resolvedIcons.defaultSet = "fa";
285
+ }
286
+ }
287
+ let mdiSvg = icons.svg?.mdi;
288
+ if (defaultSet === "mdi-svg" || mdiSvg) {
289
+ if (!mdiSvg)
290
+ mdiSvg = {};
291
+ const mdiSvgExists = isPackageExists("@mdi/js");
292
+ if (mdiSvgExists) {
293
+ resolvedIcons.svg.mdi = true;
294
+ resolvedIcons.imports.push(`import {${defaultSet === "mdi-svg" ? "aliases," : ""}mdi} from 'vuetify/iconsets/mdi-svg'`);
295
+ if (mdiSvg && mdiSvg.aliases) {
296
+ resolvedIcons.imports.push(`import {${Object.values(mdiSvg.aliases).join(",")}} from '@mdi/js'`);
297
+ Object.entries(mdiSvg.aliases).forEach(([alias, icon]) => {
298
+ resolvedIcons.aliases.push(`${alias}: ${icon}`);
299
+ });
300
+ }
301
+ resolvedIcons.sets.push("mdi");
302
+ if (defaultSet === "mdi-svg")
303
+ resolvedIcons.defaultSet = "mdi";
304
+ } else {
305
+ resolvedIcons.svg.mdi = false;
306
+ logger.warn("Missing @mdi/js dependency, install it!");
307
+ }
308
+ }
309
+ if (defaultSet !== "custom" && !resolvedIcons.unocss && !resolvedIcons.local?.length && !resolvedIcons.cdn?.length && !resolvedIcons.svg?.mdi && !resolvedIcons.svg?.fa?.length) {
310
+ logger.warn("No icons found, icons disabled!");
311
+ return disabledResolvedIcons;
312
+ }
313
+ return resolvedIcons;
314
+ }
315
+ function convertFontSetsToObjectNotation(sets) {
316
+ const result = [];
317
+ if (typeof sets === "string") {
318
+ result.push({ name: sets });
319
+ } else {
320
+ for (const set of sets) {
321
+ if (typeof set === "string")
322
+ result.push({ name: set });
323
+ else
324
+ result.push(set);
325
+ }
326
+ }
327
+ return result;
328
+ }
329
+
330
+ async function load(options, nuxt, ctx) {
331
+ var _a;
332
+ const {
333
+ configuration,
334
+ vuetifyConfigurationFilesToWatch
335
+ } = await mergeVuetifyModules(options, nuxt);
336
+ if (typeof ctx.componentsPromise === "undefined") {
337
+ const {
338
+ componentsPromise,
339
+ labComponentsPromise
340
+ } = resolveVuetifyComponents(ctx.resolver);
341
+ ctx.componentsPromise = componentsPromise;
342
+ ctx.labComponentsPromise = labComponentsPromise;
343
+ }
344
+ const { vuetifyOptions = {} } = configuration;
345
+ const {
346
+ directives: _directives,
347
+ labComponents: _labComponents,
348
+ ...vOptions
349
+ } = vuetifyOptions;
350
+ const vuetifyAppOptions = defu(vOptions, {});
351
+ cleanupBlueprint(vuetifyAppOptions);
352
+ ctx.dateAdapter = void 0;
353
+ const dateOptions = vuetifyOptions.date;
354
+ if (dateOptions) {
355
+ const adapter = dateOptions.adapter;
356
+ const date = detectDate();
357
+ if (!adapter && date.length > 1)
358
+ throw new Error(`Multiple date adapters found: ${date.map((d) => `@date-io/${d[0]}`).join(", ")}, please specify the adapter to use in the "vuetifyOptions.date.adapter" option.`);
359
+ if (adapter) {
360
+ if (adapter === "vuetify" || adapter === "custom") {
361
+ ctx.dateAdapter = adapter;
362
+ } else {
363
+ if (date.find((d) => d === adapter) === void 0)
364
+ ctx.logger.warn(`Ignoring Vuetify Date configuration, date adapter "@date-io/${adapter}" not installed!`);
365
+ else
366
+ ctx.dateAdapter = adapter;
367
+ }
368
+ } else if (date.length === 0) {
369
+ ctx.dateAdapter = "vuetify";
370
+ } else {
371
+ ctx.dateAdapter = date[0];
372
+ }
373
+ }
374
+ const oldIcons = ctx.icons;
375
+ if (oldIcons && oldIcons.cdn?.length && nuxt.options.app.head.link)
376
+ nuxt.options.app.head.link = nuxt.options.app.head.link.filter((link) => !link.key || !oldIcons.cdn.some(([key]) => link.key === key));
377
+ ctx.moduleOptions = configuration.moduleOptions;
378
+ ctx.vuetifyOptions = configuration.vuetifyOptions;
379
+ ctx.vuetifyFilesToWatch = Array.from(vuetifyConfigurationFilesToWatch);
380
+ ctx.icons = prepareIcons(ctx.unocss, ctx.logger, vuetifyAppOptions);
381
+ if (ctx.icons.enabled) {
382
+ ctx.icons.local?.forEach((css) => nuxt.options.css.push(css));
383
+ if (ctx.icons.cdn?.length) {
384
+ (_a = nuxt.options.app.head).link ?? (_a.link = []);
385
+ ctx.icons.cdn.forEach(([key, href]) => nuxt.options.app.head.link.push({
386
+ key,
387
+ rel: "stylesheet",
388
+ href,
389
+ type: "text/css",
390
+ crossorigin: "anonymous"
391
+ }));
392
+ }
393
+ }
394
+ }
395
+ function registerWatcher(options, nuxt, ctx) {
396
+ if (nuxt.options.dev) {
397
+ let pageReload;
398
+ nuxt.hooks.hook("builder:watch", (_event, path) => {
399
+ if (!pageReload && ctx.vuetifyFilesToWatch.includes(path))
400
+ return nuxt.callHook("restart");
401
+ });
402
+ nuxt.hook("vite:serverCreated", (server, { isClient }) => {
403
+ if (!server.ws || !isClient)
404
+ return;
405
+ pageReload = debounce(async () => {
406
+ const modules = [];
407
+ for (const v of RESOLVED_VIRTUAL_MODULES) {
408
+ const module = server.moduleGraph.getModuleById(v);
409
+ if (module)
410
+ modules.push(module);
411
+ }
412
+ await load(options, nuxt, ctx);
413
+ if (modules.length)
414
+ await Promise.all(modules.map((m) => server.reloadModule(m)));
415
+ }, 50, { trailing: false });
416
+ });
417
+ addVitePlugin({
418
+ name: "vuetify:configuration:watch",
419
+ enforce: "pre",
420
+ handleHotUpdate({ file }) {
421
+ if (pageReload && ctx.vuetifyFilesToWatch.includes(file))
422
+ return pageReload();
423
+ }
424
+ });
425
+ }
426
+ }
10
427
 
11
428
  function isSubdir(root, test) {
12
429
  const relative$1 = relative(root, test);
@@ -177,26 +594,7 @@ function vuetifyStylesPlugin(options, logger) {
177
594
  };
178
595
  }
179
596
 
180
- const VIRTUAL_VUETIFY_CONFIGURATION = "virtual:vuetify-configuration";
181
- const RESOLVED_VIRTUAL_VUETIFY_CONFIGURATION = `/@nuxt-vuetify-configuration/${VIRTUAL_VUETIFY_CONFIGURATION.slice("virtual:".length)}`;
182
- const VIRTUAL_VUETIFY_DATE_CONFIGURATION = "virtual:vuetify-date-configuration";
183
- const RESOLVED_VIRTUAL_VUETIFY_DATE_CONFIGURATION = `/@nuxt-vuetify-configuration/${VIRTUAL_VUETIFY_DATE_CONFIGURATION.slice("virtual:".length)}`;
184
- const VIRTUAL_VUETIFY_ICONS_CONFIGURATION = "virtual:vuetify-icons-configuration";
185
- const RESOLVED_VIRTUAL_VUETIFY_ICONS_CONFIGURATION = `/@nuxt-vuetify-configuration/${VIRTUAL_VUETIFY_ICONS_CONFIGURATION.slice("virtual:".length)}`;
186
-
187
- function vuetifyConfigurationPlugin(isDev, isSSR, i18n, directives, labComponents, vuetifyAppOptions, componentsPromise, labComponentsPromise, logger) {
188
- const {
189
- directives: _directives,
190
- date: _date,
191
- icons: _icons,
192
- localeMessages,
193
- components,
194
- ssr,
195
- aliases,
196
- ...newVuetifyOptions
197
- } = vuetifyAppOptions;
198
- if (isSSR)
199
- newVuetifyOptions.ssr = ssr ?? true;
597
+ function vuetifyConfigurationPlugin(ctx) {
200
598
  return {
201
599
  name: "vuetify:configuration:nuxt",
202
600
  enforce: "pre",
@@ -206,383 +604,219 @@ function vuetifyConfigurationPlugin(isDev, isSSR, i18n, directives, labComponent
206
604
  },
207
605
  async load(id) {
208
606
  if (id === RESOLVED_VIRTUAL_VUETIFY_CONFIGURATION) {
209
- if (i18n && newVuetifyOptions.locale) {
607
+ const {
608
+ directives: _directives,
609
+ date: _date,
610
+ icons: _icons,
611
+ localeMessages: _localeMessages,
612
+ components: _components,
613
+ labComponents: _labComponents,
614
+ ssr,
615
+ aliases: _aliases,
616
+ ...newVuetifyOptions
617
+ } = ctx.vuetifyOptions;
618
+ if (ctx.isSSR)
619
+ newVuetifyOptions.ssr = ssr ?? true;
620
+ if (ctx.i18n && newVuetifyOptions.locale) {
210
621
  delete newVuetifyOptions.locale.rtl;
211
622
  delete newVuetifyOptions.locale.locale;
212
623
  delete newVuetifyOptions.locale.fallback;
213
624
  }
214
- const result = await buildConfiguration();
625
+ const result = await buildConfiguration(ctx);
215
626
  const deepCopy = result.messages.length > 0;
216
627
  return `${result.imports}
217
628
 
218
- export const isDev = ${isDev}
219
- export function vuetifyConfiguration() {
220
- const options = JSON.parse('${JSON.stringify(newVuetifyOptions)}')
221
- ${result.directives}
222
- ${result.aliases}
223
- ${result.components}
224
- ${result.messages}
225
- return options
226
- }
227
- ${deepCopy ? `function deepCopy(src,des) {
228
- for (const key in src) {
229
- if (typeof src[key] === 'object') {
230
- if (typeof des[key] !== 'object') des[key] = {}
231
- deepCopy(src[key], des[key])
232
- } else {
233
- des[key] = src[key]
234
- }
235
- }
236
- }
237
- ` : ""}
238
- `;
239
- }
240
- }
241
- };
242
- async function buildConfiguration() {
243
- const dateOptions = vuetifyAppOptions.date;
244
- const config = {
245
- directives: "",
246
- imports: [],
247
- aliasEntries: [],
248
- aliases: aliases || {},
249
- components: new Set(components ? Array.isArray(components) ? components : [components] : []),
250
- labComponents: /* @__PURE__ */ new Set(),
251
- messages: ""
252
- };
253
- if (directives) {
254
- if (typeof directives === "boolean") {
255
- config.imports.push("import * as directives from 'vuetify/directives'");
256
- config.directives = "options.directives = directives";
257
- } else {
258
- const useDirectives = Array.isArray(directives) ? [...new Set(...directives)] : [directives];
259
- config.imports.push(useDirectives.map((d) => `import { ${d} } from 'vuetify/directives/${d}'`).join("\n"));
260
- config.directives = `options.directives = {${useDirectives.join(",")}}`;
261
- }
262
- }
263
- const importMapComponents = await componentsPromise;
264
- const componentsToImport = /* @__PURE__ */ new Map();
265
- config.components.forEach((component) => {
266
- const { from } = importMapComponents[component];
267
- if (!from) {
268
- logger.warn(`Component ${component} not found in Vuetify.`);
269
- return;
270
- }
271
- const parts = from.split("/");
272
- if (parts.length < 2) {
273
- logger.warn(`Component ${component} not found in Vuetify, please report a new issue.`);
274
- return;
275
- }
276
- if (!componentsToImport.has(parts[1]))
277
- componentsToImport.set(parts[1], []);
278
- const componentsArray = componentsToImport.get(parts[1]);
279
- if (!componentsArray.includes(component))
280
- componentsArray.push(component);
281
- });
282
- Object.entries(config.aliases).forEach(([key, component]) => {
283
- const { from } = importMapComponents[component];
284
- if (!from) {
285
- logger.warn(`Component ${component} not found in Vuetify.`);
286
- return;
287
- }
288
- const parts = from.split("/");
289
- if (parts.length < 2) {
290
- logger.warn(`Component ${component} not found in Vuetify, please report a new issue.`);
291
- return;
292
- }
293
- if (!componentsToImport.has(parts[1]))
294
- componentsToImport.set(parts[1], []);
295
- const componentsArray = componentsToImport.get(parts[1]);
296
- if (!componentsArray.includes(component))
297
- componentsArray.push(component);
298
- config.aliasEntries.push(`'${key}': ${component}`);
299
- });
300
- componentsToImport.forEach((componentsArray, from) => {
301
- config.imports.push(`import {${componentsArray.join(",")}} from 'vuetify/components/${from}'`);
302
- });
303
- let addDatePicker = true;
304
- if (labComponents) {
305
- const useLabComponents = [];
306
- if (typeof labComponents === "boolean") {
307
- config.imports.push("import * as labsComponents from 'vuetify/labs/components'");
308
- config.labComponents.add("*");
309
- addDatePicker = false;
310
- } else if (typeof labComponents === "string") {
311
- useLabComponents.push(labComponents);
312
- } else if (Array.isArray(labComponents)) {
313
- useLabComponents.push(...labComponents);
314
- }
315
- if (useLabComponents.length) {
316
- componentsToImport.clear();
317
- const importMapLabComponents = await labComponentsPromise;
318
- useLabComponents.forEach((component) => {
319
- const { from } = importMapLabComponents[component];
320
- if (!from) {
321
- logger.warn(`Lab Component ${component} not found in Vuetify.`);
322
- return;
323
- }
324
- const parts = from.split("/");
325
- if (parts.length < 2) {
326
- logger.warn(`Lab Component ${component} not found in Vuetify, please report a new issue.`);
327
- return;
328
- }
329
- if (!componentsToImport.has(parts[1]))
330
- componentsToImport.set(parts[1], []);
331
- const componentsArray = componentsToImport.get(parts[1]);
332
- if (!componentsArray.includes(component))
333
- componentsArray.push(component);
334
- config.labComponents.add(component);
335
- });
336
- if (dateOptions && !config.labComponents.has("VDatePicker")) {
337
- const entry = componentsToImport.get("VDatePicker");
338
- if (entry) {
339
- entry.push("VDatePicker");
340
- config.labComponents.add("VDatePicker");
341
- }
342
- }
343
- componentsToImport.forEach((componentsArray, from) => {
344
- config.imports.push(`import {${componentsArray.join(",")}} from 'vuetify/labs/${from}'`);
345
- });
346
- addDatePicker = !config.labComponents.has("VDatePicker");
347
- }
348
- }
349
- if (dateOptions && addDatePicker) {
350
- config.imports.push("import {VDatePicker} from 'vuetify/labs/VDatePicker'");
351
- config.labComponents.add("VDatePicker");
352
- }
353
- let componentsEntry = "";
354
- if (config.components.size) {
355
- if (config.labComponents.size) {
356
- if (config.labComponents.has("*"))
357
- componentsEntry = `options.components = {${Array.from(config.components).join(",")},...labsComponents}`;
358
- else
359
- componentsEntry = `options.components = {${Array.from(config.components).join(",")},${Array.from(config.labComponents).join(",")}}`;
360
- } else {
361
- componentsEntry = `options.components = {${Array.from(config.components).join(",")}}`;
362
- }
363
- } else if (config.labComponents.size) {
364
- if (config.labComponents.has("*"))
365
- componentsEntry = "options.components = {...labsComponents}";
366
- else
367
- componentsEntry = `options.components = {${Array.from(config.labComponents).join(",")}}`;
368
- }
369
- if (!i18n && localeMessages) {
370
- const useLocales = Array.isArray(localeMessages) ? [.../* @__PURE__ */ new Set([...localeMessages])] : [localeMessages];
371
- config.imports.push(`import {${useLocales.join(",")}} from 'vuetify/locale'`);
372
- config.messages = `
373
- options.locale = options.locale || {}
374
- options.locale.messages = options.locale.messages || {}
375
- ${useLocales.map((locale) => {
376
- return `
377
- if ('${locale}' in options.locale.messages)
378
- deepCopy(options.locale.messages['${locale}'],${locale})
379
-
380
- options.locale.messages['${locale}'] = ${locale}
381
- `;
382
- }).join("")}
383
- `;
384
- }
385
- return {
386
- imports: config.imports.length ? config.imports.join("\n") : "",
387
- components: componentsEntry,
388
- aliases: config.aliasEntries.length ? `options.aliases = {${config.aliasEntries.join(",")}}` : "",
389
- directives: config.directives,
390
- messages: config.messages
391
- };
392
- }
393
- }
394
-
395
- function vuetifyDateConfigurationPlugin(isDev, i18n, dateAdapter, dateOptions) {
396
- const { adapter: _adapter, ...newDateOptions } = dateOptions;
397
- return {
398
- name: "vuetify:date-configuration:nuxt",
399
- enforce: "pre",
400
- resolveId(id) {
401
- if (id === VIRTUAL_VUETIFY_DATE_CONFIGURATION)
402
- return RESOLVED_VIRTUAL_VUETIFY_DATE_CONFIGURATION;
403
- },
404
- async load(id) {
405
- if (id === RESOLVED_VIRTUAL_VUETIFY_DATE_CONFIGURATION) {
406
- const imports = dateAdapter === "vuetify" ? "import { VuetifyDateAdapter } from 'vuetify/labs/date/adapters/vuetify'" : dateAdapter === "custom" ? "" : `import Adapter from '@date-io/${dateAdapter}'`;
407
- return `${imports}
408
- export const isDev = ${isDev}
409
- export const i18n = ${i18n}
410
- export const adapter = '${dateAdapter}'
411
- export function dateConfiguration() {
412
- const options = JSON.parse('${JSON.stringify(newDateOptions)}')
413
- ${buildAdapter()}
414
- return options
415
- }
416
- `;
417
- }
418
- }
419
- };
420
- function buildAdapter() {
421
- if (dateAdapter === "custom")
422
- return "";
423
- if (dateAdapter === "vuetify")
424
- return "options.adapter = VuetifyDateAdapter";
425
- return "options.adapter = Adapter";
426
- }
427
- }
428
-
429
- const cssFonts = ["unocss-mdi", "mdi", "md", "fa", "fa4"];
430
- const iconsPackageNames = {
431
- "unocss-mdi": { name: "@mdi/font", css: "" },
432
- "mdi": { name: "@mdi/font", css: "@mdi/font/css/materialdesignicons.css" },
433
- "md": { name: "material-design-icons-iconfont", css: "@mdi/font/css/materialdesignicons.css" },
434
- "fa": { name: "@fortawesome/fontawesome-free", css: "@fortawesome/fontawesome-free/css/all.css" },
435
- "fa4": { name: "font-awesome@4.7.0", css: "font-awesome/css/font-awesome.min.css" }
436
- };
437
- const iconsCDN = {
438
- "unocss-mdi": "",
439
- "mdi": "https://cdn.jsdelivr.net/npm/@mdi/font@5.x/css/materialdesignicons.min.css",
440
- "md": "https://fonts.googleapis.com/css?family=Material+Icons",
441
- "fa": "https://cdn.jsdelivr.net/npm/@fortawesome/fontawesome-free@latest/css/all.min.css",
442
- "fa4": "https://cdn.jsdelivr.net/npm/font-awesome@4.x/css/font-awesome.min.css"
443
- };
444
- const disabledResolvedIcons = Object.freeze({
445
- enabled: false,
446
- unocss: false,
447
- unocssAliases: false,
448
- unocssIconPrefix: "i-",
449
- imports: [],
450
- aliases: [],
451
- sets: [],
452
- cdn: [],
453
- local: [],
454
- svg: {}
455
- });
456
- function prepareIcons(unocssPresent, logger, vuetifyOptions) {
457
- if (vuetifyOptions.icons === false)
458
- return disabledResolvedIcons;
459
- const icons = vuetifyOptions.icons || {};
460
- let { defaultSet = "mdi", sets } = icons;
461
- if (!defaultSet)
462
- defaultSet = icons.defaultSet = "mdi";
463
- if (!sets && defaultSet !== "mdi-svg" && defaultSet !== "fa-svg" && defaultSet !== "custom")
464
- sets = [{ name: defaultSet || "mdi" }];
465
- sets = sets ? convertFontSetsToObjectNotation(sets) : [];
466
- const resolvedIcons = {
467
- enabled: true,
468
- unocss: unocssPresent && (defaultSet === "unocss-mdi" || sets.some((s) => s.name === "unocss-mdi")),
469
- unocssAliases: defaultSet === "unocss-mdi",
470
- unocssIconPrefix: icons.unocssIconPrefix ?? "i-",
471
- defaultSet,
472
- sets: [],
473
- aliases: [],
474
- imports: [],
475
- cdn: [],
476
- local: [],
477
- svg: {
478
- mdi: false
479
- }
480
- };
481
- if (sets) {
482
- if (!unocssPresent && defaultSet === "unocss-mdi") {
483
- logger.warn("Configured unocss-mdi as default icon set and @unocss/nuxt is not installed, reverting configuration to use mdi icon set: install @unocss/nuxt module or change the default icon set!");
484
- defaultSet = "mdi";
485
- sets = sets.filter((s) => s.name !== "unocss-mdi");
486
- }
487
- sets.filter((s) => cssFonts.includes(s.name)).forEach(({ name, cdn }) => {
488
- if (name === "unocss-mdi")
489
- return;
490
- resolvedIcons.imports.push(`import {${name === defaultSet ? "aliases," : ""}${name}} from 'vuetify/iconsets/${name}'`);
491
- resolvedIcons.sets.push(name);
492
- if (isPackageExists(iconsPackageNames[name].name))
493
- resolvedIcons.local.push(iconsPackageNames[name].css);
494
- else
495
- resolvedIcons.cdn.push(cdn ?? iconsCDN[name]);
496
- });
497
- if (resolvedIcons.unocss && defaultSet === "unocss-mdi") {
498
- if (!resolvedIcons.sets.includes("mdi")) {
499
- resolvedIcons.sets.push("mdi");
500
- resolvedIcons.imports.push("import {mdi} from 'vuetify/iconsets/mdi'");
629
+ export const isDev = ${ctx.isDev}
630
+ export function vuetifyConfiguration() {
631
+ const options = JSON.parse('${JSON.stringify(newVuetifyOptions)}')
632
+ ${result.directives}
633
+ ${result.aliases}
634
+ ${result.components}
635
+ ${result.messages}
636
+ return options
637
+ }
638
+ ${deepCopy ? `function deepCopy(src,des) {
639
+ for (const key in src) {
640
+ if (typeof src[key] === 'object') {
641
+ if (typeof des[key] !== 'object') des[key] = {}
642
+ deepCopy(src[key], des[key])
643
+ } else {
644
+ des[key] = src[key]
501
645
  }
502
- resolvedIcons.defaultSet = "mdi";
503
646
  }
504
647
  }
505
- let faSvg = icons.svg?.fa;
506
- if (defaultSet === "fa-svg" || faSvg) {
507
- if (!faSvg)
508
- faSvg = {};
509
- let faSvgExists = isPackageExists("@fortawesome/fontawesome-svg-core");
510
- if (!faSvgExists)
511
- logger.warn("Missing @fortawesome/fontawesome-svg-core dependency, install it!");
512
- faSvgExists = isPackageExists("@fortawesome/vue-fontawesome");
513
- if (faSvgExists) {
514
- if (!faSvg.libraries?.length)
515
- faSvg.libraries = [[false, "fas", "@fortawesome/free-solid-svg-icons"]];
516
- for (const p in faSvg.libraries) {
517
- const [_defaultExport, _name, library] = faSvg.libraries[p];
518
- if (!isPackageExists(library)) {
519
- faSvgExists = false;
520
- logger.warn(`Missing library ${library} dependency, install it!`);
521
- }
648
+ ` : ""}
649
+ `;
522
650
  }
523
- } else {
524
- logger.warn("Missing @fortawesome/vue-fontawesome dependency, install it!");
525
651
  }
526
- if (faSvgExists) {
527
- resolvedIcons.imports.push(`import {${defaultSet === "fa-svg" ? "aliases," : ""}fa} from 'vuetify/iconsets/fa-svg'`);
528
- resolvedIcons.imports.push("import { library } from '@fortawesome/fontawesome-svg-core'");
529
- resolvedIcons.imports.push("import { FontAwesomeIcon } from '@fortawesome/vue-fontawesome'");
530
- resolvedIcons.imports.push("import { useNuxtApp } from '#app'");
531
- resolvedIcons.svg.fa = ["useNuxtApp().vueApp.component('font-awesome-icon', FontAwesomeIcon)"];
532
- faSvg.libraries.forEach(([defaultExport, name, library]) => {
533
- resolvedIcons.imports.push(`import ${defaultExport ? name : `{${name}}`} from '${library}'`);
534
- resolvedIcons.svg.fa.push(`library.add(${name})`);
535
- });
536
- resolvedIcons.sets.push("fa");
537
- if (defaultSet === "fa-svg")
538
- resolvedIcons.defaultSet = "fa";
652
+ };
653
+ }
654
+ async function buildConfiguration(ctx) {
655
+ const {
656
+ componentsPromise,
657
+ labComponentsPromise,
658
+ logger,
659
+ vuetifyOptions
660
+ } = ctx;
661
+ const {
662
+ aliases,
663
+ components,
664
+ directives,
665
+ localeMessages,
666
+ labComponents,
667
+ date: dateOptions
668
+ } = vuetifyOptions;
669
+ const config = {
670
+ directives: "",
671
+ imports: [],
672
+ aliasEntries: [],
673
+ aliases: aliases || {},
674
+ components: new Set(components ? Array.isArray(components) ? components : [components] : []),
675
+ labComponents: /* @__PURE__ */ new Set(),
676
+ messages: ""
677
+ };
678
+ if (directives) {
679
+ if (typeof directives === "boolean") {
680
+ config.imports.push("import * as directives from 'vuetify/directives'");
681
+ config.directives = "options.directives = directives";
682
+ } else {
683
+ const useDirectives = Array.isArray(directives) ? [...new Set(...directives)] : [directives];
684
+ config.imports.push(useDirectives.map((d) => `import { ${d} } from 'vuetify/directives/${d}'`).join("\n"));
685
+ config.directives = `options.directives = {${useDirectives.join(",")}}`;
539
686
  }
540
687
  }
541
- let mdiSvg = icons.svg?.mdi;
542
- if (defaultSet === "mdi-svg" || mdiSvg) {
543
- if (!mdiSvg)
544
- mdiSvg = {};
545
- const mdiSvgExists = isPackageExists("@mdi/js");
546
- if (mdiSvgExists) {
547
- resolvedIcons.svg.mdi = true;
548
- resolvedIcons.imports.push(`import {${defaultSet === "mdi-svg" ? "aliases," : ""}mdi} from 'vuetify/iconsets/mdi-svg'`);
549
- if (mdiSvg && mdiSvg.aliases) {
550
- resolvedIcons.imports.push(`import {${Object.values(mdiSvg.aliases).join(",")}} from '@mdi/js'`);
551
- Object.entries(mdiSvg.aliases).forEach(([alias, icon]) => {
552
- resolvedIcons.aliases.push(`${alias}: ${icon}`);
553
- });
688
+ const importMapComponents = await componentsPromise;
689
+ const componentsToImport = /* @__PURE__ */ new Map();
690
+ config.components.forEach((component) => {
691
+ const { from } = importMapComponents[component];
692
+ if (!from) {
693
+ logger.warn(`Component ${component} not found in Vuetify.`);
694
+ return;
695
+ }
696
+ const parts = from.split("/");
697
+ if (parts.length < 2) {
698
+ logger.warn(`Component ${component} not found in Vuetify, please report a new issue.`);
699
+ return;
700
+ }
701
+ if (!componentsToImport.has(parts[1]))
702
+ componentsToImport.set(parts[1], []);
703
+ const componentsArray = componentsToImport.get(parts[1]);
704
+ if (!componentsArray.includes(component))
705
+ componentsArray.push(component);
706
+ });
707
+ Object.entries(config.aliases).forEach(([key, component]) => {
708
+ const { from } = importMapComponents[component];
709
+ if (!from) {
710
+ logger.warn(`Component ${component} not found in Vuetify.`);
711
+ return;
712
+ }
713
+ const parts = from.split("/");
714
+ if (parts.length < 2) {
715
+ logger.warn(`Component ${component} not found in Vuetify, please report a new issue.`);
716
+ return;
717
+ }
718
+ if (!componentsToImport.has(parts[1]))
719
+ componentsToImport.set(parts[1], []);
720
+ const componentsArray = componentsToImport.get(parts[1]);
721
+ if (!componentsArray.includes(component))
722
+ componentsArray.push(component);
723
+ config.aliasEntries.push(`'${key}': ${component}`);
724
+ });
725
+ componentsToImport.forEach((componentsArray, from) => {
726
+ config.imports.push(`import {${componentsArray.join(",")}} from 'vuetify/components/${from}'`);
727
+ });
728
+ let addDatePicker = true;
729
+ if (labComponents) {
730
+ const useLabComponents = [];
731
+ if (typeof labComponents === "boolean") {
732
+ config.imports.push("import * as labsComponents from 'vuetify/labs/components'");
733
+ config.labComponents.add("*");
734
+ addDatePicker = false;
735
+ } else if (typeof labComponents === "string") {
736
+ useLabComponents.push(labComponents);
737
+ } else if (Array.isArray(labComponents)) {
738
+ useLabComponents.push(...labComponents);
739
+ }
740
+ if (useLabComponents.length) {
741
+ componentsToImport.clear();
742
+ const importMapLabComponents = await labComponentsPromise;
743
+ useLabComponents.forEach((component) => {
744
+ const { from } = importMapLabComponents[component];
745
+ if (!from) {
746
+ logger.warn(`Lab Component ${component} not found in Vuetify.`);
747
+ return;
748
+ }
749
+ const parts = from.split("/");
750
+ if (parts.length < 2) {
751
+ logger.warn(`Lab Component ${component} not found in Vuetify, please report a new issue.`);
752
+ return;
753
+ }
754
+ if (!componentsToImport.has(parts[1]))
755
+ componentsToImport.set(parts[1], []);
756
+ const componentsArray = componentsToImport.get(parts[1]);
757
+ if (!componentsArray.includes(component))
758
+ componentsArray.push(component);
759
+ config.labComponents.add(component);
760
+ });
761
+ if (dateOptions && !config.labComponents.has("VDatePicker")) {
762
+ const entry = componentsToImport.get("VDatePicker");
763
+ if (entry) {
764
+ entry.push("VDatePicker");
765
+ config.labComponents.add("VDatePicker");
766
+ }
554
767
  }
555
- resolvedIcons.sets.push("mdi");
556
- if (defaultSet === "mdi-svg")
557
- resolvedIcons.defaultSet = "mdi";
558
- } else {
559
- resolvedIcons.svg.mdi = false;
560
- logger.warn("Missing @mdi/js dependency, install it!");
768
+ componentsToImport.forEach((componentsArray, from) => {
769
+ config.imports.push(`import {${componentsArray.join(",")}} from 'vuetify/labs/${from}'`);
770
+ });
771
+ addDatePicker = !config.labComponents.has("VDatePicker");
561
772
  }
562
773
  }
563
- if (defaultSet !== "custom" && !resolvedIcons.unocss && !resolvedIcons.local?.length && !resolvedIcons.cdn?.length && !resolvedIcons.svg?.mdi && !resolvedIcons.svg?.fa?.length) {
564
- logger.warn("No icons found, icons disabled!");
565
- return disabledResolvedIcons;
774
+ if (dateOptions && addDatePicker) {
775
+ config.imports.push("import {VDatePicker} from 'vuetify/labs/VDatePicker'");
776
+ config.labComponents.add("VDatePicker");
566
777
  }
567
- return resolvedIcons;
568
- }
569
- function convertFontSetsToObjectNotation(sets) {
570
- const result = [];
571
- if (typeof sets === "string") {
572
- result.push({ name: sets });
573
- } else {
574
- for (const set of sets) {
575
- if (typeof set === "string")
576
- result.push({ name: set });
778
+ let componentsEntry = "";
779
+ if (config.components.size) {
780
+ if (config.labComponents.size) {
781
+ if (config.labComponents.has("*"))
782
+ componentsEntry = `options.components = {${Array.from(config.components).join(",")},...labsComponents}`;
577
783
  else
578
- result.push(set);
784
+ componentsEntry = `options.components = {${Array.from(config.components).join(",")},${Array.from(config.labComponents).join(",")}}`;
785
+ } else {
786
+ componentsEntry = `options.components = {${Array.from(config.components).join(",")}}`;
579
787
  }
788
+ } else if (config.labComponents.size) {
789
+ if (config.labComponents.has("*"))
790
+ componentsEntry = "options.components = {...labsComponents}";
791
+ else
792
+ componentsEntry = `options.components = {${Array.from(config.labComponents).join(",")}}`;
580
793
  }
581
- return result;
794
+ if (!ctx.i18n && localeMessages) {
795
+ const useLocales = Array.isArray(localeMessages) ? [.../* @__PURE__ */ new Set([...localeMessages])] : [localeMessages];
796
+ config.imports.push(`import {${useLocales.join(",")}} from 'vuetify/locale'`);
797
+ config.messages = `
798
+ options.locale = options.locale || {}
799
+ options.locale.messages = options.locale.messages || {}
800
+ ${useLocales.map((locale) => {
801
+ return `
802
+ if ('${locale}' in options.locale.messages)
803
+ deepCopy(options.locale.messages['${locale}'],${locale})
804
+
805
+ options.locale.messages['${locale}'] = ${locale}
806
+ `;
807
+ }).join("")}
808
+ `;
809
+ }
810
+ return {
811
+ imports: config.imports.length ? config.imports.join("\n") : "",
812
+ components: componentsEntry,
813
+ aliases: config.aliasEntries.length ? `options.aliases = {${config.aliasEntries.join(",")}}` : "",
814
+ directives: config.directives,
815
+ messages: config.messages
816
+ };
582
817
  }
583
818
 
584
- function vuetifyIconsPlugin(isDev, resolvedIcons) {
585
- const iconsOptionsPromise = prepareIcons();
819
+ function vuetifyIconsPlugin(ctx) {
586
820
  return {
587
821
  name: "vuetify:icons-configuration:nuxt",
588
822
  enforce: "pre",
@@ -592,23 +826,34 @@ function vuetifyIconsPlugin(isDev, resolvedIcons) {
592
826
  },
593
827
  async load(id) {
594
828
  if (id === RESOLVED_VIRTUAL_VUETIFY_ICONS_CONFIGURATION) {
595
- if (!resolvedIcons.enabled) {
596
- return `export const isDev = ${isDev}
829
+ const {
830
+ enabled,
831
+ unocss,
832
+ aliases,
833
+ fa,
834
+ defaultSet,
835
+ imports,
836
+ sets
837
+ } = await prepareIcons();
838
+ if (!enabled) {
839
+ return `export const enabled = false
840
+ export const isDev = ${ctx.isDev}
597
841
  export function iconsConfiguration() {
598
- return { defaultSet: undefined }
842
+ return {}
599
843
  }
600
844
  `;
601
845
  }
602
- const { unocss, aliases, fa, defaultSet, imports, sets } = await iconsOptionsPromise;
603
846
  if (!defaultSet) {
604
- return `export const isDev = ${isDev}
847
+ return `export const enabled = true
848
+ export const isDev = ${ctx.isDev}
605
849
  export function iconsConfiguration() {
606
- return { defaultSet: undefined }
850
+ return {}
607
851
  }
608
852
  `;
609
853
  }
610
854
  return `${imports}
611
- export const isDev = ${isDev}
855
+ export const enabled = true
856
+ export const isDev = ${ctx.isDev}
612
857
  export function iconsConfiguration() {
613
858
  ${fa.map((f) => ` ${f}`).join("\n")}
614
859
  return {
@@ -623,8 +868,9 @@ ${unocss}
623
868
  }
624
869
  };
625
870
  async function prepareIcons() {
626
- if (!resolvedIcons.enabled) {
871
+ if (!ctx.icons.enabled) {
627
872
  return {
873
+ enabled: false,
628
874
  unocss: "",
629
875
  defaultSet: void 0,
630
876
  imports: "",
@@ -634,7 +880,7 @@ ${unocss}
634
880
  };
635
881
  }
636
882
  let aliases = "aliases,";
637
- const alias = resolvedIcons.aliases;
883
+ const alias = ctx.icons.aliases;
638
884
  if (alias.length) {
639
885
  aliases = `aliases: {
640
886
  ...aliases,
@@ -643,9 +889,9 @@ ${unocss}
643
889
  `;
644
890
  }
645
891
  let unocss = "";
646
- if (resolvedIcons.unocss && resolvedIcons.unocssAliases) {
647
- resolvedIcons.imports.unshift("// @unocss-include");
648
- const prefix = `${resolvedIcons.unocssIconPrefix}mdi:`;
892
+ if (ctx.icons.unocss && ctx.icons.unocssAliases) {
893
+ ctx.icons.imports.unshift("// @unocss-include");
894
+ const prefix = `${ctx.icons.unocssIconPrefix}mdi:`;
649
895
  unocss = `const aliases = ${JSON.stringify({
650
896
  collapse: `${prefix}chevron-up`,
651
897
  complete: `${prefix}check`,
@@ -689,16 +935,81 @@ ${unocss}
689
935
  `;
690
936
  }
691
937
  return {
938
+ enabled: true,
692
939
  unocss,
693
- fa: resolvedIcons.svg?.fa ?? [],
694
- defaultSet: resolvedIcons.defaultSet,
695
- imports: Object.values(resolvedIcons.imports).join("\n"),
696
- sets: resolvedIcons.sets.join(","),
940
+ fa: ctx.icons.svg?.fa ?? [],
941
+ defaultSet: ctx.icons.defaultSet,
942
+ imports: Object.values(ctx.icons.imports).join("\n"),
943
+ sets: ctx.icons.sets.join(","),
697
944
  aliases
698
945
  };
699
946
  }
700
947
  }
701
948
 
949
+ function vuetifyDateConfigurationPlugin(ctx) {
950
+ return {
951
+ name: "vuetify:date-configuration:nuxt",
952
+ enforce: "pre",
953
+ resolveId(id) {
954
+ if (id === VIRTUAL_VUETIFY_DATE_CONFIGURATION)
955
+ return RESOLVED_VIRTUAL_VUETIFY_DATE_CONFIGURATION;
956
+ },
957
+ async load(id) {
958
+ if (id === RESOLVED_VIRTUAL_VUETIFY_DATE_CONFIGURATION) {
959
+ if (!ctx.dateAdapter) {
960
+ return `
961
+ export const enabled = false
962
+ export const isDev = ${ctx.isDev}
963
+ export const i18n = ${ctx.i18n}
964
+ export const adapter = 'custom'
965
+ export function dateConfiguration() {
966
+ return {}
967
+ }
968
+ `;
969
+ }
970
+ const { adapter: _adapter, ...newDateOptions } = ctx.vuetifyOptions.date ?? {};
971
+ const imports = ctx.dateAdapter === "vuetify" ? "import { VuetifyDateAdapter } from 'vuetify/labs/date/adapters/vuetify'" : ctx.dateAdapter === "custom" ? "" : `import Adapter from '@date-io/${ctx.dateAdapter}'`;
972
+ return `${imports}
973
+ export const enabled = true
974
+ export const isDev = ${ctx.isDev}
975
+ export const i18n = ${ctx.i18n}
976
+ export const adapter = '${ctx.dateAdapter}'
977
+ export function dateConfiguration() {
978
+ const options = JSON.parse('${JSON.stringify(newDateOptions)}')
979
+ ${buildAdapter()}
980
+ return options
981
+ }
982
+ `;
983
+ }
984
+ }
985
+ };
986
+ function buildAdapter() {
987
+ if (ctx.dateAdapter === "custom")
988
+ return "";
989
+ if (ctx.dateAdapter === "vuetify")
990
+ return "options.adapter = VuetifyDateAdapter";
991
+ return "options.adapter = Adapter";
992
+ }
993
+ }
994
+
995
+ function configureVite(configKey, nuxt, ctx) {
996
+ nuxt.hook("vite:extend", ({ config }) => checkVuetifyPlugins(config));
997
+ nuxt.hook("vite:extendConfig", (viteInlineConfig) => {
998
+ viteInlineConfig.plugins = viteInlineConfig.plugins || [];
999
+ checkVuetifyPlugins(viteInlineConfig);
1000
+ viteInlineConfig.optimizeDeps = defu(viteInlineConfig.optimizeDeps, { exclude: ["vuetify"] });
1001
+ viteInlineConfig.ssr || (viteInlineConfig.ssr = {});
1002
+ viteInlineConfig.ssr.noExternal = [
1003
+ ...Array.isArray(viteInlineConfig.ssr.noExternal) ? viteInlineConfig.ssr.noExternal : [],
1004
+ configKey
1005
+ ];
1006
+ viteInlineConfig.plugins.push(vuetifyStylesPlugin({ styles: ctx.moduleOptions.styles }, ctx.logger));
1007
+ viteInlineConfig.plugins.push(vuetifyConfigurationPlugin(ctx));
1008
+ viteInlineConfig.plugins.push(vuetifyIconsPlugin(ctx));
1009
+ viteInlineConfig.plugins.push(vuetifyDateConfigurationPlugin(ctx));
1010
+ });
1011
+ }
1012
+
702
1013
  function toKebabCase(str = "") {
703
1014
  if (toKebabCase.cache.has(str))
704
1015
  return toKebabCase.cache.get(str);
@@ -708,75 +1019,74 @@ function toKebabCase(str = "") {
708
1019
  }
709
1020
  toKebabCase.cache = /* @__PURE__ */ new Map();
710
1021
 
711
- function detectDate() {
712
- const result = [];
713
- [
714
- "date-fns",
715
- "moment",
716
- "luxon",
717
- "dayjs",
718
- "js-joda",
719
- "date-fns-jalali",
720
- "jalaali",
721
- "hijri"
722
- ].forEach((adapter) => {
723
- if (isPackageExists(`@date-io/${adapter}`))
724
- result.push(adapter);
1022
+ function configureNuxt(configKey, nuxt, ctx) {
1023
+ var _a;
1024
+ const { importComposables, prefixComposables, styles } = ctx.moduleOptions;
1025
+ const runtimeDir = ctx.resolver.resolve("./runtime");
1026
+ nuxt.options.build.transpile.push(configKey);
1027
+ nuxt.options.build.transpile.push(runtimeDir);
1028
+ (_a = nuxt.options).css ?? (_a.css = []);
1029
+ if (typeof styles === "string" && ["sass", "expose"].includes(styles))
1030
+ nuxt.options.css.unshift("vuetify/styles/main.sass");
1031
+ else if (styles === true)
1032
+ nuxt.options.css.unshift("vuetify/styles");
1033
+ else if (typeof styles === "object" && typeof styles?.configFile === "string")
1034
+ nuxt.options.css.unshift(styles.configFile);
1035
+ extendWebpackConfig(() => {
1036
+ throw new Error("Webpack is not supported: vuetify-nuxt-module module can only be used with Vite!");
725
1037
  });
726
- return result;
727
- }
728
- function cleanupBlueprint(vuetifyOptions) {
729
- const blueprint = vuetifyOptions.blueprint;
730
- if (blueprint) {
731
- delete blueprint.ssr;
732
- delete blueprint.components;
733
- delete blueprint.directives;
734
- delete blueprint.locale;
735
- delete blueprint.date;
736
- delete blueprint.icons;
737
- vuetifyOptions.blueprint = blueprint;
738
- }
739
- }
740
- function checkVuetifyPlugins(config) {
741
- let plugin = config.plugins?.find((p) => p && typeof p === "object" && "name" in p && p.name === "vuetify:import");
742
- if (plugin)
743
- throw new Error("Remove vite-plugin-vuetify plugin from Vite Plugins entry in Nuxt config file!");
744
- plugin = config.plugins?.find((p) => p && typeof p === "object" && "name" in p && p.name === "vuetify:styles");
745
- if (plugin)
746
- throw new Error("Remove vite-plugin-vuetify plugin from Vite Plugins entry in Nuxt config file!");
747
- }
748
- function resolveVuetifyComponents(resolver) {
749
- const vuetifyBase = resolveVuetifyBase();
750
- const componentsPromise = importMapResolver();
751
- const labComponentsPromise = importMapLabResolver();
752
- return {
753
- vuetifyBase,
754
- componentsPromise,
755
- labComponentsPromise
756
- };
757
- async function importMapResolver() {
758
- return JSON.parse(await readFile(resolver.resolve(vuetifyBase, "dist/json/importMap.json"), "utf-8")).components;
759
- }
760
- async function importMapLabResolver() {
761
- return JSON.parse(await readFile(resolver.resolve(vuetifyBase, "dist/json/importMap-labs.json"), "utf-8")).components;
1038
+ nuxt.hook("prepare:types", ({ references }) => {
1039
+ references.push({ types: "vuetify" });
1040
+ references.push({ types: "vuetify-nuxt-module/custom-configuration" });
1041
+ references.push({ types: "vuetify-nuxt-module/configuration" });
1042
+ });
1043
+ nuxt.hook("components:extend", async (c) => {
1044
+ const components = await ctx.componentsPromise;
1045
+ Object.keys(components).forEach((component) => {
1046
+ c.push({
1047
+ pascalName: component,
1048
+ kebabName: toKebabCase(component),
1049
+ export: component,
1050
+ filePath: "vuetify/components",
1051
+ shortPath: "vuetify/components",
1052
+ chunkName: toKebabCase(component),
1053
+ prefetch: false,
1054
+ preload: false,
1055
+ global: false,
1056
+ mode: "all"
1057
+ });
1058
+ });
1059
+ });
1060
+ if (importComposables) {
1061
+ const composables = ["useLocale", "useDefaults", "useDisplay", "useLayout", "useRtl", "useTheme"];
1062
+ addImports(composables.map((name) => ({
1063
+ name,
1064
+ from: "vuetify",
1065
+ as: prefixComposables ? name.replace(/^use/, "useV") : void 0,
1066
+ meta: { docsUrl: `https://vuetifyjs.com/en/api/${toKebabCase(name)}/` }
1067
+ })));
762
1068
  }
763
- }
764
-
765
- async function mergeVuetifyModules(options, nuxt) {
766
- const moduleOptions = [];
767
- await nuxt.callHook("vuetify:registerModule", (layerModuleOptions) => moduleOptions.push(layerModuleOptions));
768
- if (nuxt.options._layers.length > 1) {
769
- nuxt.options._layers.forEach((layer, idx) => {
770
- if (idx > 0 && layer.config.vuetify)
771
- moduleOptions.push(layer.config.vuetify);
1069
+ addPlugin({
1070
+ src: ctx.resolver.resolve(runtimeDir, `plugins/vuetify${ctx.i18n ? "-sync" : ""}`)
1071
+ });
1072
+ addPlugin({
1073
+ src: ctx.resolver.resolve(runtimeDir, "plugins/vuetify-icons")
1074
+ });
1075
+ if (ctx.i18n) {
1076
+ addPlugin({
1077
+ src: ctx.resolver.resolve(runtimeDir, "plugins/vuetify-i18n")
772
1078
  });
773
1079
  }
774
- moduleOptions.push(options);
775
- if (moduleOptions.length > 1) {
776
- const [base, ...rest] = moduleOptions;
777
- return defu(base, ...rest);
1080
+ if (nuxt.options.dev) {
1081
+ addPlugin({
1082
+ src: ctx.resolver.resolve(runtimeDir, "plugins/vuetify-date")
1083
+ });
778
1084
  } else {
779
- return options;
1085
+ if (ctx.dateAdapter) {
1086
+ addPlugin({
1087
+ src: ctx.resolver.resolve(runtimeDir, "plugins/vuetify-date")
1088
+ });
1089
+ }
780
1090
  }
781
1091
  }
782
1092
 
@@ -801,159 +1111,26 @@ const module = defineNuxtModule({
801
1111
  }
802
1112
  }),
803
1113
  async setup(options, nuxt) {
804
- var _a, _b;
805
1114
  if (!isNuxt3(nuxt))
806
1115
  logger.error(`Cannot support nuxt version: ${getNuxtVersion(nuxt)}`);
807
- const resolver = createResolver(import.meta.url);
808
- options = await mergeVuetifyModules(options, nuxt);
809
- const { vuetifyOptions = {} } = options;
810
- const {
811
- directives = false,
812
- labComponents = false,
813
- ...vOptions
814
- } = vuetifyOptions;
815
- const moduleOptions = defu(options.moduleOptions ?? {}, {
816
- styles: true,
817
- importComposables: true,
818
- prefixComposables: false
819
- });
820
- const isSSR = nuxt.options.ssr;
821
- const vuetifyAppOptions = defu(vOptions, {});
822
- cleanupBlueprint(vuetifyAppOptions);
823
- const { styles } = moduleOptions;
824
- const i18n = hasNuxtModule("@nuxtjs/i18n", nuxt);
825
- let dateAdapter;
826
- const dateOptions = vuetifyOptions.date;
827
- if (dateOptions) {
828
- const adapter = dateOptions.adapter;
829
- const date = detectDate();
830
- if (!adapter && date.length > 1)
831
- throw new Error(`Multiple date adapters found: ${date.map((d) => `@date-io/${d[0]}`).join(", ")}, please specify the adapter to use in the "vuetifyOptions.date.adapter" option.`);
832
- if (adapter) {
833
- if (adapter === "vuetify" || adapter === "custom") {
834
- dateAdapter = adapter;
835
- } else {
836
- if (date.find((d) => d === adapter) === void 0)
837
- logger.warn(`Ignoring Vuetify Date configuration, date adapter "@date-io/${adapter}" not installed!`);
838
- else
839
- dateAdapter = adapter;
840
- }
841
- } else if (date.length === 0) {
842
- dateAdapter = "vuetify";
843
- } else {
844
- dateAdapter = date[0];
845
- }
846
- }
847
- nuxt.options.build.transpile.push(CONFIG_KEY);
848
- const icons = prepareIcons(hasNuxtModule("@unocss/nuxt"), logger, vuetifyOptions);
849
- (_a = nuxt.options).css ?? (_a.css = []);
850
- if (typeof styles === "string" && ["sass", "expose"].includes(styles))
851
- nuxt.options.css.unshift("vuetify/styles/main.sass");
852
- else if (styles === true)
853
- nuxt.options.css.unshift("vuetify/styles");
854
- else if (typeof styles === "object" && typeof styles?.configFile === "string")
855
- nuxt.options.css.unshift(styles.configFile);
856
- if (icons.enabled) {
857
- icons.local?.forEach((css) => nuxt.options.css.push(css));
858
- if (icons.cdn?.length) {
859
- (_b = nuxt.options.app.head).link ?? (_b.link = []);
860
- icons.cdn.forEach((href) => nuxt.options.app.head.link.push({
861
- rel: "stylesheet",
862
- href,
863
- type: "text/css",
864
- crossorigin: "anonymous"
865
- }));
866
- }
867
- }
868
- extendWebpackConfig(() => {
869
- throw new Error("Webpack is not supported: vuetify-nuxt-module module can only be used with Vite!");
870
- });
871
- nuxt.hook("vite:extend", ({ config }) => checkVuetifyPlugins(config));
872
- nuxt.hook("prepare:types", ({ references }) => {
873
- references.push({ types: "vuetify" });
874
- references.push({ types: "vuetify-nuxt-module/configuration" });
875
- });
876
- const {
877
- componentsPromise,
878
- labComponentsPromise
879
- } = resolveVuetifyComponents(resolver);
880
- nuxt.hook("components:extend", async (c) => {
881
- const components = await componentsPromise;
882
- Object.keys(components).forEach((component) => {
883
- c.push({
884
- pascalName: component,
885
- kebabName: toKebabCase(component),
886
- export: component,
887
- filePath: "vuetify/components",
888
- shortPath: "vuetify/components",
889
- chunkName: toKebabCase(component),
890
- prefetch: false,
891
- preload: false,
892
- global: false,
893
- mode: "all"
894
- });
895
- });
896
- });
897
- if (moduleOptions.importComposables) {
898
- const composables = ["useLocale", "useDefaults", "useDisplay", "useLayout", "useRtl", "useTheme"];
899
- addImports(composables.map((name) => ({
900
- name,
901
- from: "vuetify",
902
- as: moduleOptions.prefixComposables ? name.replace(/^use/, "useV") : void 0,
903
- meta: { docsUrl: `https://vuetifyjs.com/en/api/${toKebabCase(name)}/` }
904
- })));
905
- }
906
- nuxt.hook("vite:extendConfig", (viteInlineConfig) => {
907
- viteInlineConfig.plugins = viteInlineConfig.plugins || [];
908
- checkVuetifyPlugins(viteInlineConfig);
909
- viteInlineConfig.optimizeDeps = defu(viteInlineConfig.optimizeDeps, { exclude: ["vuetify"] });
910
- viteInlineConfig.ssr || (viteInlineConfig.ssr = {});
911
- viteInlineConfig.ssr.noExternal = [
912
- ...Array.isArray(viteInlineConfig.ssr.noExternal) ? viteInlineConfig.ssr.noExternal : [],
913
- CONFIG_KEY
914
- ];
915
- viteInlineConfig.plugins.push(vuetifyStylesPlugin({ styles }, logger));
916
- viteInlineConfig.plugins.push(vuetifyConfigurationPlugin(
917
- nuxt.options.dev,
918
- isSSR,
919
- i18n,
920
- directives,
921
- labComponents,
922
- vuetifyAppOptions,
923
- componentsPromise,
924
- labComponentsPromise,
925
- logger
926
- ));
927
- viteInlineConfig.plugins.push(vuetifyIconsPlugin(
928
- nuxt.options.dev,
929
- icons
930
- ));
931
- if (dateAdapter) {
932
- viteInlineConfig.plugins.push(vuetifyDateConfigurationPlugin(
933
- nuxt.options.dev,
934
- i18n,
935
- dateAdapter,
936
- dateOptions
937
- ));
938
- }
939
- });
940
- const runtimeDir = resolver.resolve("./runtime");
941
- addPlugin({
942
- src: resolver.resolve(runtimeDir, `plugins/vuetify${i18n ? "-sync" : ""}`)
943
- });
944
- addPlugin({
945
- src: resolver.resolve(runtimeDir, "plugins/vuetify-icons")
946
- });
947
- if (i18n) {
948
- addPlugin({
949
- src: resolver.resolve(runtimeDir, "plugins/vuetify-i18n")
950
- });
951
- }
952
- if (dateAdapter) {
953
- addPlugin({
954
- src: resolver.resolve(runtimeDir, "plugins/vuetify-date")
955
- });
956
- }
1116
+ const ctx = {
1117
+ logger,
1118
+ resolver: createResolver(import.meta.url),
1119
+ moduleOptions: void 0,
1120
+ vuetifyOptions: void 0,
1121
+ vuetifyFilesToWatch: [],
1122
+ isSSR: nuxt.options.ssr,
1123
+ isDev: nuxt.options.dev,
1124
+ unocss: hasNuxtModule("@unocss/nuxt", nuxt),
1125
+ i18n: hasNuxtModule("@nuxtjs/i18n", nuxt),
1126
+ icons: void 0,
1127
+ componentsPromise: void 0,
1128
+ labComponentsPromise: void 0
1129
+ };
1130
+ await load(options, nuxt, ctx);
1131
+ configureNuxt(CONFIG_KEY, nuxt, ctx);
1132
+ registerWatcher(options, nuxt, ctx);
1133
+ configureVite(CONFIG_KEY, nuxt, ctx);
957
1134
  }
958
1135
  });
959
1136