@tixxin/nuxt-theme-engine 0.0.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/LICENSE +21 -0
- package/README.md +171 -0
- package/dist/module.d.mts +15 -0
- package/dist/module.json +12 -0
- package/dist/module.mjs +897 -0
- package/dist/runtime/build-shims.d.ts +52 -0
- package/dist/runtime/components/ThemeComponent.d.vue.ts +10 -0
- package/dist/runtime/components/ThemeComponent.vue +46 -0
- package/dist/runtime/components/ThemeComponent.vue.d.ts +10 -0
- package/dist/runtime/composables/useThemeConfig.d.ts +10 -0
- package/dist/runtime/composables/useThemeConfig.js +88 -0
- package/dist/runtime/composables/useThemeEngine.d.ts +6 -0
- package/dist/runtime/composables/useThemeEngine.js +68 -0
- package/dist/runtime/devtools/page.d.vue.ts +3 -0
- package/dist/runtime/devtools/page.vue +64 -0
- package/dist/runtime/devtools/page.vue.d.ts +3 -0
- package/dist/runtime/plugins/theme-sync.client.d.ts +2 -0
- package/dist/runtime/plugins/theme-sync.client.js +9 -0
- package/dist/runtime/tsconfig.json +13 -0
- package/dist/types.d.mts +7 -0
- package/package.json +52 -0
package/dist/module.mjs
ADDED
|
@@ -0,0 +1,897 @@
|
|
|
1
|
+
import { promises } from 'node:fs';
|
|
2
|
+
import { createRequire } from 'node:module';
|
|
3
|
+
import { useNuxt, defineNuxtModule, createResolver, addImportsDir, addPlugin, addComponent, addTemplate, addTypeTemplate, extendPages, logger } from '@nuxt/kit';
|
|
4
|
+
import 'node:child_process';
|
|
5
|
+
import 'node:path';
|
|
6
|
+
import 'node:process';
|
|
7
|
+
import 'node:stream';
|
|
8
|
+
import 'node:readline';
|
|
9
|
+
import { resolve, relative, extname, dirname, join } from 'pathe';
|
|
10
|
+
import fg from 'fast-glob';
|
|
11
|
+
import { z } from 'zod';
|
|
12
|
+
|
|
13
|
+
//#region \0rolldown/runtime.js
|
|
14
|
+
var l = (e, t) => () => (t || e((t = { exports: {} }).exports, t), t.exports);
|
|
15
|
+
var u = /* @__PURE__ */ createRequire(import.meta.url);
|
|
16
|
+
//#endregion
|
|
17
|
+
//#region node_modules/isexe/windows.js
|
|
18
|
+
var _ = /* @__PURE__ */ l(((e, t) => {
|
|
19
|
+
t.exports = a;
|
|
20
|
+
a.sync = o;
|
|
21
|
+
var n = u("fs");
|
|
22
|
+
function r(e, t) {
|
|
23
|
+
var n = t.pathExt !== void 0 ? t.pathExt : process.env.PATHEXT;
|
|
24
|
+
if (!n) return true;
|
|
25
|
+
n = n.split(";");
|
|
26
|
+
if (n.indexOf("") !== -1) return true;
|
|
27
|
+
for (var r = 0; r < n.length; r++) {
|
|
28
|
+
var i = n[r].toLowerCase();
|
|
29
|
+
if (i && e.substr(-i.length).toLowerCase() === i) return true;
|
|
30
|
+
}
|
|
31
|
+
return false;
|
|
32
|
+
}
|
|
33
|
+
function i(e, t, n) {
|
|
34
|
+
if (!e.isSymbolicLink() && !e.isFile()) return false;
|
|
35
|
+
return r(t, n);
|
|
36
|
+
}
|
|
37
|
+
function a(e, t, r) {
|
|
38
|
+
n.stat(e, function(n, a) {
|
|
39
|
+
r(n, n ? false : i(a, e, t));
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
function o(e, t) {
|
|
43
|
+
return i(n.statSync(e), e, t);
|
|
44
|
+
}
|
|
45
|
+
}));
|
|
46
|
+
//#endregion
|
|
47
|
+
//#region node_modules/isexe/mode.js
|
|
48
|
+
var v = /* @__PURE__ */ l(((e, t) => {
|
|
49
|
+
t.exports = r;
|
|
50
|
+
r.sync = i;
|
|
51
|
+
var n = u("fs");
|
|
52
|
+
function r(e, t, r) {
|
|
53
|
+
n.stat(e, function(e, n) {
|
|
54
|
+
r(e, e ? false : a(n, t));
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
function i(e, t) {
|
|
58
|
+
return a(n.statSync(e), t);
|
|
59
|
+
}
|
|
60
|
+
function a(e, t) {
|
|
61
|
+
return e.isFile() && o(e, t);
|
|
62
|
+
}
|
|
63
|
+
function o(e, t) {
|
|
64
|
+
var n = e.mode;
|
|
65
|
+
var r = e.uid;
|
|
66
|
+
var i = e.gid;
|
|
67
|
+
var a = t.uid !== void 0 ? t.uid : process.getuid && process.getuid();
|
|
68
|
+
var o = t.gid !== void 0 ? t.gid : process.getgid && process.getgid();
|
|
69
|
+
var s = parseInt("100", 8);
|
|
70
|
+
var c = parseInt("010", 8);
|
|
71
|
+
var l = parseInt("001", 8);
|
|
72
|
+
var u = s | c;
|
|
73
|
+
return n & l || n & c && i === o || n & s && r === a || n & u && a === 0;
|
|
74
|
+
}
|
|
75
|
+
}));
|
|
76
|
+
//#endregion
|
|
77
|
+
//#region node_modules/isexe/index.js
|
|
78
|
+
var y = /* @__PURE__ */ l(((e, t) => {
|
|
79
|
+
u("fs");
|
|
80
|
+
var n;
|
|
81
|
+
if (process.platform === "win32" || global.TESTING_WINDOWS) n = _();
|
|
82
|
+
else n = v();
|
|
83
|
+
t.exports = r;
|
|
84
|
+
r.sync = i;
|
|
85
|
+
function r(e, t, i) {
|
|
86
|
+
if (typeof t === "function") {
|
|
87
|
+
i = t;
|
|
88
|
+
t = {};
|
|
89
|
+
}
|
|
90
|
+
if (!i) {
|
|
91
|
+
if (typeof Promise !== "function") throw new TypeError("callback not provided");
|
|
92
|
+
return new Promise(function(n, i) {
|
|
93
|
+
r(e, t || {}, function(e, t) {
|
|
94
|
+
if (e) i(e);
|
|
95
|
+
else n(t);
|
|
96
|
+
});
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
n(e, t || {}, function(e, n) {
|
|
100
|
+
if (e) {
|
|
101
|
+
if (e.code === "EACCES" || t && t.ignoreErrors) {
|
|
102
|
+
e = null;
|
|
103
|
+
n = false;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
i(e, n);
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
function i(e, t) {
|
|
110
|
+
try {
|
|
111
|
+
return n.sync(e, t || {});
|
|
112
|
+
} catch (e) {
|
|
113
|
+
if (t && t.ignoreErrors || e.code === "EACCES") return false;
|
|
114
|
+
else throw e;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
}));
|
|
118
|
+
//#endregion
|
|
119
|
+
//#region node_modules/which/which.js
|
|
120
|
+
var b = /* @__PURE__ */ l(((e, t) => {
|
|
121
|
+
const n = process.platform === "win32" || process.env.OSTYPE === "cygwin" || process.env.OSTYPE === "msys";
|
|
122
|
+
const r = u("path");
|
|
123
|
+
const i = n ? ";" : ":";
|
|
124
|
+
const a = y();
|
|
125
|
+
const o = (e) => Object.assign(/* @__PURE__ */ new Error(`not found: ${e}`), { code: "ENOENT" });
|
|
126
|
+
const s = (e, t) => {
|
|
127
|
+
const r = t.colon || i;
|
|
128
|
+
const a = e.match(/\//) || n && e.match(/\\/) ? [""] : [...n ? [process.cwd()] : [], ...(t.path || process.env.PATH || "").split(r)];
|
|
129
|
+
const o = n ? t.pathExt || process.env.PATHEXT || ".EXE;.CMD;.BAT;.COM" : "";
|
|
130
|
+
const s = n ? o.split(r) : [""];
|
|
131
|
+
if (n) {
|
|
132
|
+
if (e.indexOf(".") !== -1 && s[0] !== "") s.unshift("");
|
|
133
|
+
}
|
|
134
|
+
return {
|
|
135
|
+
pathEnv: a,
|
|
136
|
+
pathExt: s,
|
|
137
|
+
pathExtExe: o
|
|
138
|
+
};
|
|
139
|
+
};
|
|
140
|
+
const c = (e, t, n) => {
|
|
141
|
+
if (typeof t === "function") {
|
|
142
|
+
n = t;
|
|
143
|
+
t = {};
|
|
144
|
+
}
|
|
145
|
+
if (!t) t = {};
|
|
146
|
+
const { pathEnv: i, pathExt: c, pathExtExe: l } = s(e, t);
|
|
147
|
+
const u = [];
|
|
148
|
+
const d = (n) => new Promise((a, s) => {
|
|
149
|
+
if (n === i.length) return t.all && u.length ? a(u) : s(o(e));
|
|
150
|
+
const c = i[n];
|
|
151
|
+
const l = /^".*"$/.test(c) ? c.slice(1, -1) : c;
|
|
152
|
+
const d = r.join(l, e);
|
|
153
|
+
a(f(!l && /^\.[\\\/]/.test(e) ? e.slice(0, 2) + d : d, n, 0));
|
|
154
|
+
});
|
|
155
|
+
const f = (e, n, r) => new Promise((i, o) => {
|
|
156
|
+
if (r === c.length) return i(d(n + 1));
|
|
157
|
+
const s = c[r];
|
|
158
|
+
a(e + s, { pathExt: l }, (a, o) => {
|
|
159
|
+
if (!a && o) if (t.all) u.push(e + s);
|
|
160
|
+
else return i(e + s);
|
|
161
|
+
return i(f(e, n, r + 1));
|
|
162
|
+
});
|
|
163
|
+
});
|
|
164
|
+
return n ? d(0).then((e) => n(null, e), n) : d(0);
|
|
165
|
+
};
|
|
166
|
+
const l = (e, t) => {
|
|
167
|
+
t = t || {};
|
|
168
|
+
const { pathEnv: n, pathExt: i, pathExtExe: c } = s(e, t);
|
|
169
|
+
const l = [];
|
|
170
|
+
for (let o = 0; o < n.length; o++) {
|
|
171
|
+
const s = n[o];
|
|
172
|
+
const u = /^".*"$/.test(s) ? s.slice(1, -1) : s;
|
|
173
|
+
const d = r.join(u, e);
|
|
174
|
+
const f = !u && /^\.[\\\/]/.test(e) ? e.slice(0, 2) + d : d;
|
|
175
|
+
for (let e = 0; e < i.length; e++) {
|
|
176
|
+
const n = f + i[e];
|
|
177
|
+
try {
|
|
178
|
+
if (a.sync(n, { pathExt: c })) if (t.all) l.push(n);
|
|
179
|
+
else return n;
|
|
180
|
+
} catch (e) {}
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
if (t.all && l.length) return l;
|
|
184
|
+
if (t.nothrow) return null;
|
|
185
|
+
throw o(e);
|
|
186
|
+
};
|
|
187
|
+
t.exports = c;
|
|
188
|
+
c.sync = l;
|
|
189
|
+
}));
|
|
190
|
+
//#endregion
|
|
191
|
+
//#region node_modules/path-key/index.js
|
|
192
|
+
var x = /* @__PURE__ */ l(((e, t) => {
|
|
193
|
+
const n = (e = {}) => {
|
|
194
|
+
const t = e.env || process.env;
|
|
195
|
+
if ((e.platform || process.platform) !== "win32") return "PATH";
|
|
196
|
+
return Object.keys(t).reverse().find((e) => e.toUpperCase() === "PATH") || "Path";
|
|
197
|
+
};
|
|
198
|
+
t.exports = n;
|
|
199
|
+
t.exports.default = n;
|
|
200
|
+
}));
|
|
201
|
+
//#endregion
|
|
202
|
+
//#region node_modules/cross-spawn/lib/util/resolveCommand.js
|
|
203
|
+
var S = /* @__PURE__ */ l(((e, t) => {
|
|
204
|
+
const n = u("path");
|
|
205
|
+
const r = b();
|
|
206
|
+
const i = x();
|
|
207
|
+
function a(e, t) {
|
|
208
|
+
const a = e.options.env || process.env;
|
|
209
|
+
const o = process.cwd();
|
|
210
|
+
const s = e.options.cwd != null;
|
|
211
|
+
const c = s && process.chdir !== void 0 && !process.chdir.disabled;
|
|
212
|
+
if (c) try {
|
|
213
|
+
process.chdir(e.options.cwd);
|
|
214
|
+
} catch (e) {}
|
|
215
|
+
let l;
|
|
216
|
+
try {
|
|
217
|
+
l = r.sync(e.command, {
|
|
218
|
+
path: a[i({ env: a })],
|
|
219
|
+
pathExt: t ? n.delimiter : void 0
|
|
220
|
+
});
|
|
221
|
+
} catch (e) {} finally {
|
|
222
|
+
if (c) process.chdir(o);
|
|
223
|
+
}
|
|
224
|
+
if (l) l = n.resolve(s ? e.options.cwd : "", l);
|
|
225
|
+
return l;
|
|
226
|
+
}
|
|
227
|
+
function o(e) {
|
|
228
|
+
return a(e) || a(e, true);
|
|
229
|
+
}
|
|
230
|
+
t.exports = o;
|
|
231
|
+
}));
|
|
232
|
+
//#endregion
|
|
233
|
+
//#region node_modules/cross-spawn/lib/util/escape.js
|
|
234
|
+
var C = /* @__PURE__ */ l(((e, t) => {
|
|
235
|
+
const n = /([()\][%!^"`<>&|;, *?])/g;
|
|
236
|
+
function r(e) {
|
|
237
|
+
e = e.replace(n, "^$1");
|
|
238
|
+
return e;
|
|
239
|
+
}
|
|
240
|
+
function i(e, t) {
|
|
241
|
+
e = `${e}`;
|
|
242
|
+
e = e.replace(/(?=(\\+?)?)\1"/g, "$1$1\\\"");
|
|
243
|
+
e = e.replace(/(?=(\\+?)?)\1$/, "$1$1");
|
|
244
|
+
e = `"${e}"`;
|
|
245
|
+
e = e.replace(n, "^$1");
|
|
246
|
+
if (t) e = e.replace(n, "^$1");
|
|
247
|
+
return e;
|
|
248
|
+
}
|
|
249
|
+
t.exports.command = r;
|
|
250
|
+
t.exports.argument = i;
|
|
251
|
+
}));
|
|
252
|
+
//#endregion
|
|
253
|
+
//#region node_modules/shebang-regex/index.js
|
|
254
|
+
var w = /* @__PURE__ */ l(((e, t) => {
|
|
255
|
+
t.exports = /^#!(.*)/;
|
|
256
|
+
}));
|
|
257
|
+
//#endregion
|
|
258
|
+
//#region node_modules/shebang-command/index.js
|
|
259
|
+
var T = /* @__PURE__ */ l(((e, t) => {
|
|
260
|
+
const n = w();
|
|
261
|
+
t.exports = (e = "") => {
|
|
262
|
+
const t = e.match(n);
|
|
263
|
+
if (!t) return null;
|
|
264
|
+
const [r, i] = t[0].replace(/#! ?/, "").split(" ");
|
|
265
|
+
const a = r.split("/").pop();
|
|
266
|
+
if (a === "env") return i;
|
|
267
|
+
return i ? `${a} ${i}` : a;
|
|
268
|
+
};
|
|
269
|
+
}));
|
|
270
|
+
//#endregion
|
|
271
|
+
//#region node_modules/cross-spawn/lib/util/readShebang.js
|
|
272
|
+
var E = /* @__PURE__ */ l(((e, t) => {
|
|
273
|
+
const n = u("fs");
|
|
274
|
+
const r = T();
|
|
275
|
+
function i(e) {
|
|
276
|
+
const t = 150;
|
|
277
|
+
const i = Buffer.alloc(t);
|
|
278
|
+
let a;
|
|
279
|
+
try {
|
|
280
|
+
a = n.openSync(e, "r");
|
|
281
|
+
n.readSync(a, i, 0, t, 0);
|
|
282
|
+
n.closeSync(a);
|
|
283
|
+
} catch (e) {}
|
|
284
|
+
return r(i.toString());
|
|
285
|
+
}
|
|
286
|
+
t.exports = i;
|
|
287
|
+
}));
|
|
288
|
+
//#endregion
|
|
289
|
+
//#region node_modules/cross-spawn/lib/parse.js
|
|
290
|
+
var D = /* @__PURE__ */ l(((e, t) => {
|
|
291
|
+
const n = u("path");
|
|
292
|
+
const r = S();
|
|
293
|
+
const i = C();
|
|
294
|
+
const a = E();
|
|
295
|
+
const o = process.platform === "win32";
|
|
296
|
+
const s = /\.(?:com|exe)$/i;
|
|
297
|
+
const c = /node_modules[\\/].bin[\\/][^\\/]+\.cmd$/i;
|
|
298
|
+
function l(e) {
|
|
299
|
+
e.file = r(e);
|
|
300
|
+
const t = e.file && a(e.file);
|
|
301
|
+
if (t) {
|
|
302
|
+
e.args.unshift(e.file);
|
|
303
|
+
e.command = t;
|
|
304
|
+
return r(e);
|
|
305
|
+
}
|
|
306
|
+
return e.file;
|
|
307
|
+
}
|
|
308
|
+
function d(e) {
|
|
309
|
+
if (!o) return e;
|
|
310
|
+
const t = l(e);
|
|
311
|
+
const r = !s.test(t);
|
|
312
|
+
if (e.options.forceShell || r) {
|
|
313
|
+
const r = c.test(t);
|
|
314
|
+
e.command = n.normalize(e.command);
|
|
315
|
+
e.command = i.command(e.command);
|
|
316
|
+
e.args = e.args.map((e) => i.argument(e, r));
|
|
317
|
+
e.args = [
|
|
318
|
+
"/d",
|
|
319
|
+
"/s",
|
|
320
|
+
"/c",
|
|
321
|
+
`"${[e.command].concat(e.args).join(" ")}"`
|
|
322
|
+
];
|
|
323
|
+
e.command = process.env.comspec || "cmd.exe";
|
|
324
|
+
e.options.windowsVerbatimArguments = true;
|
|
325
|
+
}
|
|
326
|
+
return e;
|
|
327
|
+
}
|
|
328
|
+
function f(e, t, n) {
|
|
329
|
+
if (t && !Array.isArray(t)) {
|
|
330
|
+
n = t;
|
|
331
|
+
t = null;
|
|
332
|
+
}
|
|
333
|
+
t = t ? t.slice(0) : [];
|
|
334
|
+
n = Object.assign({}, n);
|
|
335
|
+
const r = {
|
|
336
|
+
command: e,
|
|
337
|
+
args: t,
|
|
338
|
+
options: n,
|
|
339
|
+
file: void 0,
|
|
340
|
+
original: {
|
|
341
|
+
command: e,
|
|
342
|
+
args: t
|
|
343
|
+
}
|
|
344
|
+
};
|
|
345
|
+
return n.shell ? r : d(r);
|
|
346
|
+
}
|
|
347
|
+
t.exports = f;
|
|
348
|
+
}));
|
|
349
|
+
//#endregion
|
|
350
|
+
//#region node_modules/cross-spawn/lib/enoent.js
|
|
351
|
+
var O = /* @__PURE__ */ l(((e, t) => {
|
|
352
|
+
const n = process.platform === "win32";
|
|
353
|
+
function r(e, t) {
|
|
354
|
+
return Object.assign(/* @__PURE__ */ new Error(`${t} ${e.command} ENOENT`), {
|
|
355
|
+
code: "ENOENT",
|
|
356
|
+
errno: "ENOENT",
|
|
357
|
+
syscall: `${t} ${e.command}`,
|
|
358
|
+
path: e.command,
|
|
359
|
+
spawnargs: e.args
|
|
360
|
+
});
|
|
361
|
+
}
|
|
362
|
+
function i(e, t) {
|
|
363
|
+
if (!n) return;
|
|
364
|
+
const r = e.emit;
|
|
365
|
+
e.emit = function(n, i) {
|
|
366
|
+
if (n === "exit") {
|
|
367
|
+
const n = a(i, t);
|
|
368
|
+
if (n) return r.call(e, "error", n);
|
|
369
|
+
}
|
|
370
|
+
return r.apply(e, arguments);
|
|
371
|
+
};
|
|
372
|
+
}
|
|
373
|
+
function a(e, t) {
|
|
374
|
+
if (n && e === 1 && !t.file) return r(t.original, "spawn");
|
|
375
|
+
return null;
|
|
376
|
+
}
|
|
377
|
+
function o(e, t) {
|
|
378
|
+
if (n && e === 1 && !t.file) return r(t.original, "spawnSync");
|
|
379
|
+
return null;
|
|
380
|
+
}
|
|
381
|
+
t.exports = {
|
|
382
|
+
hookChildProcess: i,
|
|
383
|
+
verifyENOENT: a,
|
|
384
|
+
verifyENOENTSync: o,
|
|
385
|
+
notFoundError: r
|
|
386
|
+
};
|
|
387
|
+
}));
|
|
388
|
+
//#endregion
|
|
389
|
+
//#region node_modules/cross-spawn/index.js
|
|
390
|
+
var k = /* @__PURE__ */ l(((e, t) => {
|
|
391
|
+
const n = u("child_process");
|
|
392
|
+
const r = D();
|
|
393
|
+
const i = O();
|
|
394
|
+
function a(e, t, a) {
|
|
395
|
+
const o = r(e, t, a);
|
|
396
|
+
const s = n.spawn(o.command, o.args, o.options);
|
|
397
|
+
i.hookChildProcess(s, o);
|
|
398
|
+
return s;
|
|
399
|
+
}
|
|
400
|
+
function o(e, t, a) {
|
|
401
|
+
const o = r(e, t, a);
|
|
402
|
+
const s = n.spawnSync(o.command, o.args, o.options);
|
|
403
|
+
s.error = s.error || i.verifyENOENTSync(s.status, o);
|
|
404
|
+
return s;
|
|
405
|
+
}
|
|
406
|
+
t.exports = a;
|
|
407
|
+
t.exports.spawn = a;
|
|
408
|
+
t.exports.sync = o;
|
|
409
|
+
t.exports._parse = r;
|
|
410
|
+
t.exports._enoent = i;
|
|
411
|
+
}));
|
|
412
|
+
//#endregion
|
|
413
|
+
//#region src/non-zero-exit-error.ts
|
|
414
|
+
k();
|
|
415
|
+
|
|
416
|
+
function addCustomTab(tab, nuxt = useNuxt()) {
|
|
417
|
+
nuxt.hook("devtools:customTabs", async (tabs) => {
|
|
418
|
+
if (typeof tab === "function")
|
|
419
|
+
tab = await tab();
|
|
420
|
+
tabs.push(tab);
|
|
421
|
+
});
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
function extractThemeScopedCss(css, themeName) {
|
|
425
|
+
const selectors = [
|
|
426
|
+
new RegExp(`\\[data-theme=["']${themeName}["']\\][^{]*\\{([\\s\\S]*?)\\}`, "g"),
|
|
427
|
+
new RegExp(`\\.dark\\s+\\[data-theme=["']${themeName}["']\\][^{]*\\{([\\s\\S]*?)\\}`, "g")
|
|
428
|
+
];
|
|
429
|
+
return selectors.flatMap((pattern) => {
|
|
430
|
+
return Array.from(css.matchAll(pattern)).map((match) => match[1] ?? "");
|
|
431
|
+
});
|
|
432
|
+
}
|
|
433
|
+
function extractCssVars(css) {
|
|
434
|
+
return Array.from(css.matchAll(/(--theme-[a-zA-Z0-9-_]+)\s*:/g)).map((match) => match[1]).filter((value) => Boolean(value));
|
|
435
|
+
}
|
|
436
|
+
async function checkCssVars(rootDir, themes, requiredCssVars) {
|
|
437
|
+
if (requiredCssVars.length === 0) {
|
|
438
|
+
return [];
|
|
439
|
+
}
|
|
440
|
+
const cssFiles = await fg([
|
|
441
|
+
".nuxt/dist/client/**/*.css",
|
|
442
|
+
".output/public/_nuxt/**/*.css"
|
|
443
|
+
], {
|
|
444
|
+
cwd: rootDir,
|
|
445
|
+
absolute: true,
|
|
446
|
+
onlyFiles: true
|
|
447
|
+
});
|
|
448
|
+
if (cssFiles.length === 0) {
|
|
449
|
+
return Promise.all(themes.map(async (theme) => {
|
|
450
|
+
const sourceCss = await Promise.all(theme.cssFiles.map((file) => promises.readFile(resolve(file), "utf8")));
|
|
451
|
+
const provided = Array.from(new Set(extractCssVars(sourceCss.join("\n")))).sort();
|
|
452
|
+
return {
|
|
453
|
+
theme: theme.name,
|
|
454
|
+
provided,
|
|
455
|
+
missing: requiredCssVars.filter((variable) => !provided.includes(variable))
|
|
456
|
+
};
|
|
457
|
+
}));
|
|
458
|
+
}
|
|
459
|
+
const cssChunks = await Promise.all(cssFiles.map((file) => promises.readFile(resolve(file), "utf8")));
|
|
460
|
+
const joinedCss = cssChunks.join("\n");
|
|
461
|
+
return themes.map((theme) => {
|
|
462
|
+
const scopedBlocks = extractThemeScopedCss(joinedCss, theme.name).join("\n");
|
|
463
|
+
const provided = Array.from(new Set(extractCssVars(scopedBlocks))).sort();
|
|
464
|
+
const missing = requiredCssVars.filter((variable) => !provided.includes(variable));
|
|
465
|
+
return {
|
|
466
|
+
theme: theme.name,
|
|
467
|
+
provided,
|
|
468
|
+
missing
|
|
469
|
+
};
|
|
470
|
+
});
|
|
471
|
+
}
|
|
472
|
+
|
|
473
|
+
function parseContractNames(source) {
|
|
474
|
+
const match = source.match(/themeContractNames\s*=\s*\[([\s\S]*?)\]\s*as const/);
|
|
475
|
+
if (!match) {
|
|
476
|
+
return [];
|
|
477
|
+
}
|
|
478
|
+
const contractListSource = match[1] ?? "";
|
|
479
|
+
return Array.from(contractListSource.matchAll(/['"`]([^'"`]+)['"`]/g)).map((result) => result[1]).filter((name) => Boolean(name));
|
|
480
|
+
}
|
|
481
|
+
async function generateThemeComponentDts(contractsSourcePath, contractsImportId) {
|
|
482
|
+
const source = await promises.readFile(contractsSourcePath, "utf8");
|
|
483
|
+
const names = parseContractNames(source);
|
|
484
|
+
const union = names.length > 0 ? names.map((name) => `'${name}'`).join(" | ") : "never";
|
|
485
|
+
return `import type { DefineComponent } from 'vue'
|
|
486
|
+
import type { ThemeComponentContracts } from ${JSON.stringify(contractsImportId)}
|
|
487
|
+
|
|
488
|
+
declare module '#build/theme-engine.contracts.mjs' {
|
|
489
|
+
export const themeEngineContracts: {
|
|
490
|
+
entry: string
|
|
491
|
+
importId: string
|
|
492
|
+
}
|
|
493
|
+
|
|
494
|
+
export type GeneratedThemeComponentName = ${union}
|
|
495
|
+
export type GeneratedThemeComponentContracts = ThemeComponentContracts
|
|
496
|
+
export type ThemeComponentDiscriminatedProps = {
|
|
497
|
+
[K in keyof ThemeComponentContracts]: { name: K } & ThemeComponentContracts[K]
|
|
498
|
+
}[keyof ThemeComponentContracts]
|
|
499
|
+
}
|
|
500
|
+
|
|
501
|
+
type ThemeComponentDiscriminatedProps = import('#build/theme-engine.contracts.mjs').ThemeComponentDiscriminatedProps
|
|
502
|
+
declare const ThemeComponent: DefineComponent<ThemeComponentDiscriminatedProps>
|
|
503
|
+
|
|
504
|
+
declare module 'vue' {
|
|
505
|
+
export interface GlobalComponents {
|
|
506
|
+
ThemeComponent: typeof ThemeComponent
|
|
507
|
+
}
|
|
508
|
+
}
|
|
509
|
+
|
|
510
|
+
export {}
|
|
511
|
+
`;
|
|
512
|
+
}
|
|
513
|
+
|
|
514
|
+
const COMPONENT_GLOB = "**/*.{vue,js,ts,tsx}";
|
|
515
|
+
function toPascalCase(segment) {
|
|
516
|
+
return segment.replace(/\.[^.]+$/, "").split(/[^a-zA-Z0-9]+/).filter(Boolean).map((part) => part.charAt(0).toUpperCase() + part.slice(1)).join("");
|
|
517
|
+
}
|
|
518
|
+
function toComponentName(relativePath) {
|
|
519
|
+
return relativePath.split(/[\\/]/).map((segment) => toPascalCase(segment.replace(extname(segment), ""))).join("");
|
|
520
|
+
}
|
|
521
|
+
function toThemePrefix(themeName) {
|
|
522
|
+
return themeName.split(/[^a-zA-Z0-9]+/).filter(Boolean).map((segment) => segment.charAt(0).toUpperCase() + segment.slice(1)).join("");
|
|
523
|
+
}
|
|
524
|
+
function toImportPath(buildDir, filePath) {
|
|
525
|
+
const relativePath = relative(buildDir, filePath).replace(/\\/g, "/");
|
|
526
|
+
return relativePath.startsWith(".") ? relativePath : `./${relativePath}`;
|
|
527
|
+
}
|
|
528
|
+
async function scanThemeComponentSources(theme) {
|
|
529
|
+
try {
|
|
530
|
+
await promises.access(theme.componentsDir);
|
|
531
|
+
} catch {
|
|
532
|
+
return [];
|
|
533
|
+
}
|
|
534
|
+
const files = await fg(COMPONENT_GLOB, {
|
|
535
|
+
cwd: theme.componentsDir,
|
|
536
|
+
absolute: true,
|
|
537
|
+
onlyFiles: true
|
|
538
|
+
});
|
|
539
|
+
return files.map((filePath) => {
|
|
540
|
+
const relativePath = relative(theme.componentsDir, filePath);
|
|
541
|
+
return {
|
|
542
|
+
logicalName: toComponentName(relativePath),
|
|
543
|
+
filePath,
|
|
544
|
+
relativePath,
|
|
545
|
+
ownerTheme: theme.name
|
|
546
|
+
};
|
|
547
|
+
});
|
|
548
|
+
}
|
|
549
|
+
async function generateThemeRegistry(themes, buildDir) {
|
|
550
|
+
new Map(themes.map((theme) => [theme.name, theme]));
|
|
551
|
+
const componentSourcesByTheme = /* @__PURE__ */ new Map();
|
|
552
|
+
for (const theme of themes) {
|
|
553
|
+
const sources = await scanThemeComponentSources(theme);
|
|
554
|
+
componentSourcesByTheme.set(
|
|
555
|
+
theme.name,
|
|
556
|
+
new Map(sources.map((source) => [source.logicalName, source]))
|
|
557
|
+
);
|
|
558
|
+
}
|
|
559
|
+
const registry = {
|
|
560
|
+
themes: {},
|
|
561
|
+
uniqueAliases: []
|
|
562
|
+
};
|
|
563
|
+
const seenAliases = /* @__PURE__ */ new Set();
|
|
564
|
+
for (const theme of themes) {
|
|
565
|
+
const entries = {};
|
|
566
|
+
for (const themeName of theme.inheritanceChain) {
|
|
567
|
+
const sourceMap = componentSourcesByTheme.get(themeName);
|
|
568
|
+
if (!sourceMap) {
|
|
569
|
+
continue;
|
|
570
|
+
}
|
|
571
|
+
for (const [logicalName, source] of sourceMap.entries()) {
|
|
572
|
+
if (entries[logicalName]) {
|
|
573
|
+
continue;
|
|
574
|
+
}
|
|
575
|
+
const entry = {
|
|
576
|
+
logicalName,
|
|
577
|
+
alias: `${toThemePrefix(theme.name)}${logicalName}`,
|
|
578
|
+
theme: theme.name,
|
|
579
|
+
sourceTheme: source.ownerTheme,
|
|
580
|
+
filePath: source.filePath,
|
|
581
|
+
importPath: toImportPath(buildDir, source.filePath)
|
|
582
|
+
};
|
|
583
|
+
entries[logicalName] = entry;
|
|
584
|
+
if (!seenAliases.has(entry.alias)) {
|
|
585
|
+
seenAliases.add(entry.alias);
|
|
586
|
+
registry.uniqueAliases.push(entry);
|
|
587
|
+
}
|
|
588
|
+
}
|
|
589
|
+
}
|
|
590
|
+
registry.themes[theme.name] = entries;
|
|
591
|
+
}
|
|
592
|
+
registry.uniqueAliases.sort((left, right) => left.alias.localeCompare(right.alias));
|
|
593
|
+
return registry;
|
|
594
|
+
}
|
|
595
|
+
|
|
596
|
+
const themeJsonSchema = z.object({
|
|
597
|
+
name: z.string().min(1).regex(/^[a-z0-9-]+$/),
|
|
598
|
+
extends: z.string().min(1).regex(/^[a-z0-9-]+$/).optional(),
|
|
599
|
+
label: z.string().min(1).optional(),
|
|
600
|
+
description: z.string().min(1).optional()
|
|
601
|
+
});
|
|
602
|
+
async function fileExists(path) {
|
|
603
|
+
try {
|
|
604
|
+
await promises.access(path);
|
|
605
|
+
return true;
|
|
606
|
+
} catch {
|
|
607
|
+
return false;
|
|
608
|
+
}
|
|
609
|
+
}
|
|
610
|
+
function detectCycles(themesByName) {
|
|
611
|
+
const visited = /* @__PURE__ */ new Set();
|
|
612
|
+
const visiting = /* @__PURE__ */ new Set();
|
|
613
|
+
const visit = (themeName) => {
|
|
614
|
+
if (visited.has(themeName)) {
|
|
615
|
+
return;
|
|
616
|
+
}
|
|
617
|
+
if (visiting.has(themeName)) {
|
|
618
|
+
throw new Error(`Detected circular theme inheritance involving "${themeName}".`);
|
|
619
|
+
}
|
|
620
|
+
visiting.add(themeName);
|
|
621
|
+
const theme = themesByName.get(themeName);
|
|
622
|
+
if (!theme) {
|
|
623
|
+
throw new Error(`Theme "${themeName}" is missing from the resolved theme map.`);
|
|
624
|
+
}
|
|
625
|
+
if (theme.extends) {
|
|
626
|
+
if (!themesByName.has(theme.extends)) {
|
|
627
|
+
throw new Error(`Theme "${themeName}" extends missing parent theme "${theme.extends}".`);
|
|
628
|
+
}
|
|
629
|
+
visit(theme.extends);
|
|
630
|
+
}
|
|
631
|
+
visiting.delete(themeName);
|
|
632
|
+
visited.add(themeName);
|
|
633
|
+
};
|
|
634
|
+
for (const themeName of themesByName.keys()) {
|
|
635
|
+
visit(themeName);
|
|
636
|
+
}
|
|
637
|
+
}
|
|
638
|
+
function resolveInheritanceChain(themeName, themesByName) {
|
|
639
|
+
const chain = [];
|
|
640
|
+
let cursor = themesByName.get(themeName);
|
|
641
|
+
while (cursor) {
|
|
642
|
+
chain.push(cursor.name);
|
|
643
|
+
cursor = cursor.extends ? themesByName.get(cursor.extends) : void 0;
|
|
644
|
+
}
|
|
645
|
+
return chain;
|
|
646
|
+
}
|
|
647
|
+
async function loadThemeDefinitions(themesDir) {
|
|
648
|
+
const themeJsonFiles = await fg("*/theme.json", {
|
|
649
|
+
cwd: themesDir,
|
|
650
|
+
absolute: true,
|
|
651
|
+
onlyFiles: true
|
|
652
|
+
});
|
|
653
|
+
const themes = await Promise.all(themeJsonFiles.map(async (themeJsonPath) => {
|
|
654
|
+
const raw = await promises.readFile(themeJsonPath, "utf8");
|
|
655
|
+
const json = themeJsonSchema.parse(JSON.parse(raw));
|
|
656
|
+
const themePath = dirname(themeJsonPath);
|
|
657
|
+
const componentsDir = join(themePath, "app/components");
|
|
658
|
+
const assetsDir = join(themePath, "app/assets");
|
|
659
|
+
const cssFiles = await fileExists(assetsDir) ? await fg("**/*.{css,scss,sass,less,pcss}", {
|
|
660
|
+
cwd: assetsDir,
|
|
661
|
+
absolute: true,
|
|
662
|
+
onlyFiles: true
|
|
663
|
+
}) : [];
|
|
664
|
+
return {
|
|
665
|
+
name: json.name,
|
|
666
|
+
label: json.label ?? json.name,
|
|
667
|
+
description: json.description,
|
|
668
|
+
extends: json.extends,
|
|
669
|
+
path: themePath,
|
|
670
|
+
themeJsonPath,
|
|
671
|
+
componentsDir,
|
|
672
|
+
assetsDir,
|
|
673
|
+
cssFiles,
|
|
674
|
+
inheritanceChain: []
|
|
675
|
+
};
|
|
676
|
+
}));
|
|
677
|
+
const themesByName = new Map(themes.map((theme) => [theme.name, theme]));
|
|
678
|
+
detectCycles(themesByName);
|
|
679
|
+
const resolvedThemes = await Promise.all(themes.map(async (theme) => {
|
|
680
|
+
if (!await fileExists(theme.componentsDir)) {
|
|
681
|
+
return {
|
|
682
|
+
...theme,
|
|
683
|
+
inheritanceChain: resolveInheritanceChain(theme.name, themesByName)
|
|
684
|
+
};
|
|
685
|
+
}
|
|
686
|
+
return {
|
|
687
|
+
...theme,
|
|
688
|
+
inheritanceChain: resolveInheritanceChain(theme.name, themesByName)
|
|
689
|
+
};
|
|
690
|
+
}));
|
|
691
|
+
return resolvedThemes.sort((left, right) => left.name.localeCompare(right.name));
|
|
692
|
+
}
|
|
693
|
+
|
|
694
|
+
const DEFAULTS = {
|
|
695
|
+
themesDir: "themes",
|
|
696
|
+
defaultTheme: "base",
|
|
697
|
+
cookieKey: "theme-pref",
|
|
698
|
+
lazyLoadThemes: false,
|
|
699
|
+
requiredCssVars: [],
|
|
700
|
+
contractsEntry: "@tixxin/theme-contracts",
|
|
701
|
+
contractsImportId: "@tixxin/theme-contracts"
|
|
702
|
+
};
|
|
703
|
+
const require$1 = createRequire(import.meta.url);
|
|
704
|
+
async function pathExists(path) {
|
|
705
|
+
try {
|
|
706
|
+
await promises.access(path);
|
|
707
|
+
return true;
|
|
708
|
+
} catch {
|
|
709
|
+
return false;
|
|
710
|
+
}
|
|
711
|
+
}
|
|
712
|
+
function isLocalSpecifier(specifier) {
|
|
713
|
+
return specifier.startsWith(".") || specifier.startsWith("/") || specifier.startsWith("~") || /^[A-Za-z]:[\\/]/.test(specifier);
|
|
714
|
+
}
|
|
715
|
+
async function resolveContractsEntry(entry, importId, rootDir, moduleRoot, aliases) {
|
|
716
|
+
const internalDefaultEntry = resolve(moduleRoot, "packages/theme-contracts/src/index.ts");
|
|
717
|
+
if ((entry === "@tixxin/theme-contracts" || entry === "packages/theme-contracts/src/index.ts") && await pathExists(internalDefaultEntry)) {
|
|
718
|
+
return internalDefaultEntry;
|
|
719
|
+
}
|
|
720
|
+
const aliasTarget = aliases[entry] ?? aliases[importId];
|
|
721
|
+
if (typeof aliasTarget === "string") {
|
|
722
|
+
return isLocalSpecifier(aliasTarget) ? resolve(rootDir, aliasTarget) : aliasTarget;
|
|
723
|
+
}
|
|
724
|
+
if (isLocalSpecifier(entry)) {
|
|
725
|
+
return resolve(rootDir, entry);
|
|
726
|
+
}
|
|
727
|
+
return require$1.resolve(entry, {
|
|
728
|
+
paths: [rootDir, moduleRoot]
|
|
729
|
+
});
|
|
730
|
+
}
|
|
731
|
+
function serializeRegistry(registry) {
|
|
732
|
+
const registryShape = Object.fromEntries(
|
|
733
|
+
Object.entries(registry.themes).map(([themeName, entries]) => {
|
|
734
|
+
return [themeName, Object.fromEntries(
|
|
735
|
+
Object.entries(entries).map(([logicalName, entry]) => {
|
|
736
|
+
return [logicalName, {
|
|
737
|
+
alias: entry.alias,
|
|
738
|
+
sourceTheme: entry.sourceTheme
|
|
739
|
+
}];
|
|
740
|
+
})
|
|
741
|
+
)];
|
|
742
|
+
})
|
|
743
|
+
);
|
|
744
|
+
const loaderEntries = registry.uniqueAliases.map((entry, index) => ({
|
|
745
|
+
constName: `loader_${index}`,
|
|
746
|
+
entry
|
|
747
|
+
}));
|
|
748
|
+
const loaderDefinitions = loaderEntries.map((item) => `const ${item.constName} = () => import(${JSON.stringify(item.entry.importPath)})`).join("\n");
|
|
749
|
+
const loaderLookup = new Map(loaderEntries.map((item) => [`${item.entry.theme}:${item.entry.logicalName}`, item.constName]));
|
|
750
|
+
const loaderObject = Object.entries(registry.themes).map(([themeName, entries]) => {
|
|
751
|
+
const entrySource = Object.keys(entries).map((logicalName) => {
|
|
752
|
+
const loaderName = loaderLookup.get(`${themeName}:${logicalName}`);
|
|
753
|
+
return `${JSON.stringify(logicalName)}: ${loaderName}`;
|
|
754
|
+
}).join(",\n ");
|
|
755
|
+
return `${JSON.stringify(themeName)}: {
|
|
756
|
+
${entrySource}
|
|
757
|
+
}`;
|
|
758
|
+
}).join(",\n ");
|
|
759
|
+
return `${loaderDefinitions}
|
|
760
|
+
|
|
761
|
+
export const themeComponentRegistry = ${JSON.stringify(registryShape, null, 2)}
|
|
762
|
+
|
|
763
|
+
export const themeComponentLoaders = {
|
|
764
|
+
${loaderObject}
|
|
765
|
+
}
|
|
766
|
+
`;
|
|
767
|
+
}
|
|
768
|
+
function serializeOptions(options, themes) {
|
|
769
|
+
const serializedThemes = themes.map((theme) => ({
|
|
770
|
+
name: theme.name,
|
|
771
|
+
label: theme.label,
|
|
772
|
+
extends: theme.extends ?? null,
|
|
773
|
+
inheritanceChain: theme.inheritanceChain
|
|
774
|
+
}));
|
|
775
|
+
return `export const themeEngineOptions = ${JSON.stringify(options, null, 2)}
|
|
776
|
+
export const themeEngineThemeNames = ${JSON.stringify(themes.map((theme) => theme.name), null, 2)}
|
|
777
|
+
export const themeEngineThemes = ${JSON.stringify(serializedThemes, null, 2)}
|
|
778
|
+
`;
|
|
779
|
+
}
|
|
780
|
+
function serializeCssReport(report) {
|
|
781
|
+
return `export const themeCssVariableReport = ${JSON.stringify(report, null, 2)}
|
|
782
|
+
`;
|
|
783
|
+
}
|
|
784
|
+
function serializeContracts(entry, importId) {
|
|
785
|
+
return `export const themeEngineContracts = ${JSON.stringify({
|
|
786
|
+
entry,
|
|
787
|
+
importId
|
|
788
|
+
}, null, 2)}
|
|
789
|
+
`;
|
|
790
|
+
}
|
|
791
|
+
const module$1 = defineNuxtModule({
|
|
792
|
+
meta: {
|
|
793
|
+
name: "@tixxin/nuxt-theme-engine",
|
|
794
|
+
configKey: "themeEngine",
|
|
795
|
+
compatibility: {
|
|
796
|
+
nuxt: ">=4.0.0"
|
|
797
|
+
}
|
|
798
|
+
},
|
|
799
|
+
defaults: DEFAULTS,
|
|
800
|
+
async setup(moduleOptions, nuxt) {
|
|
801
|
+
const resolver = createResolver(import.meta.url);
|
|
802
|
+
const moduleRoot = resolver.resolve("..");
|
|
803
|
+
const options = {
|
|
804
|
+
...DEFAULTS,
|
|
805
|
+
...moduleOptions
|
|
806
|
+
};
|
|
807
|
+
const themesDir = resolve(nuxt.options.rootDir, options.themesDir);
|
|
808
|
+
const contractsImportId = options.contractsImportId;
|
|
809
|
+
const contractsEntry = await resolveContractsEntry(
|
|
810
|
+
options.contractsEntry,
|
|
811
|
+
contractsImportId,
|
|
812
|
+
nuxt.options.rootDir,
|
|
813
|
+
moduleRoot,
|
|
814
|
+
nuxt.options.alias
|
|
815
|
+
);
|
|
816
|
+
const themes = await loadThemeDefinitions(themesDir);
|
|
817
|
+
const defaultTheme = themes.some((theme) => theme.name === options.defaultTheme) ? options.defaultTheme : themes[0]?.name ?? options.defaultTheme;
|
|
818
|
+
const resolvedOptions = {
|
|
819
|
+
...options,
|
|
820
|
+
contractsEntry,
|
|
821
|
+
contractsImportId,
|
|
822
|
+
defaultTheme,
|
|
823
|
+
lazyLoadThemes: options.lazyLoadThemes && !nuxt.options.dev
|
|
824
|
+
};
|
|
825
|
+
const registry = await generateThemeRegistry(themes, nuxt.options.buildDir);
|
|
826
|
+
if (!nuxt.options.alias[contractsImportId]) {
|
|
827
|
+
nuxt.options.alias[contractsImportId] = contractsEntry;
|
|
828
|
+
}
|
|
829
|
+
addImportsDir(resolver.resolve("./runtime/composables"));
|
|
830
|
+
addPlugin(resolver.resolve("./runtime/plugins/theme-sync.client"));
|
|
831
|
+
addComponent({
|
|
832
|
+
name: "ThemeComponent",
|
|
833
|
+
filePath: resolver.resolve("./runtime/components/ThemeComponent.vue")
|
|
834
|
+
});
|
|
835
|
+
if (!resolvedOptions.lazyLoadThemes) {
|
|
836
|
+
for (const entry of registry.uniqueAliases) {
|
|
837
|
+
addComponent({
|
|
838
|
+
name: entry.alias,
|
|
839
|
+
filePath: entry.filePath
|
|
840
|
+
});
|
|
841
|
+
}
|
|
842
|
+
}
|
|
843
|
+
for (const theme of themes) {
|
|
844
|
+
for (const cssFile of theme.cssFiles) {
|
|
845
|
+
if (!nuxt.options.css.includes(cssFile)) {
|
|
846
|
+
nuxt.options.css.push(cssFile);
|
|
847
|
+
}
|
|
848
|
+
}
|
|
849
|
+
}
|
|
850
|
+
addTemplate({
|
|
851
|
+
filename: "theme-engine.options.mjs",
|
|
852
|
+
getContents: () => serializeOptions(resolvedOptions, themes)
|
|
853
|
+
});
|
|
854
|
+
addTemplate({
|
|
855
|
+
filename: "theme-engine.registry.mjs",
|
|
856
|
+
getContents: () => serializeRegistry(registry)
|
|
857
|
+
});
|
|
858
|
+
addTemplate({
|
|
859
|
+
filename: "theme-engine.contracts.mjs",
|
|
860
|
+
getContents: () => serializeContracts(contractsEntry, contractsImportId)
|
|
861
|
+
});
|
|
862
|
+
const cssReportTemplate = addTemplate({
|
|
863
|
+
filename: "theme-engine.css-report.mjs",
|
|
864
|
+
getContents: () => serializeCssReport([])
|
|
865
|
+
});
|
|
866
|
+
addTypeTemplate({
|
|
867
|
+
filename: "types/theme-components.d.ts",
|
|
868
|
+
getContents: () => generateThemeComponentDts(contractsEntry, contractsImportId)
|
|
869
|
+
});
|
|
870
|
+
extendPages((pages) => {
|
|
871
|
+
pages.push({
|
|
872
|
+
name: "theme-engine-devtools",
|
|
873
|
+
path: "/_theme-engine-devtools",
|
|
874
|
+
file: resolver.resolve("./runtime/devtools/page.vue")
|
|
875
|
+
});
|
|
876
|
+
});
|
|
877
|
+
addCustomTab({
|
|
878
|
+
name: "theme-engine",
|
|
879
|
+
title: "Theme Engine",
|
|
880
|
+
icon: "carbon:paint-brush",
|
|
881
|
+
category: "modules",
|
|
882
|
+
view: {
|
|
883
|
+
type: "iframe",
|
|
884
|
+
src: "/_theme-engine-devtools"
|
|
885
|
+
}
|
|
886
|
+
}, nuxt);
|
|
887
|
+
nuxt.hook("close", async () => {
|
|
888
|
+
const report = await checkCssVars(nuxt.options.rootDir, themes, resolvedOptions.requiredCssVars);
|
|
889
|
+
await promises.writeFile(cssReportTemplate.dst, serializeCssReport(report), "utf8");
|
|
890
|
+
for (const item of report.filter((entry) => entry.missing.length > 0)) {
|
|
891
|
+
logger.warn(`Theme "${item.theme}" is missing required CSS variables: ${item.missing.join(", ")}`);
|
|
892
|
+
}
|
|
893
|
+
});
|
|
894
|
+
}
|
|
895
|
+
});
|
|
896
|
+
|
|
897
|
+
export { module$1 as default };
|