"use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } }// src/index.ts var _purgecss = require('purgecss'); // src/extractors/regex.ts var REGEX_SPECIAL = /[\\^$.*+?()[\]{}|]/g; var REGEX_HAS_SPECIAL = RegExp(REGEX_SPECIAL.source); function toSource(source) { source = Array.isArray(source) ? source : [source]; source = source.map((item) => item instanceof RegExp ? item.source : item); return source.join(""); } function pattern(source) { return new RegExp(toSource(source), "g"); } function any(sources) { return `(?:${sources.map(toSource).join("|")})`; } function optional(source) { return `(?:${toSource(source)})?`; } // src/extractors/default-extractor.ts function defaultExtractor() { let patterns = Array.from(buildRegExps()); return (content) => { let results = []; for (let pattern2 of patterns) { results = [...results, ..._nullishCoalesce(content.match(pattern2), () => ( []))]; } return results.filter((v) => v !== void 0).map(clipAtBalancedParens); }; } function* buildRegExps() { let separator = ":"; let prefix = ""; let utility = any([ /\[[^\s:'"`]+:[^\s\[\]]+\]/, /\[[^\s:'"`]+:[^\s]+?\[[^\s]+\][^\s]+?\]/, pattern([ /-?(?:\w+)/, optional( any([ pattern([ /-(?:\w+-)*\[[^\s:]+\]/, /(?![{([]])/, /(?:\/[^\s'"`\\><$]*)?/ ]), pattern([ /-(?:\w+-)*\[[^\s]+\]/, /(?![{([]])/, /(?:\/[^\s'"`\\$]*)?/ ]), /[-\/][^\s'"`\\$={><]*/ ]) ) ]) ]); let variantPatterns = [ any([ pattern([/@\[[^\s"'`]+\](\/[^\s"'`]+)?/, separator]), pattern([/([^\s"'`\[\\]+-)?\[[^\s"'`]+\]/, separator]), pattern([/[^\s"'`\[\\]+/, separator]) ]), any([ pattern([/([^\s"'`\[\\]+-)?\[[^\s`]+\]/, separator]), pattern([/[^\s`\[\\]+/, separator]) ]) ]; for (const variantPattern of variantPatterns) { yield pattern([ "((?=((", variantPattern, ")+))\\2)?", /!?/, prefix, utility ]); } yield /[^<>"'`\s.(){}[\]#=%$]*[^<>"'`\s.(){}[\]#=%:$]/g; } var SPECIALS = /([\[\]'"`])([^\[\]'"`])?/g; var ALLOWED_CLASS_CHARACTERS = /[^"'`\s<>\]]+/; function clipAtBalancedParens(input) { if (!input.includes("-[")) { return input; } let depth = 0; let openStringTypes = []; let matches = input.matchAll(SPECIALS); const matched = Array.from(matches).flatMap((match) => { const [, ...groups] = match; return groups.map( (group, idx) => Object.assign([], match, { index: match.index + idx, 0: group }) ); }); for (let match of matched) { let char = match[0]; let inStringType = openStringTypes.at(-1); if (char === inStringType) { openStringTypes.pop(); } else if (char === "'" || char === '"' || char === "`") { openStringTypes.push(char); } if (inStringType) { continue; } else if (char === "[") { depth++; continue; } else if (char === "]") { depth--; continue; } if (depth < 0) { return input.substring(0, match.index - 1); } if (depth === 0 && !ALLOWED_CLASS_CHARACTERS.test(char)) { return input.substring(0, match.index); } } return input; } // src/index.ts var _estreewalker = require('estree-walker'); var _path = require('path'); var EXT_CSS = /\.(css)$/; var MAX_STRING_LITERAL_LENGTH = 5e4; function purgeCss(purgeOptions) { var _a; let viteConfig; const selectors = /* @__PURE__ */ new Set(); const standard = [ "*", "html", "body", /aria-current/, /^\:[-a-z]+$/, ..._nullishCoalesce(((_a = purgeOptions == null ? void 0 : purgeOptions.safelist) == null ? void 0 : _a.standard), () => ( [])) ]; const extractor = _nullishCoalesce((purgeOptions == null ? void 0 : purgeOptions.defaultExtractor), () => ( defaultExtractor())); const moduleIds = /* @__PURE__ */ new Set(); return { name: "vite-plugin-tailwind-purgecss", apply: "build", enforce: "post", load(id) { if (EXT_CSS.test(id)) return; moduleIds.add(id); }, configResolved(config) { viteConfig = config; }, async generateBundle(options, bundle) { var _a2; const assets = {}; for (const id of moduleIds) { const info = this.getModuleInfo(id); if ((info == null ? void 0 : info.isIncluded) !== true || info.code === null) continue; const ast = this.parse(info.code); _estreewalker.walk.call(void 0, ast, { enter(node, parent, key, index) { if (node.type === "Literal" && typeof node.value === "string") { node.value.split(/\s+/).forEach((word) => { if (word.length < MAX_STRING_LITERAL_LENGTH) { extractor(word).forEach((selector) => selectors.add(selector)); } else selectors.add(word); }); } if (node.type === "Identifier") { selectors.add(node.name); } if (node.type === "TemplateElement") { const value = _nullishCoalesce(node.value.cooked, () => ( node.value.raw)); value.split(/\s+/).forEach((word) => { if (word.length < MAX_STRING_LITERAL_LENGTH) { extractor(word).forEach((selector) => selectors.add(selector)); } else selectors.add(word); }); } } }); } for (const [fileName, chunkOrAsset] of Object.entries(bundle)) { if (chunkOrAsset.type === "asset" && EXT_CSS.test(fileName)) { assets[fileName] = chunkOrAsset; } } for (const selector of selectors) { standard.push(selector); } for (const [fileName, asset] of Object.entries(assets)) { const purgeCSSResult = await new (0, _purgecss.PurgeCSS)().purge({ ...purgeOptions, content: [_path.join.call(void 0, viteConfig.root, "**/*.html"), ..._nullishCoalesce((purgeOptions == null ? void 0 : purgeOptions.content), () => ( []))], css: [{ raw: asset.source.trim(), name: fileName }], rejected: true, rejectedCss: true, safelist: { ...purgeOptions == null ? void 0 : purgeOptions.safelist, standard, greedy: [/svelte-/, /data-theme/, ..._nullishCoalesce(((_a2 = purgeOptions == null ? void 0 : purgeOptions.safelist) == null ? void 0 : _a2.greedy), () => ( []))] } }); if (purgeCSSResult[0]) { delete bundle[asset.fileName]; this.emitFile({ ...asset, type: "asset", source: purgeCSSResult[0].css }); } } } }; } var src_default = purgeCss; exports.default = src_default; exports.purgeCss = purgeCss; //# sourceMappingURL=index.js.map