'use strict'; const promises = require('node:fs/promises'); const node_path = require('node:path'); const fg = require('fast-glob'); const postcss = require('postcss'); const core = require('@unocss/core'); const config = require('@unocss/config'); const cssTree = require('css-tree'); const MagicString = require('magic-string'); function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e["default"] : e; } const fg__default = /*#__PURE__*/_interopDefaultLegacy(fg); const postcss__default = /*#__PURE__*/_interopDefaultLegacy(postcss); const MagicString__default = /*#__PURE__*/_interopDefaultLegacy(MagicString); const defaultIncludeGlobs = ["**/*.{html,js,ts,jsx,tsx,vue,svelte,astro,elm,php,phtml,mdx,md}"]; async function parseApply(root, uno, directiveName) { root.walkAtRules(directiveName, async (rule) => { if (!rule.parent) return; const source = rule.source; const classNames = core.expandVariantGroup(rule.params).split(/\s+/g).map((className) => className.trim().replace(/\\/, "")); const utils = (await Promise.all( classNames.map((i) => uno.parseToken(i, "-")) )).filter(core.notNull).flat().sort((a, b) => a[0] - b[0]).sort((a, b) => (a[3] ? uno.parentOrders.get(a[3]) ?? 0 : 0) - (b[3] ? uno.parentOrders.get(b[3]) ?? 0 : 0)).reduce((acc, item) => { const target = acc.find((i) => i[1] === item[1] && i[3] === item[3]); if (target) target[2] += item[2]; else acc.push([...item]); return acc; }, []); if (!utils.length) return; for (const i of utils) { const [, _selector, body, parent] = i; const selector = _selector?.replace(core.regexScopePlaceholder, " ") || _selector; if (parent || selector && selector !== ".\\-") { const node = cssTree.parse(rule.parent.toString(), { context: "rule" }); let newSelector = cssTree.generate(node.prelude); if (selector && selector !== ".\\-") { const selectorAST = cssTree.parse(selector, { context: "selector" }); const prelude = cssTree.clone(node.prelude); prelude.children.forEach((child) => { const parentSelectorAst = cssTree.clone(selectorAST); parentSelectorAst.children.forEach((i2) => { if (i2.type === "ClassSelector" && i2.name === "\\-") Object.assign(i2, cssTree.clone(child)); }); Object.assign(child, parentSelectorAst); }); newSelector = cssTree.generate(prelude); } let css = `${newSelector}{${body}}`; if (parent) css = `${parent}{${css}}`; const css_parsed = postcss__default.parse(css); css_parsed.walkDecls((declaration) => { declaration.source = source; }); rule.parent.after(css_parsed); } else { const css = postcss__default.parse(body); css.walkDecls((declaration) => { declaration.source = source; }); rule.parent.append(css); } } rule.remove(); }); } function themeFnRE(directiveName) { return new RegExp(`${directiveName}\\((.*?)\\)`, "g"); } async function parseTheme(root, uno, directiveName) { root.walkDecls((decl) => { const matches = Array.from(decl.value.matchAll(themeFnRE(directiveName))); if (!matches.length) return; for (const match of matches) { const rawArg = match[1].trim(); if (!rawArg) throw new Error(`${directiveName}() expect exact one argument, but got 0`); let value = uno.config.theme; const keys = rawArg.slice(1, -1).split("."); keys.every((key) => { if (value[key] != null) value = value[key]; else if (value[+key] != null) value = value[+key]; else return false; return true; }); if (typeof value === "string") { const code = new MagicString__default(decl.value); code.overwrite( match.index, match.index + match[0].length, value ); decl.value = code.toString(); } } }); } async function parseScreen(root, uno, directiveName) { root.walkAtRules(directiveName, async (rule) => { let breakpointName = ""; let prefix = ""; if (rule.params) breakpointName = rule.params.trim(); if (!breakpointName) return; const match = breakpointName.match(/^(?:(lt|at)-)?(\w+)$/); if (match) { prefix = match[1]; breakpointName = match[2]; } const resolveBreakpoints = () => { let breakpoints; if (uno.userConfig && uno.userConfig.theme) breakpoints = uno.userConfig.theme.breakpoints; if (!breakpoints) breakpoints = uno.config.theme.breakpoints; return breakpoints; }; const variantEntries = Object.entries(resolveBreakpoints() ?? {}).map(([point, size], idx) => [point, size, idx]); const generateMediaQuery = (breakpointName2, prefix2) => { const [, size, idx] = variantEntries.find((i) => i[0] === breakpointName2); if (prefix2) { if (prefix2 === "lt") return `(max-width: ${calcMaxWidthBySize(size)})`; else if (prefix2 === "at") return `(min-width: ${size})${variantEntries[idx + 1] ? ` and (max-width: ${calcMaxWidthBySize(variantEntries[idx + 1][1])})` : ""}`; else throw new Error(`breakpoint variant not supported: ${prefix2}`); } return `(min-width: ${size})`; }; if (!variantEntries.find((i) => i[0] === breakpointName)) throw new Error(`breakpoint ${breakpointName} not found`); rule.name = "media"; rule.params = `${generateMediaQuery(breakpointName, prefix)}`; }); } function calcMaxWidthBySize(size) { const value = size.match(/^-?[0-9]+\.?[0-9]*/)?.[0] || ""; const unit = size.slice(value.length); const maxWidth = parseFloat(value) - 0.1; return Number.isNaN(maxWidth) ? size : `${maxWidth}${unit}`; } function unocss(options = {}) { core.warnOnce( "`@unocss/postcss` package is in an experimental state right now. It doesn't follow semver, and may introduce breaking changes in patch versions." ); const { cwd = process.cwd(), content, configOrPath } = options; const directiveMap = Object.assign({ apply: "apply", theme: "theme", screen: "screen", unocss: "unocss" }, options.directiveMap || {}); const fileMap = /* @__PURE__ */ new Map(); const fileClassMap = /* @__PURE__ */ new Map(); const classes = /* @__PURE__ */ new Set(); const targetCache = /* @__PURE__ */ new Set(); const config$1 = config.loadConfig(cwd, configOrPath); let uno; let promises$1 = []; let last_config_mtime = 0; const targetRE = new RegExp(Object.values(directiveMap).join("|")); return { postcssPlugin: directiveMap.unocss, plugins: [ async function(root, result) { const from = result.opts.from?.split("?")[0]; if (!from) return; let isTarget = targetCache.has(from); const isScanTarget = root.toString().includes(`@${directiveMap.unocss}`); if (targetRE.test(root.toString())) { if (!isTarget) { root.walkAtRules((rule) => { if (rule.name === directiveMap.unocss || rule.name === directiveMap.apply || rule.name === directiveMap.screen) isTarget = true; if (isTarget) return false; }); if (!isTarget) { const themeFn = themeFnRE(directiveMap.theme); root.walkDecls((decl) => { if (themeFn.test(decl.value)) { isTarget = true; return false; } }); } else { targetCache.add(from); } } } else if (targetCache.has(from)) { targetCache.delete(from); } if (!isTarget) return; try { const cfg = await config$1; if (!uno) { uno = core.createGenerator(cfg.config); } else if (cfg.sources.length) { const config_mtime = (await promises.stat(cfg.sources[0])).mtimeMs; if (config_mtime > last_config_mtime) { uno = core.createGenerator((await config.loadConfig(cwd, configOrPath)).config); last_config_mtime = config_mtime; } } } catch (error) { throw new Error(`UnoCSS config not found: ${error.message}`); } const globs = content?.filter((v) => typeof v === "string") ?? defaultIncludeGlobs; const rawContent = content?.filter((v) => typeof v === "object") ?? []; const entries = await fg__default(isScanTarget ? globs : from, { cwd, dot: true, absolute: true, ignore: ["**/{.git,node_modules}/**"], stats: true }); await parseApply(root, uno, directiveMap.apply); await parseTheme(root, uno, directiveMap.theme); await parseScreen(root, uno, directiveMap.screen); promises$1.push( ...rawContent.map(async (v) => { const { matched } = await uno.generate(v.raw, { id: `unocss.${v.extension}` }); for (const candidate of matched) classes.add(candidate); }), ...entries.map(async ({ path: file, mtimeMs }) => { result.messages.push({ type: "dependency", plugin: directiveMap.unocss, file: node_path.normalize(file), parent: from }); if (fileMap.has(file) && mtimeMs <= fileMap.get(file)) return; else fileMap.set(file, mtimeMs); const content2 = await promises.readFile(file, "utf8"); const { matched } = await uno.generate(content2, { id: file }); fileClassMap.set(file, matched); }) ); await Promise.all(promises$1); promises$1 = []; for (const set of fileClassMap.values()) { for (const candidate of set) classes.add(candidate); } const c = await uno.generate(classes); classes.clear(); const excludes = []; root.walkAtRules(directiveMap.unocss, (rule) => { if (rule.params) { const source = rule.source; const layers = rule.params.split(",").map((v) => v.trim()); const css = postcss__default.parse( layers.map((i) => (i === "all" ? c.getLayers() : c.getLayer(i)) || "").filter(Boolean).join("\n") ); css.walkDecls((declaration) => { declaration.source = source; }); rule.replaceWith(css); excludes.push(rule.params); } }); root.walkAtRules(directiveMap.unocss, (rule) => { if (!rule.params) { const source = rule.source; const css = postcss__default.parse(c.getLayers(void 0, excludes) || ""); css.walkDecls((declaration) => { declaration.source = source; }); rule.replaceWith(css); } }); } ] }; } unocss.postcss = true; unocss.default = unocss; module.exports = unocss;