feat: docker compose maybe

This commit is contained in:
ash committed 2023-11-13 16:10:04 -05:00
1 parent 180b261e40
commit b625ccd8d6
8031 files changed
+2182966

No files matched your search

+10
View File
@@ -0,0 +1,10 @@
import { Plugin } from 'vite';
import { UserDefinedOptions, ComplexSafelist } from 'purgecss';
type Options = Partial<UserDefinedOptions> & {
safelist?: ComplexSafelist;
};
type PurgeOptions = Omit<Options, 'css'>;
declare function purgeCss(purgeOptions?: PurgeOptions): Plugin;
export { purgeCss as default, purgeCss };
+228
View File
@@ -0,0 +1,228 @@
"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
+1
View File
@@ -0,0 +1 @@
{"version":3,"sources":["../src/index.ts","../src/extractors/regex.ts","../src/extractors/default-extractor.ts"],"names":["pattern","_a"],"mappings":"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","sourcesContent":["import { PurgeCSS } from 'purgecss';\nimport { defaultExtractor } from './extractors/default-extractor';\nimport { walk } from 'estree-walker';\nimport { join } from 'path';\nimport type { ResolvedConfig, Plugin } from 'vite';\nimport type { ComplexSafelist, StringRegExpArray, UserDefinedOptions } from 'purgecss';\n\ntype Extractor = (content: stLine truncated
+228
View File
@@ -0,0 +1,228 @@
// src/index.ts
import { PurgeCSS } from "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, ...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
import { walk } from "estree-walker";
import { join } from "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]+$/,
...((_a = purgeOptions == null ? void 0 : purgeOptions.safelist) == null ? void 0 : _a.standard) ?? []
];
const extractor = (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);
walk(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 = 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 PurgeCSS().purge({
...purgeOptions,
content: [join(viteConfig.root, "**/*.html"), ...(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/, ...((_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;
export {
src_default as default,
purgeCss
};
//# sourceMappingURL=index.mjs.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"sources":["../src/index.ts","../src/extractors/regex.ts","../src/extractors/default-extractor.ts"],"sourcesContent":["import { PurgeCSS } from 'purgecss';\nimport { defaultExtractor } from './extractors/default-extractor';\nimport { walk } from 'estree-walker';\nimport { join } from 'path';\nimport type { ResolvedConfig, Plugin } from 'vite';\nimport type { ComplexSafelist, StringRegExpArray, UserDefinedOptions } from 'purgecss';\n\ntype Extractor = (content: string) => string[];\n\ntype Options = Partial<UserDefinedOptions> & {\n\tsafelist?: ComplexSafelist;\n};\ntype PurgeOptions = Omit<Options, 'css'>;\n\nconst EXT_CSS = /\\.(css)$/;\nconst MAX_STRING_LITERAL_LENGTH = 50_000;\n\nexport function purgeCss(purgeOptions?: PurgeOptions): Plugin {\n\tlet viteConfig: ResolvedConfig;\n\tconst selectors = new Set<string>();\n\tconst standard: StringRegExpArray = [\n\t\t'*',\n\t\t'html',\n\t\t'body',\n\t\t/aria-current/,\n\t\t// fix for pseudo-class functions that begin with `:` getting purged (e.g. `:is`)\n\t\t// see: https://github.com/FullHuman/purgecss/issues/978\n\t\t/^\\:[-a-z]+$/,\n\t\t...(purgeOptions?.safelist?.standard ?? []),\n\t];\n\tconst extractor = (purgeOptions?.defaultExtractor as Extractor) ?? defaultExtractor();\n\tconst moduleIds = new Set<string>();\n\n\treturn {\n\t\tname: 'vite-plugin-tailwind-purgecss',\n\t\tapply: 'build',\n\t\tenforce: 'post',\n\n\t\tload(id) {\n\t\t\tif (EXT_CSS.test(id)) return;\n\t\t\tmoduleIds.add(id);\n\t\t},\n\n\t\tconfigResolved(config) {\n\t\t\tviteConfig = config;\n\t\t},\n\n\t\tasync generateBundle(options, bundle) {\n\t\t\ttype ChunkOrAsset = (typeof bundle)[string];\n\t\t\ttype Asset = Extract<ChunkOrAsset, { type: 'asset' }>;\n\t\t\tconst assets: Record<string, Asset> = {};\n\n\t\t\tfor (const id of moduleIds) {\n\t\t\t\tconst info = this.getModuleInfo(id);\n\t\t\t\tif (info?.isIncluded !== true || info.code === null) continue;\n\n\t\t\t\tconst ast = this.parse(info.code);\n\n\t\t\t\t// @ts-expect-error mismatched node types\n\t\t\t\twalk(ast, {\n\t\t\t\t\tenter(node, parent, key, index) {\n\t\t\t\t\t\tif (node.type === 'Literal' && typeof node.value === 'string') {\n\t\t\t\t\t\t\tnode.value.split(/\\s+/).forEach((word) => {\n\t\t\t\t\t\t\t\tif (word.length < MAX_STRING_LITERAL_LENGTH) {\n\t\t\t\t\t\t\t\t\textractor(word).forEach((selector) => selectors.add(selector));\n\t\t\t\t\t\t\t\t} else selectors.add(word);\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (node.type === 'Identifier') {\n\t\t\t\t\t\t\tselectors.add(node.name);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (node.type === 'TemplateElement') {\n\t\t\t\t\t\t\tconst value = node.value.cooked ?? node.value.raw;\n\t\t\t\t\t\t\tvalue.split(/\\s+/).forEach((word) => {\n\t\t\t\t\t\t\t\tif (word.length < MAX_STRING_LITERAL_LENGTH) {\n\t\t\t\t\t\t\t\t\textractor(word).forEach((selector) => selectors.add(selector));\n\t\t\t\t\t\t\t\t} else selectors.add(word);\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t}\n\t\t\t\t\t},\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tfor (const [fileName, chunkOrAsset] of Object.entries(bundle)) {\n\t\t\t\tif (chunkOrAsset.type === 'asset' && EXT_CSS.test(fileName)) {\n\t\t\t\t\tassets[fileName] = chunkOrAsset;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tfor (const selector of selectors) {\n\t\t\t\tstandard.push(selector);\n\t\t\t}\n\n\t\t\tfor (const [fileName, asset] of Object.entries(assets)) {\n\t\t\t\tconst purgeCSSResult = await new PurgeCSS().purge({\n\t\t\t\t\t...purgeOptions,\n\t\t\t\t\tcontent: [join(viteConfig.root, '**/*.html'), ...(purgeOptions?.content ?? [])],\n\t\t\t\t\tcss: [{ raw: (asset.source as string).trim(), name: fileName }],\n\t\t\t\t\trejected: true,\n\t\t\t\t\trejectedCss: true,\n\t\t\t\t\tsafelist: {\n\t\t\t\t\t\t...purgeOptions?.safelist,\n\t\t\t\t\t\tstandard,\n\t\t\t\t\t\tgreedy: [/svelte-/, /data-theme/, ...(purgeOptions?.safelist?.greedy ?? [])],\n\t\t\t\t\t},\n\t\t\t\t});\n\n\t\t\t\tif (purgeCSSResult[0]) {\n\t\t\t\t\t// prevent the original from being written\n\t\t\t\t\tdelete bundle[asset.fileName];\n\n\t\t\t\t\t// emit the newly purged css file\n\t\t\t\t\tthis.emitFile({\n\t\t\t\t\t\t...asset,\n\t\t\t\t\t\ttype: 'asset',\n\t\t\t\t\t\tsource: purgeCSSResult[0].css,\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t};\n}\n\nexport default purgeCss;\n","const REGEX_SPECIAL = /[\\\\^$.*+?()[\\]{}|]/g;\nconst REGEX_HAS_SPECIAL = RegExp(REGEX_SPECIAL.source);\n\nfunction toSource(source: string | RegExp | Array<string | RegExp>) {\n\tsource = Array.isArray(source) ? source : [source];\n\n\tsource = source.map((item) => (item instanceof RegExp ? item.source : item));\n\n\treturn source.join('');\n}\n\nexport function pattern(source: string | RegExp | Array<string | RegExp>) {\n\treturn new RegExp(toSource(source), 'g');\n}\n\nexport function withoutCapturing(source: string | RegExp | Array<string | RegExp>) {\n\treturn new RegExp(`(?:${toSource(source)})`, 'g');\n}\n\nexport function any(sources: Array<string | RegExp>) {\n\treturn `(?:${sources.map(toSource).join('|')})`;\n}\n\nexporLine truncated