vuetify-nuxt-module 0.4.11 → 0.5.0

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