@vuestic/compiler
Version:
Combination of bundling tools focusing on improving development experience when working with Vuestic UI
1,147 lines (1,104 loc) • 36.5 kB
JavaScript
var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
// If the importer is in node compatibility mode or this is not an ESM
// file that has been converted to a CommonJS file using a Babel-
// compatible transform (i.e. "__esModule" has not been set), then set
// "default" to the CommonJS "module.exports" for node compatibility.
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
mod
));
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
// vite-plugin.ts
var vite_plugin_exports = {};
__export(vite_plugin_exports, {
vuestic: () => vuestic
});
module.exports = __toCommonJS(vite_plugin_exports);
// node_modules/tsup/assets/cjs_shims.js
var getImportMetaUrl = () => typeof document === "undefined" ? new URL(`file:${__filename}`).href : document.currentScript && document.currentScript.src || new URL("main.js", document.baseURI).href;
var importMetaUrl = /* @__PURE__ */ getImportMetaUrl();
// devtools/plugin/plugin.ts
var import_vite = require("vite");
var import_pluginutils = require("@rollup/pluginutils");
// devtools/plugin/compiler.ts
var import_compiler_sfc = require("@vue/compiler-sfc");
var import_magic_string = __toESM(require("magic-string"), 1);
// devtools/shared/CONST.ts
var PREFIX = "va";
var API_PREFIX = "/vuestic-devtools-api";
// devtools/shared/slug.ts
var knownPaths = /* @__PURE__ */ new Map();
var minifyPath = (path) => {
const minified = `${PREFIX}-${knownPaths.size}`;
knownPaths.set(minified, path);
return minified;
};
var unminifyPath = (minified) => {
if (knownPaths.has(minified)) {
return knownPaths.get(minified);
}
return null;
};
var replacePath = (minified, path) => {
knownPaths.set(minified, path);
return minified;
};
// devtools/shared/file-query.ts
var stringifyFileQuery = (path, start, end) => `${path}:${start}:${end}`;
var parseFileQuery = (query) => {
const params = query.split(":");
const end = params.pop();
const start = params.pop();
const path = params.join(":");
return { path, start: Number(start), end: Number(end) };
};
// devtools/plugin/compiler.ts
var import_promises = require("fs/promises");
// devtools/plugin/diff-sync.ts
var makeDiffSyncByRow = (original, modified) => {
const originalLines = original.split("\n");
const modifiedLines = modified.split("\n");
let sourceShift = 0;
let outputShift = 0;
const blocks = [];
for (let i = 0; i < Math.max(originalLines.length, modifiedLines.length); i++) {
const sourceLine = (originalLines[i] ?? "") + "\n";
const modifiedLine = (modifiedLines[i] ?? "") + "\n";
if (sourceLine === modifiedLine) {
blocks.push({
type: "equal",
start: { source: sourceShift, output: outputShift },
end: {
source: sourceShift + sourceLine.length,
output: outputShift + sourceLine.length
},
source: sourceLine
});
} else {
const lineDiff = makeDiffSync(sourceLine, modifiedLine);
for (const block of lineDiff) {
blocks.push({
...block,
start: {
source: block.start.source + sourceShift,
output: block.start.output + outputShift
},
end: {
source: block.end.source + sourceShift,
output: block.end.output + outputShift
}
});
}
}
sourceShift += sourceLine.length;
outputShift += modifiedLine.length;
}
return mergeEqualBlocks(blocks);
};
var mergeEqualBlocks = (blocks) => {
return blocks.reduce((acc, block) => {
const last = acc.at(-1);
if (block.type === "equal" && last?.type === "equal") {
last.source += block.source;
last.end = block.end;
} else {
acc.push(block);
}
return acc;
}, []);
};
var makeDiffSync = (source, output) => {
let originalShift = 0;
let modifiedShift = 0;
function makeBlock(type, sourceStart, sourceEnd, outputStart, outputEnd) {
const blockSource = type === "insert" ? output.slice(outputStart, outputEnd) : source.slice(sourceStart, sourceEnd);
return {
start: {
source: sourceStart,
output: outputStart
},
end: {
source: sourceEnd,
output: outputEnd
},
type,
source: blockSource
};
}
const blocks = [
makeBlock("equal", 0, 0, 0, 0)
];
function findInsert(originalShift2, modifiedShift2) {
const modifiedShiftStart = modifiedShift2;
while (originalShift2 < source.length && modifiedShift2 < output.length) {
if (output[modifiedShift2] === source[originalShift2]) {
break;
}
modifiedShift2++;
}
if (output.length < modifiedShiftStart) {
return;
}
return makeBlock("insert", originalShift2, originalShift2, modifiedShiftStart, modifiedShift2);
}
function findDelete(originalShift2, modifiedShift2) {
const originalShiftStart = originalShift2;
while (originalShift2 < source.length && modifiedShift2 < output.length) {
if (output[modifiedShift2] === source[originalShift2]) {
return makeBlock("delete", originalShiftStart, originalShift2, modifiedShift2, modifiedShift2);
}
originalShift2++;
}
}
while (originalShift < source.length && modifiedShift < output.length) {
const originalChar = source[originalShift];
const modifiedChar = output[modifiedShift];
const currentBlock = blocks[blocks.length - 1];
if (originalChar === modifiedChar) {
if (currentBlock.type === "equal") {
currentBlock.end.output++;
currentBlock.end.source++;
currentBlock.source = source.slice(currentBlock.start.source, currentBlock.end.source);
} else {
blocks.push(makeBlock("equal", originalShift, originalShift + 1, modifiedShift, modifiedShift + 1));
}
originalShift++;
modifiedShift++;
} else {
const nextChain = findDelete(originalShift, modifiedShift);
const insertBlock = findInsert(originalShift, modifiedShift);
if (nextChain && insertBlock) {
if (output.slice(modifiedShift).includes(nextChain.source)) {
blocks.push(insertBlock);
modifiedShift = insertBlock.end.output;
continue;
}
blocks.push(nextChain);
originalShift = nextChain.end.source;
continue;
}
if (insertBlock) {
blocks.push(insertBlock);
modifiedShift = insertBlock.end.output;
continue;
}
if (nextChain) {
blocks.push(nextChain);
originalShift = nextChain.end.source;
continue;
}
break;
}
}
return blocks;
};
// devtools/plugin/compiler.ts
var walk = (node, cb) => {
cb(node);
if (!("children" in node)) {
return;
}
for (const child of node.children) {
if (typeof child === "string") {
continue;
}
if (typeof child === "symbol") {
continue;
}
if (child.type === 4) {
continue;
}
walk(child, cb);
}
};
var findEndTagIndex = (source) => {
let inQuotes = false;
for (let i = 0; i < source.length; i++) {
if (source[i] === '"') {
inQuotes = !inQuotes;
}
if (source[i] === ">" && !inQuotes) {
return i;
}
}
return -1;
};
var findSefCloseTagIndex = (source) => {
let inQuotes = false;
for (let i = 0; i < source.length; i++) {
if (source[i] === '"') {
inQuotes = !inQuotes;
}
if (source[i] === "/" && source[i + 1] === ">" && !inQuotes) {
return i;
}
}
return -1;
};
var getNodeTagLoc = (source) => {
let selfCloseIndex = findSefCloseTagIndex(source);
let closeIndex = findEndTagIndex(source);
if (selfCloseIndex === -1) {
selfCloseIndex = source.length;
}
if (closeIndex === -1) {
closeIndex = source.length;
}
return {
start: { offset: 0 },
end: { offset: selfCloseIndex < closeIndex ? selfCloseIndex + 2 : closeIndex + 1 },
source: source.slice(0, selfCloseIndex < closeIndex ? selfCloseIndex + 2 : closeIndex + 1),
endSymbol: selfCloseIndex < closeIndex ? "/>" : ">"
};
};
var fromOutputToSourceShift = (source, output) => {
const diff = makeDiffSyncByRow(source, output);
return (start, end) => {
let current = void 0;
let shiftStart = 0;
let shiftEnd = 0;
for (let i = 0; i < diff.length; i++) {
current = diff[i];
if (current.end.output > end) {
break;
}
if (current.type === "equal") {
continue;
} else if (current.type === "insert") {
if (current.start.output < start) {
shiftStart -= current.source.length;
}
if (current.end.output < end) {
shiftEnd -= current.source.length;
}
}
}
if (!current) {
return { start: 0, end: 0 };
}
return { start: shiftStart, end: shiftEnd };
};
};
var transformFile = async (code, id) => {
const sourceFile = await (0, import_promises.readFile)(id, "utf-8");
const result = (0, import_compiler_sfc.parse)(code);
const templateAst = result.descriptor.template?.ast;
if (!templateAst) {
return;
}
let source = new import_magic_string.default(code);
if (code !== sourceFile) {
const getShift = fromOutputToSourceShift(sourceFile, code);
walk(templateAst, (node) => {
if (node.type === 1) {
const tagLoc = getNodeTagLoc(node.loc.source);
const shift = getShift(node.loc.start.offset, node.loc.end.offset);
const nodeId = stringifyFileQuery(id, node.loc.start.offset + shift.start, node.loc.end.offset + shift.end);
const withAttribute = ` data-${PREFIX}="" data-${minifyPath(nodeId)}="${node.tag}"`;
source.appendLeft(node.loc.start.offset + tagLoc.end.offset - tagLoc.endSymbol.length, withAttribute);
}
});
} else {
walk(templateAst, (node) => {
if (node.type === 1) {
const tagLoc = getNodeTagLoc(node.loc.source);
const nodeId = stringifyFileQuery(id, node.loc.start.offset, node.loc.end.offset);
const withAttribute = ` data-${PREFIX}="" data-${minifyPath(nodeId)}="${node.tag}"`;
source.appendLeft(node.loc.start.offset + tagLoc.end.offset - tagLoc.endSymbol.length, withAttribute);
}
});
}
return {
code: source.toString(),
map: source.generateMap()
};
};
// devtools/server/utils.ts
var readBody = async (req) => {
return new Promise((resolve3) => {
let body = "";
req.on("data", (chunk) => {
body += chunk;
});
req.on("end", () => {
resolve3(body);
});
});
};
// devtools/server/file.ts
var import_promises2 = require("fs/promises");
var requestSource = async (path) => {
const source = await (0, import_promises2.readFile)(path, "utf-8");
return source.toString();
};
var getIntent = (source, lineStart) => {
let intent = 0;
for (let i = lineStart - 1; i > 0; i--) {
if (source[i] === " ") {
intent++;
} else {
break;
}
}
return intent;
};
var removeIntent = (source, intent) => {
const lines = source.split("\n");
const intentString = " ".repeat(intent);
return lines.map((line) => {
if (line.startsWith(intentString)) {
return line.slice(intentString.length);
}
return line;
}).join("\n");
};
var addIntent = (source, intent) => {
if (source.length === 0) {
return source;
}
const lines = source.split("\n");
const intentString = " ".repeat(intent);
return lines.filter((line) => line.length > 0).map((line, index) => {
if (index === 0) {
return line;
}
return intentString + line;
}).join("\n");
};
var getComponentSource = async (path, start, end) => {
const fileSource = await requestSource(path);
const intent = getIntent(fileSource, start);
const componentSource = fileSource.slice(start, end);
return removeIntent(componentSource, intent);
};
var setComponentSource = async (path, start, end, source) => {
const fileSource = await requestSource(path);
const intent = getIntent(fileSource, start);
const sourceWithIntent = addIntent(source, intent);
const fileSourceStart = fileSource.slice(0, start);
const fileSourceEnd = fileSource.slice(end);
const newFileContent = fileSourceStart + sourceWithIntent + fileSourceEnd;
await (0, import_promises2.writeFile)(path, newFileContent);
return {
path,
start,
end: start + sourceWithIntent.length
};
};
var deleteComponentSource = async (path, start, end) => {
const fileSource = await requestSource(path);
const intent = getIntent(fileSource, start);
if (intent === 0) {
await (0, import_promises2.writeFile)(path, fileSource.slice(0, start) + fileSource.slice(end));
return {
path,
start,
end: start
};
}
const fileSourceStart = fileSource.slice(0, start - intent - "\n".length);
const fileSourceEnd = fileSource.slice(end);
await (0, import_promises2.writeFile)(path, fileSourceStart + fileSourceEnd);
return {
path,
start: start - intent - "\n".length,
end: start - intent - "\n".length
};
};
var getComponentLineAndCol = async (path, start) => {
const fileSource = await requestSource(path);
const intent = getIntent(fileSource, start);
const lines = fileSource.slice(0, start).split("\n");
const line = lines.length;
const col = intent;
return { line, col };
};
var getRelativeFilePath = (path) => {
return "." + path.replace(process.cwd(), "");
};
// devtools/server/server-middleware.ts
var devtoolsServerMiddleware = () => {
return async (req, res, next) => {
if (!req.url || !req.url.startsWith(API_PREFIX)) {
return next();
}
const url = new URL(req.url, "http://localhost:8088");
const minified = url.searchParams.get("q") ?? "";
const unminified = unminifyPath(minified);
if (!unminified) {
res.writeHead(400);
res.end(`No q provided. Got q="${url.searchParams.get("q")}"`);
return;
}
const { path, start, end } = parseFileQuery(unminified);
if (req.method === "GET" && req.url.startsWith(`${API_PREFIX}/node-source`)) {
res.writeHead(200);
res.end(await getComponentSource(path, start, end));
return;
}
if (req.method === "PATCH" && req.url.startsWith(`${API_PREFIX}/node-source`)) {
const body = await readBody(req);
if (!(typeof body === "string")) {
throw new Error("Body is required.");
}
const newPath = await setComponentSource(path, start, end, body);
replacePath(minified, stringifyFileQuery(newPath.path, newPath.start, newPath.end));
res.writeHead(200);
res.end(minified);
return;
}
if (req.method === "DELETE" && req.url.startsWith(`${API_PREFIX}/node-source`)) {
const newPath = await deleteComponentSource(path, start, end);
replacePath(minified, stringifyFileQuery(newPath.path, newPath.start, newPath.end));
res.writeHead(200);
res.end();
return;
}
if (req.method === "GET" && req.url.startsWith(`${API_PREFIX}/file-name`)) {
res.writeHead(200);
res.end(unminified);
return;
}
if (req.method === "GET" && req.url.startsWith(`${API_PREFIX}/relative-file-path`)) {
res.writeHead(200);
res.end(getRelativeFilePath(path));
return;
}
if (req.method === "GET" && req.url.startsWith(`${API_PREFIX}/vscode-path`)) {
const { line, col } = await getComponentLineAndCol(path, Number(start));
res.writeHead(200);
res.end(`${path}:${line}:${col}`);
return;
}
next();
};
};
// devtools/plugin/plugin.ts
var import_node_url = require("url");
// shared/plugin/js.ts
var import_magic_string2 = __toESM(require("magic-string"), 1);
// shared/plugin/code.ts
var import_acorn = require("acorn");
var getContentInParenthesis = (content) => {
let text = "";
let bracketCount = 0;
for (let i = 0; i < content.length; i++) {
if (content[i] === "(") {
bracketCount++;
continue;
}
if (content[i] === ")") {
bracketCount--;
}
if (bracketCount === 0) {
break;
}
text += content[i];
}
return text;
};
var isObject = (t) => {
return t.type === "ObjectExpression";
};
var isProperty = (t) => {
return t.type === "Property";
};
var OBJECT_DECLARATION = "const obj = ";
var replaceOrAddConfigPropertyValue = (content, newValue) => {
const code = OBJECT_DECLARATION + content;
try {
const program = (0, import_acorn.parse)(code, { ecmaVersion: 2020 });
const object = program.body[0].declarations[0].init;
let configProperty = null;
if (isObject(object)) {
const properties = object.properties;
for (const property of properties) {
if (isProperty(property)) {
const name = "name" in property.key ? property.key.name : "value" in property.key ? property.key.value : null;
if (name === "config") {
configProperty = property;
break;
}
}
}
if (!configProperty) {
return `{
config: ${newValue},
${properties.map((p) => {
return p.loc?.source;
}).join(", ")}
}`;
}
return (code.slice(0, configProperty.start) + `config: ` + newValue + code.slice(configProperty.end)).slice(OBJECT_DECLARATION.length);
}
return content;
} catch (e) {
console.error("Unable to parse code:", code);
console.error(e);
return content;
}
};
var omitComments = (code) => {
return code.replace(/\/\/.*|\/\*[\s\S]*?\*\//g, "").trim();
};
// shared/plugin/js.ts
var CREATE_APP_REGEX = /createApp\(([^)]+)\)/gm;
function getCreateAppTemplate(code) {
const match = CREATE_APP_REGEX.exec(code);
return match ? match[0] : null;
}
var createMagicString = (code) => {
return typeof code === "string" ? new import_magic_string2.default(code) : code;
};
var addImport = (originalCode, code) => {
const ms = createMagicString(originalCode);
ms.appendLeft(0, code + "\n");
return ms;
};
var hasImport = (originalCode, from) => {
const ms = createMagicString(originalCode);
if (typeof from === "string") {
const importRegex = new RegExp(`import\\s+.*?\\s+from\\s+['"]${from}['"]`);
return importRegex.test(ms.original);
}
if (typeof from === "object" && from.from && from.named) {
const importRegex = new RegExp(`import\\s+.*?\\s+from\\s+['"]${from.from}['"]\\s*{\\s*${from.named}\\s*}`);
return importRegex.test(ms.original);
}
return false;
};
var hasVuePlugin = (originalCode, pluginName) => {
const ms = createMagicString(originalCode);
const pluginRegex = new RegExp(`\\.use\\(${pluginName}\\(`);
return pluginRegex.test(omitComments(ms.original));
};
var addVuePlugin = (originalCode, code) => {
const ms = createMagicString(originalCode);
const createAppTemplate = getCreateAppTemplate(ms.original);
if (!createAppTemplate) {
return null;
}
const createAppIndex = ms.original.indexOf(createAppTemplate);
ms.appendRight(createAppIndex + createAppTemplate.length, `.use(${code})`);
return ms;
};
var mergeVuesticPluginConfigOption = (originalCode, pluginName, content = "") => {
const ms = createMagicString(originalCode);
const createPluginCode = `.use(${pluginName}(`;
const existingPluginIndex = ms.original.indexOf(createPluginCode);
if (existingPluginIndex === -1) {
return null;
}
const nextCode = ms.original.slice(existingPluginIndex + createPluginCode.length - 1);
const contentInParenthesis = getContentInParenthesis(nextCode);
let newCode;
if (contentInParenthesis) {
newCode = replaceOrAddConfigPropertyValue(contentInParenthesis, content);
} else {
newCode = `{ config: ${content} }`;
}
return ms.remove(existingPluginIndex, existingPluginIndex + createPluginCode.length + contentInParenthesis.length + 2).appendLeft(existingPluginIndex + createPluginCode.length, `.use(${pluginName}(${newCode}))`);
};
var compileCode = (ms) => {
if (typeof ms === "string") {
return { code: ms };
}
return {
code: ms.toString(),
map: ms.generateMap()
};
};
// devtools/plugin/add-vue-plugin.ts
var setupDevtoolsVuePlugin = (code) => {
let newCode = addVuePlugin(code, "createVuesticDevtools()");
if (!newCode) {
return null;
}
newCode = addImport(newCode, 'import { createVuesticDevtools } from "@vuestic/compiler/devtools";');
return {
code: newCode.toString(),
map: newCode.generateMap({ hires: true })
};
};
// shared/color.ts
var white = "\x1B[0m";
var reset = "\x1BRESET";
var red = "\x1B[31m";
var yellow = "\x1B[33m";
var cyan = "\x1B[36m";
var formatString = (str) => {
str = str.replace(/\[([^\]]*)\]/g, (_, p1) => cyan + p1 + reset);
if (str.startsWith("!!! ")) {
str = red + str.slice(4).replaceAll(reset, red) + reset;
}
if (str.startsWith("! ")) {
str = yellow + str.slice(2).replaceAll(reset, yellow) + reset;
}
return str.replaceAll(reset, white);
};
// devtools/plugin/plugin.ts
var ALT_KEY = process.platform === "darwin" ? "Option \u2325" : "Alt";
var logger = (0, import_vite.createLogger)("info", {
prefix: "[vuestic:devtools]"
});
var devtools = (options = {}) => {
const filter = (0, import_pluginutils.createFilter)(
options.include ?? ["**/*.vue"],
options.exclude ?? ["node_modules/**"]
);
let config;
return {
name: "vuestic:devtools",
configureServer(server) {
server.middlewares.use(devtoolsServerMiddleware());
},
configResolved(resolvedConfig) {
config = resolvedConfig;
},
async resolveId(id) {
if (id.startsWith("@vuestic/compiler/devtools")) {
if (config.isProduction) {
throw new Error("VuesticDevtools: devtools must not be imported in production");
}
return (0, import_node_url.fileURLToPath)(new import_node_url.URL("../client/index.ts", importMetaUrl));
}
},
async transform(code, id) {
if (config.isProduction) {
return;
}
if (/\/src\/main\.(ts|js|mjs|mts)$/.test(id)) {
const newCode = setupDevtoolsVuePlugin(code);
if (!newCode) {
throw new Error("Failed to setup vuestic devtools plugin");
}
if (newCode) {
logger.info(formatString(`Vuestic Devtools installed. Open your application and press [${ALT_KEY}] + [F12] to open devtools`), {
timestamp: true
});
} else {
logger.error(formatString("! Devtools plugin can not find createApp(App) in your main file. This is likely a bug, please, open an issue on GitHub."), {
timestamp: true
});
logger.error(formatString("[https://github.com/epicmaxco/vuestic-ui/issues/new?assignees=&labels=BUG&projects=&template=bug-template.md]"), {
timestamp: true
});
}
return newCode;
}
if (!filter(id)) {
return;
}
return transformFile(code, id);
}
};
};
// css-layers/plugin.ts
var import_magic_string3 = __toESM(require("magic-string"), 1);
var addLayer = (ms, layer, tailwind) => {
ms.prepend(`@layer ${tailwind ? "base, " : ""}vuestic.styles, vuestic.components;
@layer ${layer} {
`);
ms.append(`
}`);
return {
code: ms.toString(),
map: ms.generateMap()
};
};
var cssLayers = (options = { tailwind: false }) => ({
name: "vuestic:css-layer",
transform(code, id) {
if (!id.endsWith(".css")) return null;
if (id.includes("vuestic-ui/dist/styles/") || id.includes("vuestic-ui/packages/ui/dist/styles/")) {
return addLayer(new import_magic_string3.default(code), "vuestic.styles", options.tailwind);
}
if (id.includes("vuestic-ui/dist/es/") || id.includes("vuestic-ui/packages/ui/dist/es/")) {
return addLayer(new import_magic_string3.default(code), "vuestic.components", options.tailwind);
}
}
});
// vuestic-config/plugins/config-resolver.ts
var import_node_fs = require("fs");
var import_promises3 = require("fs/promises");
var import_node_path = require("path");
var VUESTIC_CONFIG_ALIAS = "#vuestic-config";
var resolveVuesticConfigPath = () => {
if ((0, import_node_fs.existsSync)("./vuestic.config.ts")) {
return "./vuestic.config.ts";
} else if ((0, import_node_fs.existsSync)("./vuestic.config.js")) {
return "./vuestic.config.js";
} else if ((0, import_node_fs.existsSync)("./vuestic.config.mjs")) {
return "./vuestic.config.mjs";
} else if ((0, import_node_fs.existsSync)("./vuestic.config.cjs")) {
return "./vuestic.config.cjs";
} else if ((0, import_node_fs.existsSync)("./vuestic.config.mts")) {
return "./vuestic.config.mts";
} else {
return void 0;
}
};
var isConfigExists = (configPath) => {
if (!configPath) {
return resolveVuesticConfigPath();
}
return (0, import_node_fs.existsSync)(configPath);
};
var configResolver = (options = {}) => {
return {
name: "vuestic:config-resolver",
// Resolve vuestic config alias
async resolveId(source, importer) {
if (source === VUESTIC_CONFIG_ALIAS) {
const {
configPath = resolveVuesticConfigPath()
} = options;
if (configPath) {
return (0, import_node_path.resolve)(configPath);
}
return `virtual:vuestic-config`;
}
},
async load(id) {
if (id === `virtual:vuestic-config`) {
return "export default {}";
}
}
};
};
// shared/plugin/is-entry-file.ts
var isEntryFile = (id) => {
return /\/src\/main\.(ts|js|mjs|mts)$/.test(id);
};
// vuestic-config/plugins/use-config.ts
var CONFIG_IMPORT_NAME = "vuesticConfig$va1";
var useConfig = (options = {}) => {
return {
name: "vuestic:use-config",
transform(code, id) {
if (!isEntryFile(id)) {
return;
}
if (!isConfigExists(options.configPath)) {
return;
}
let newCode = addImport(code, `import ${CONFIG_IMPORT_NAME} from '#vuestic-config'`);
const createVuestic = mergeVuesticPluginConfigOption(newCode, "createVuestic", CONFIG_IMPORT_NAME);
const createVuesticEssential = mergeVuesticPluginConfigOption(newCode, "createVuesticEssential", CONFIG_IMPORT_NAME);
if (createVuestic) {
return compileCode(createVuestic);
}
if (createVuesticEssential) {
return compileCode(createVuesticEssential);
}
throw new Error("createVuestic or createVuesticEssential not found in entry file. Please ensure you installed createVuestic plugin or used autoImport option for compiler.");
}
};
};
// vuestic-config/plugins/config-types.ts
var import_promises4 = require("fs/promises");
var import_path = require("path");
var generateConfigTypes = (configPath) => {
return `
import type config from '${configPath}';
import type { PartialGlobalConfig, IconConfiguration } from 'vuestic-ui';
type ExtractColorNames<T extends PartialGlobalConfig> = T['colors'] extends { variables: infer U } ? keyof U : never
type ExtractIconNames<T extends PartialGlobalConfig> = T['icons'] extends IconConfiguration<infer U>[] ? U : never
type ExtractI18nKeys<T extends PartialGlobalConfig> = keyof T['i18n']
type Config = typeof config
type ColorNames = ExtractColorNames<Config>
declare module 'vuestic-ui' {
export interface CustomColorVariables extends Record<ColorNames, string> {}
}
type IconNames = ExtractIconNames<Config>
declare module 'vuestic-ui' {
export interface CustomIconVariables extends Record<IconNames, string> {}
}
type I18nKeys = ExtractI18nKeys<Config>
declare module 'vuestic-ui' {
export interface CustomI18NKeys extends Record<I18nKeys, string> {}
}
`;
};
var typeModule = (configPath) => {
const config = configPath ? generateConfigTypes(configPath) : "";
return `
import * as Vue from 'vue'
${config}
declare module 'vue' {
// eslint-disable-next-line @typescript-eslint/no-empty-object-type
export interface GlobalComponents extends VuesticComponents {}
}
`.trim();
};
var indexTs = () => {
return `
export * from './components'
export * from './config'
`;
};
var configTypes = (options = {}) => {
return {
name: "vuestic:config-types",
async buildStart() {
let configPath = options.configPath || resolveVuesticConfigPath();
configPath = configPath ? (0, import_path.resolve)(configPath) : configPath;
const module2 = typeModule(configPath);
await (0, import_promises4.mkdir)("node_modules/.vuestic", { recursive: true });
await Promise.all([
(0, import_promises4.writeFile)("node_modules/.vuestic/index.d.ts", indexTs(), {
encoding: "utf-8",
flag: "w"
}),
(0, import_promises4.writeFile)("node_modules/.vuestic/config.d.ts", module2, {
encoding: "utf-8",
flag: "w"
})
]);
}
};
};
// vuestic-config/plugin.ts
var vuesticConfig = (options = {}) => {
return [
configTypes(options),
configResolver(options),
useConfig(options)
];
};
// auto-import/plugin.ts
var import_vite2 = __toESM(require("unplugin-vue-components/vite"), 1);
var import_compiler_sfc2 = require("@vue/compiler-sfc");
function installVuesticEssentialPlugin(ms) {
if (!hasImport(ms, { named: "createVuesticEssential", from: "vuestic-ui" })) {
addImport(ms, `import { createVuesticEssential } from 'vuestic-ui'`);
}
if (!hasVuePlugin(ms, "createVuesticEssential")) {
addVuePlugin(ms, "createVuesticEssential()");
}
return ms;
}
function installVuesticEssentialStyles(ms, options) {
if (!hasImport(ms, "vuestic-ui/styles/essential.css")) {
addImport(ms, `import 'vuestic-ui/styles/essential.css'`);
}
if (options.typography) {
if (!hasImport(ms, "vuestic-ui/styles/typography.css")) {
addImport(ms, `import 'vuestic-ui/styles/typography.css'`);
}
}
return ms;
}
var vuesticAutoImport = (options = {}) => {
const prefix = "Va";
return [
{
name: "vuestic:auto-import",
enforce: "pre",
transform(code, id) {
if (!isEntryFile(id)) {
return;
}
const ms = new import_compiler_sfc2.MagicString(code);
installVuesticEssentialPlugin(ms);
installVuesticEssentialStyles(ms, options);
return {
code: ms.toString(),
map: ms.generateMap({ hires: true })
};
}
},
(0, import_vite2.default)({
dts: "node_modules/.vuestic/components.d.ts",
resolvers: [
(componentName) => {
if (componentName.startsWith(prefix))
return { name: componentName, from: "vuestic-ui" };
}
]
})
];
};
// shared/merge-deep.ts
var isObject2 = (obj) => obj && typeof obj === "object" && !Array.isArray(obj);
var mergeDeep = (target, source) => {
if (!isObject2(target)) {
target = {};
}
Object.keys(source).forEach((key) => {
const targetValue = target[key];
const sourceValue = source[key];
if (sourceValue instanceof RegExp || sourceValue instanceof Date) {
target[key] = sourceValue;
} else if (isObject2(targetValue) && isObject2(sourceValue)) {
target[key] = mergeDeep(Object.create(
Object.getPrototypeOf(targetValue),
Object.getOwnPropertyDescriptors(targetValue)
), sourceValue);
} else {
target[key] = sourceValue;
}
});
return target;
};
// logger.ts
var import_vite3 = require("vite");
var logger2 = (0, import_vite3.createLogger)("info", {
prefix: "[vuestic:compiler]"
});
// shared/project-env.ts
var import_confbox = require("confbox");
var import_fs = require("fs");
var import_meta = {};
function readPackageJson() {
try {
const packageJson = (0, import_fs.readFileSync)("package.json", "utf-8");
return (0, import_confbox.parseJSON5)(packageJson);
} catch (error) {
return null;
}
}
function checkModuleExists(moduleName) {
try {
import_meta.resolve?.(moduleName);
return true;
} catch (error) {
return false;
}
}
function getNodeVersion() {
const version = process.versions.node;
return {
major: parseInt(version.split(".")[0], 10),
minor: parseInt(version.split(".")[1], 10),
patch: parseInt(version.split(".")[2], 10),
full: version,
toString: () => version
};
}
function getPackageManager() {
const packageJson = readPackageJson();
if ((0, import_fs.existsSync)("yarn.lock")) {
return "yarn";
}
if ((0, import_fs.existsSync)("pnpm-lock.yaml")) {
return "pnpm";
}
if ((0, import_fs.existsSync)("bun.lockb")) {
return "bun";
}
if ((0, import_fs.existsSync)("package-lock.json")) {
return "npm";
}
return packageJson?.packageManager?.split("@")[0] || "npm";
}
function withCache(cb) {
let cache = null;
return () => {
if (cache) return cache;
cache = cb();
return cache;
};
}
var getProjectEnv = withCache(() => {
return {
hasVuesticUI: checkModuleExists("vuestic-ui"),
hasTailwindCSS: checkModuleExists("tailwindcss"),
hasTypescript: checkModuleExists("typescript"),
nodeVersion: getNodeVersion(),
packageManager: getPackageManager(),
production: process.env?.NODE_ENV === "production" || import_meta?.env?.PROD
};
});
// dev-warn.ts
var import_chalk = __toESM(require("chalk"), 1);
var primaryColor = (text) => {
return import_chalk.default.hex("#154EC1")(text);
};
function devWarn() {
console.log("");
console.log(import_chalk.default.yellowBright(" Warning:"));
console.log(` You're using ${primaryColor("@vuestic/compiler")}. It is in active development stage.`);
console.log();
console.log(" Make sure to report any issues you encounter.\n");
console.log(` - Dev Docs: ${primaryColor("https://develop.ui.vuestic.dev/")}`);
console.log(` - Discord: ${primaryColor("https://discord.gg/u7fQdqQt8c")}`);
console.log(` - Github: ${primaryColor("https://github.com/epicmaxco/vuestic-ui")}`);
console.log("");
}
// vite-plugin.ts
var defaultOptions = {
devtools: true,
cssLayers: "auto",
autoImport: true,
config: {
configPath: ""
}
};
var vuestic = (options = {}) => {
devWarn();
options = mergeDeep(defaultOptions, options);
const extractOptions = (key) => {
return typeof options[key] === "object" ? options[key] : void 0;
};
const env = getProjectEnv();
if (!env?.hasVuesticUI) {
logger2.error(formatString(`Vuestic UI is not installed in the project. Run [${env.packageManager} install vuestic-ui].`), {
timestamp: true
});
return [];
}
const plugins = [];
if (options.devtools !== false && !env.production) {
logger2.info(formatString("Using [vuestic:devtools] plugin."), {
timestamp: true
});
plugins.push(devtools(extractOptions("devtools")));
}
if (options.cssLayers === "auto" && env.hasTailwindCSS) {
logger2.info(formatString("Using [vuestic:css-layers] plugin, because Tailwind CSS is detected."), {
timestamp: true
});
plugins.push(cssLayers({ tailwind: true }));
} else if (options.cssLayers === true) {
logger2.info(formatString("Using [vuestic:css-layers] plugin."), {
timestamp: true
});
plugins.push(cssLayers({ tailwind: env.hasTailwindCSS }));
}
if (Boolean(options.autoImport)) {
logger2.info(formatString("Using [vuestic:auto-import] plugin."), {
timestamp: true
});
plugins.push(...vuesticAutoImport(extractOptions("autoImport")));
}
if (Boolean(options.config)) {
logger2.info(formatString("Using [vuestic:config] plugin."), {
timestamp: true
});
plugins.push(...vuesticConfig(extractOptions("config")));
}
return plugins;
};
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
vuestic
});
;