summaryrefslogtreecommitdiff
path: root/node_modules/tailwindcss/lib/cli
diff options
context:
space:
mode:
authorPhilipp Tanlak <philipp.tanlak@gmail.com>2025-11-24 20:54:57 +0100
committerPhilipp Tanlak <philipp.tanlak@gmail.com>2025-11-24 20:57:48 +0100
commitb1e2c8fd5cb5dfa46bc440a12eafaf56cd844b1c (patch)
tree49d360fd6cbc6a2754efe93524ac47ff0fbe0f7d /node_modules/tailwindcss/lib/cli
Docs
Diffstat (limited to 'node_modules/tailwindcss/lib/cli')
-rw-r--r--node_modules/tailwindcss/lib/cli/build/deps.js62
-rw-r--r--node_modules/tailwindcss/lib/cli/build/index.js54
-rw-r--r--node_modules/tailwindcss/lib/cli/build/plugin.js378
-rw-r--r--node_modules/tailwindcss/lib/cli/build/utils.js88
-rw-r--r--node_modules/tailwindcss/lib/cli/build/watching.js182
-rw-r--r--node_modules/tailwindcss/lib/cli/help/index.js73
-rw-r--r--node_modules/tailwindcss/lib/cli/index.js230
-rw-r--r--node_modules/tailwindcss/lib/cli/init/index.js63
8 files changed, 1130 insertions, 0 deletions
diff --git a/node_modules/tailwindcss/lib/cli/build/deps.js b/node_modules/tailwindcss/lib/cli/build/deps.js
new file mode 100644
index 0000000..1aa8116
--- /dev/null
+++ b/node_modules/tailwindcss/lib/cli/build/deps.js
@@ -0,0 +1,62 @@
+// @ts-check
+"use strict";
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+function _export(target, all) {
+ for(var name in all)Object.defineProperty(target, name, {
+ enumerable: true,
+ get: all[name]
+ });
+}
+_export(exports, {
+ loadPostcss: function() {
+ return loadPostcss;
+ },
+ loadPostcssImport: function() {
+ return loadPostcssImport;
+ },
+ loadCssNano: function() {
+ return loadCssNano;
+ },
+ loadAutoprefixer: function() {
+ return loadAutoprefixer;
+ }
+});
+const _index = require("../../../peers/index.js");
+function loadPostcss() {
+ // Try to load a local `postcss` version first
+ try {
+ return require("postcss");
+ } catch {}
+ return (0, _index.lazyPostcss)();
+}
+function loadPostcssImport() {
+ // Try to load a local `postcss-import` version first
+ try {
+ return require("postcss-import");
+ } catch {}
+ return (0, _index.lazyPostcssImport)();
+}
+function loadCssNano() {
+ let options = {
+ preset: [
+ "default",
+ {
+ cssDeclarationSorter: false
+ }
+ ]
+ };
+ // Try to load a local `cssnano` version first
+ try {
+ return require("cssnano");
+ } catch {}
+ return (0, _index.lazyCssnano)()(options);
+}
+function loadAutoprefixer() {
+ // Try to load a local `autoprefixer` version first
+ try {
+ return require("autoprefixer");
+ } catch {}
+ return (0, _index.lazyAutoprefixer)();
+}
diff --git a/node_modules/tailwindcss/lib/cli/build/index.js b/node_modules/tailwindcss/lib/cli/build/index.js
new file mode 100644
index 0000000..60304f6
--- /dev/null
+++ b/node_modules/tailwindcss/lib/cli/build/index.js
@@ -0,0 +1,54 @@
+// @ts-check
+"use strict";
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+Object.defineProperty(exports, "build", {
+ enumerable: true,
+ get: function() {
+ return build;
+ }
+});
+const _fs = /*#__PURE__*/ _interop_require_default(require("fs"));
+const _path = /*#__PURE__*/ _interop_require_default(require("path"));
+const _resolveConfigPath = require("../../util/resolveConfigPath.js");
+const _plugin = require("./plugin.js");
+function _interop_require_default(obj) {
+ return obj && obj.__esModule ? obj : {
+ default: obj
+ };
+}
+async function build(args) {
+ let input = args["--input"];
+ let shouldWatch = args["--watch"];
+ // TODO: Deprecate this in future versions
+ if (!input && args["_"][1]) {
+ console.error("[deprecation] Running tailwindcss without -i, please provide an input file.");
+ input = args["--input"] = args["_"][1];
+ }
+ if (input && input !== "-" && !_fs.default.existsSync(input = _path.default.resolve(input))) {
+ console.error(`Specified input file ${args["--input"]} does not exist.`);
+ process.exit(9);
+ }
+ if (args["--config"] && !_fs.default.existsSync(args["--config"] = _path.default.resolve(args["--config"]))) {
+ console.error(`Specified config file ${args["--config"]} does not exist.`);
+ process.exit(9);
+ }
+ // TODO: Reference the @config path here if exists
+ let configPath = args["--config"] ? args["--config"] : (0, _resolveConfigPath.resolveDefaultConfigPath)();
+ let processor = await (0, _plugin.createProcessor)(args, configPath);
+ if (shouldWatch) {
+ // Abort the watcher if stdin is closed to avoid zombie processes
+ // You can disable this behavior with --watch=always
+ if (args["--watch"] !== "always") {
+ process.stdin.on("end", ()=>process.exit(0));
+ }
+ process.stdin.resume();
+ await processor.watch();
+ } else {
+ await processor.build().catch((e)=>{
+ console.error(e);
+ process.exit(1);
+ });
+ }
+}
diff --git a/node_modules/tailwindcss/lib/cli/build/plugin.js b/node_modules/tailwindcss/lib/cli/build/plugin.js
new file mode 100644
index 0000000..22a539f
--- /dev/null
+++ b/node_modules/tailwindcss/lib/cli/build/plugin.js
@@ -0,0 +1,378 @@
+// @ts-check
+"use strict";
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+Object.defineProperty(exports, "createProcessor", {
+ enumerable: true,
+ get: function() {
+ return createProcessor;
+ }
+});
+const _path = /*#__PURE__*/ _interop_require_default(require("path"));
+const _fs = /*#__PURE__*/ _interop_require_default(require("fs"));
+const _postcssloadconfig = /*#__PURE__*/ _interop_require_default(require("postcss-load-config"));
+const _lilconfig = require("lilconfig");
+const _plugins = /*#__PURE__*/ _interop_require_default(require("postcss-load-config/src/plugins" // Little bit scary, looking at private/internal API
+));
+const _options = /*#__PURE__*/ _interop_require_default(require("postcss-load-config/src/options" // Little bit scary, looking at private/internal API
+));
+const _processTailwindFeatures = /*#__PURE__*/ _interop_require_default(require("../../processTailwindFeatures"));
+const _deps = require("./deps");
+const _utils = require("./utils");
+const _sharedState = require("../../lib/sharedState");
+const _resolveConfig = /*#__PURE__*/ _interop_require_default(require("../../../resolveConfig.js"));
+const _content = require("../../lib/content.js");
+const _watching = require("./watching.js");
+const _fastglob = /*#__PURE__*/ _interop_require_default(require("fast-glob"));
+const _findAtConfigPath = require("../../lib/findAtConfigPath.js");
+const _log = /*#__PURE__*/ _interop_require_default(require("../../util/log"));
+const _loadconfig = require("../../lib/load-config");
+const _getModuleDependencies = /*#__PURE__*/ _interop_require_default(require("../../lib/getModuleDependencies"));
+function _interop_require_default(obj) {
+ return obj && obj.__esModule ? obj : {
+ default: obj
+ };
+}
+/**
+ *
+ * @param {string} [customPostCssPath ]
+ * @returns
+ */ async function loadPostCssPlugins(customPostCssPath) {
+ let config = customPostCssPath ? await (async ()=>{
+ let file = _path.default.resolve(customPostCssPath);
+ // Implementation, see: https://unpkg.com/browse/postcss-load-config@3.1.0/src/index.js
+ // @ts-ignore
+ let { config ={} } = await (0, _lilconfig.lilconfig)("postcss").load(file);
+ if (typeof config === "function") {
+ config = config();
+ } else {
+ config = Object.assign({}, config);
+ }
+ if (!config.plugins) {
+ config.plugins = [];
+ }
+ return {
+ file,
+ plugins: (0, _plugins.default)(config, file),
+ options: (0, _options.default)(config, file)
+ };
+ })() : await (0, _postcssloadconfig.default)();
+ let configPlugins = config.plugins;
+ let configPluginTailwindIdx = configPlugins.findIndex((plugin)=>{
+ if (typeof plugin === "function" && plugin.name === "tailwindcss") {
+ return true;
+ }
+ if (typeof plugin === "object" && plugin !== null && plugin.postcssPlugin === "tailwindcss") {
+ return true;
+ }
+ return false;
+ });
+ let beforePlugins = configPluginTailwindIdx === -1 ? [] : configPlugins.slice(0, configPluginTailwindIdx);
+ let afterPlugins = configPluginTailwindIdx === -1 ? configPlugins : configPlugins.slice(configPluginTailwindIdx + 1);
+ return [
+ beforePlugins,
+ afterPlugins,
+ config.options
+ ];
+}
+function loadBuiltinPostcssPlugins() {
+ let postcss = (0, _deps.loadPostcss)();
+ let IMPORT_COMMENT = "__TAILWIND_RESTORE_IMPORT__: ";
+ return [
+ [
+ (root)=>{
+ root.walkAtRules("import", (rule)=>{
+ if (rule.params.slice(1).startsWith("tailwindcss/")) {
+ rule.after(postcss.comment({
+ text: IMPORT_COMMENT + rule.params
+ }));
+ rule.remove();
+ }
+ });
+ },
+ (0, _deps.loadPostcssImport)(),
+ (root)=>{
+ root.walkComments((rule)=>{
+ if (rule.text.startsWith(IMPORT_COMMENT)) {
+ rule.after(postcss.atRule({
+ name: "import",
+ params: rule.text.replace(IMPORT_COMMENT, "")
+ }));
+ rule.remove();
+ }
+ });
+ }
+ ],
+ [],
+ {}
+ ];
+}
+let state = {
+ /** @type {any} */ context: null,
+ /** @type {ReturnType<typeof createWatcher> | null} */ watcher: null,
+ /** @type {{content: string, extension: string}[]} */ changedContent: [],
+ /** @type {ReturnType<typeof load> | null} */ configBag: null,
+ contextDependencies: new Set(),
+ /** @type {import('../../lib/content.js').ContentPath[]} */ contentPaths: [],
+ refreshContentPaths () {
+ var _this_context;
+ this.contentPaths = (0, _content.parseCandidateFiles)(this.context, (_this_context = this.context) === null || _this_context === void 0 ? void 0 : _this_context.tailwindConfig);
+ },
+ get config () {
+ return this.context.tailwindConfig;
+ },
+ get contentPatterns () {
+ return {
+ all: this.contentPaths.map((contentPath)=>contentPath.pattern),
+ dynamic: this.contentPaths.filter((contentPath)=>contentPath.glob !== undefined).map((contentPath)=>contentPath.pattern)
+ };
+ },
+ loadConfig (configPath, content) {
+ if (this.watcher && configPath) {
+ this.refreshConfigDependencies();
+ }
+ let config = (0, _loadconfig.loadConfig)(configPath);
+ let dependencies = (0, _getModuleDependencies.default)(configPath);
+ this.configBag = {
+ config,
+ dependencies,
+ dispose () {
+ for (let file of dependencies){
+ delete require.cache[require.resolve(file)];
+ }
+ }
+ };
+ // @ts-ignore
+ this.configBag.config = (0, _resolveConfig.default)(this.configBag.config, {
+ content: {
+ files: []
+ }
+ });
+ // Override content files if `--content` has been passed explicitly
+ if ((content === null || content === void 0 ? void 0 : content.length) > 0) {
+ this.configBag.config.content.files = content;
+ }
+ return this.configBag.config;
+ },
+ refreshConfigDependencies () {
+ var _this_configBag;
+ _sharedState.env.DEBUG && console.time("Module dependencies");
+ (_this_configBag = this.configBag) === null || _this_configBag === void 0 ? void 0 : _this_configBag.dispose();
+ _sharedState.env.DEBUG && console.timeEnd("Module dependencies");
+ },
+ readContentPaths () {
+ let content = [];
+ // Resolve globs from the content config
+ // TODO: When we make the postcss plugin async-capable this can become async
+ let files = _fastglob.default.sync(this.contentPatterns.all);
+ for (let file of files){
+ if (false) {
+ content.push({
+ file,
+ extension: _path.default.extname(file).slice(1)
+ });
+ } else {
+ content.push({
+ content: _fs.default.readFileSync(_path.default.resolve(file), "utf8"),
+ extension: _path.default.extname(file).slice(1)
+ });
+ }
+ }
+ // Resolve raw content in the tailwind config
+ let rawContent = this.config.content.files.filter((file)=>{
+ return file !== null && typeof file === "object";
+ });
+ for (let { raw: htmlContent , extension ="html" } of rawContent){
+ content.push({
+ content: htmlContent,
+ extension
+ });
+ }
+ return content;
+ },
+ getContext ({ createContext , cliConfigPath , root , result , content }) {
+ if (this.context) {
+ this.context.changedContent = this.changedContent.splice(0);
+ return this.context;
+ }
+ _sharedState.env.DEBUG && console.time("Searching for config");
+ var _findAtConfigPath1;
+ let configPath = (_findAtConfigPath1 = (0, _findAtConfigPath.findAtConfigPath)(root, result)) !== null && _findAtConfigPath1 !== void 0 ? _findAtConfigPath1 : cliConfigPath;
+ _sharedState.env.DEBUG && console.timeEnd("Searching for config");
+ _sharedState.env.DEBUG && console.time("Loading config");
+ let config = this.loadConfig(configPath, content);
+ _sharedState.env.DEBUG && console.timeEnd("Loading config");
+ _sharedState.env.DEBUG && console.time("Creating context");
+ this.context = createContext(config, []);
+ Object.assign(this.context, {
+ userConfigPath: configPath
+ });
+ _sharedState.env.DEBUG && console.timeEnd("Creating context");
+ _sharedState.env.DEBUG && console.time("Resolving content paths");
+ this.refreshContentPaths();
+ _sharedState.env.DEBUG && console.timeEnd("Resolving content paths");
+ if (this.watcher) {
+ _sharedState.env.DEBUG && console.time("Watch new files");
+ this.watcher.refreshWatchedFiles();
+ _sharedState.env.DEBUG && console.timeEnd("Watch new files");
+ }
+ for (let file of this.readContentPaths()){
+ this.context.changedContent.push(file);
+ }
+ return this.context;
+ }
+};
+async function createProcessor(args, cliConfigPath) {
+ var _args_content;
+ let postcss = (0, _deps.loadPostcss)();
+ let input = args["--input"];
+ let output = args["--output"];
+ let includePostCss = args["--postcss"];
+ let customPostCssPath = typeof args["--postcss"] === "string" ? args["--postcss"] : undefined;
+ let [beforePlugins, afterPlugins, postcssOptions] = includePostCss ? await loadPostCssPlugins(customPostCssPath) : loadBuiltinPostcssPlugins();
+ if (args["--purge"]) {
+ _log.default.warn("purge-flag-deprecated", [
+ "The `--purge` flag has been deprecated.",
+ "Please use `--content` instead."
+ ]);
+ if (!args["--content"]) {
+ args["--content"] = args["--purge"];
+ }
+ }
+ var _args_content_split;
+ let content = (_args_content_split = (_args_content = args["--content"]) === null || _args_content === void 0 ? void 0 : _args_content.split(/(?<!{[^}]+),/)) !== null && _args_content_split !== void 0 ? _args_content_split : [];
+ let tailwindPlugin = ()=>{
+ return {
+ postcssPlugin: "tailwindcss",
+ async Once (root, { result }) {
+ _sharedState.env.DEBUG && console.time("Compiling CSS");
+ await (0, _processTailwindFeatures.default)(({ createContext })=>{
+ console.error();
+ console.error("Rebuilding...");
+ return ()=>{
+ return state.getContext({
+ createContext,
+ cliConfigPath,
+ root,
+ result,
+ content
+ });
+ };
+ })(root, result);
+ _sharedState.env.DEBUG && console.timeEnd("Compiling CSS");
+ }
+ };
+ };
+ tailwindPlugin.postcss = true;
+ let plugins = [
+ ...beforePlugins,
+ tailwindPlugin,
+ !args["--minify"] && _utils.formatNodes,
+ ...afterPlugins,
+ !args["--no-autoprefixer"] && (0, _deps.loadAutoprefixer)(),
+ args["--minify"] && (0, _deps.loadCssNano)()
+ ].filter(Boolean);
+ /** @type {import('postcss').Processor} */ // @ts-ignore
+ let processor = postcss(plugins);
+ async function readInput() {
+ // Piping in data, let's drain the stdin
+ if (input === "-") {
+ return (0, _utils.drainStdin)();
+ }
+ // Input file has been provided
+ if (input) {
+ return _fs.default.promises.readFile(_path.default.resolve(input), "utf8");
+ }
+ // No input file provided, fallback to default atrules
+ return "@tailwind base; @tailwind components; @tailwind utilities";
+ }
+ async function build() {
+ let start = process.hrtime.bigint();
+ return readInput().then((css)=>processor.process(css, {
+ ...postcssOptions,
+ from: input,
+ to: output
+ })).then((result)=>{
+ if (!state.watcher) {
+ return result;
+ }
+ _sharedState.env.DEBUG && console.time("Recording PostCSS dependencies");
+ for (let message of result.messages){
+ if (message.type === "dependency") {
+ state.contextDependencies.add(message.file);
+ }
+ }
+ _sharedState.env.DEBUG && console.timeEnd("Recording PostCSS dependencies");
+ // TODO: This needs to be in a different spot
+ _sharedState.env.DEBUG && console.time("Watch new files");
+ state.watcher.refreshWatchedFiles();
+ _sharedState.env.DEBUG && console.timeEnd("Watch new files");
+ return result;
+ }).then((result)=>{
+ if (!output) {
+ process.stdout.write(result.css);
+ return;
+ }
+ return Promise.all([
+ (0, _utils.outputFile)(result.opts.to, result.css),
+ result.map && (0, _utils.outputFile)(result.opts.to + ".map", result.map.toString())
+ ]);
+ }).then(()=>{
+ let end = process.hrtime.bigint();
+ console.error();
+ console.error("Done in", (end - start) / BigInt(1e6) + "ms.");
+ }).then(()=>{}, (err)=>{
+ // TODO: If an initial build fails we can't easily pick up any PostCSS dependencies
+ // that were collected before the error occurred
+ // The result is not stored on the error so we have to store it externally
+ // and pull the messages off of it here somehow
+ // This results in a less than ideal DX because the watcher will not pick up
+ // changes to imported CSS if one of them caused an error during the initial build
+ // If you fix it and then save the main CSS file so there's no error
+ // The watcher will start watching the imported CSS files and will be
+ // resilient to future errors.
+ if (state.watcher) {
+ console.error(err);
+ } else {
+ return Promise.reject(err);
+ }
+ });
+ }
+ /**
+ * @param {{file: string, content(): Promise<string>, extension: string}[]} changes
+ */ async function parseChanges(changes) {
+ return Promise.all(changes.map(async (change)=>({
+ content: await change.content(),
+ extension: change.extension
+ })));
+ }
+ if (input !== undefined && input !== "-") {
+ state.contextDependencies.add(_path.default.resolve(input));
+ }
+ return {
+ build,
+ watch: async ()=>{
+ state.watcher = (0, _watching.createWatcher)(args, {
+ state,
+ /**
+ * @param {{file: string, content(): Promise<string>, extension: string}[]} changes
+ */ async rebuild (changes) {
+ let needsNewContext = changes.some((change)=>{
+ var _state_configBag;
+ return ((_state_configBag = state.configBag) === null || _state_configBag === void 0 ? void 0 : _state_configBag.dependencies.has(change.file)) || state.contextDependencies.has(change.file);
+ });
+ if (needsNewContext) {
+ state.context = null;
+ } else {
+ for (let change of (await parseChanges(changes))){
+ state.changedContent.push(change);
+ }
+ }
+ return build();
+ }
+ });
+ await build();
+ }
+ };
+}
diff --git a/node_modules/tailwindcss/lib/cli/build/utils.js b/node_modules/tailwindcss/lib/cli/build/utils.js
new file mode 100644
index 0000000..3bed060
--- /dev/null
+++ b/node_modules/tailwindcss/lib/cli/build/utils.js
@@ -0,0 +1,88 @@
+// @ts-check
+"use strict";
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+function _export(target, all) {
+ for(var name in all)Object.defineProperty(target, name, {
+ enumerable: true,
+ get: all[name]
+ });
+}
+_export(exports, {
+ indentRecursive: function() {
+ return indentRecursive;
+ },
+ formatNodes: function() {
+ return formatNodes;
+ },
+ readFileWithRetries: function() {
+ return readFileWithRetries;
+ },
+ drainStdin: function() {
+ return drainStdin;
+ },
+ outputFile: function() {
+ return outputFile;
+ }
+});
+const _fs = /*#__PURE__*/ _interop_require_default(require("fs"));
+const _path = /*#__PURE__*/ _interop_require_default(require("path"));
+function _interop_require_default(obj) {
+ return obj && obj.__esModule ? obj : {
+ default: obj
+ };
+}
+function indentRecursive(node, indent = 0) {
+ node.each && node.each((child, i)=>{
+ if (!child.raws.before || !child.raws.before.trim() || child.raws.before.includes("\n")) {
+ child.raws.before = `\n${node.type !== "rule" && i > 0 ? "\n" : ""}${" ".repeat(indent)}`;
+ }
+ child.raws.after = `\n${" ".repeat(indent)}`;
+ indentRecursive(child, indent + 1);
+ });
+}
+function formatNodes(root) {
+ indentRecursive(root);
+ if (root.first) {
+ root.first.raws.before = "";
+ }
+}
+async function readFileWithRetries(path, tries = 5) {
+ for(let n = 0; n <= tries; n++){
+ try {
+ return await _fs.default.promises.readFile(path, "utf8");
+ } catch (err) {
+ if (n !== tries) {
+ if (err.code === "ENOENT" || err.code === "EBUSY") {
+ await new Promise((resolve)=>setTimeout(resolve, 10));
+ continue;
+ }
+ }
+ throw err;
+ }
+ }
+}
+function drainStdin() {
+ return new Promise((resolve, reject)=>{
+ let result = "";
+ process.stdin.on("data", (chunk)=>{
+ result += chunk;
+ });
+ process.stdin.on("end", ()=>resolve(result));
+ process.stdin.on("error", (err)=>reject(err));
+ });
+}
+async function outputFile(file, newContents) {
+ try {
+ let currentContents = await _fs.default.promises.readFile(file, "utf8");
+ if (currentContents === newContents) {
+ return; // Skip writing the file
+ }
+ } catch {}
+ // Write the file
+ await _fs.default.promises.mkdir(_path.default.dirname(file), {
+ recursive: true
+ });
+ await _fs.default.promises.writeFile(file, newContents, "utf8");
+}
diff --git a/node_modules/tailwindcss/lib/cli/build/watching.js b/node_modules/tailwindcss/lib/cli/build/watching.js
new file mode 100644
index 0000000..83639bd
--- /dev/null
+++ b/node_modules/tailwindcss/lib/cli/build/watching.js
@@ -0,0 +1,182 @@
+// @ts-check
+"use strict";
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+Object.defineProperty(exports, "createWatcher", {
+ enumerable: true,
+ get: function() {
+ return createWatcher;
+ }
+});
+const _chokidar = /*#__PURE__*/ _interop_require_default(require("chokidar"));
+const _fs = /*#__PURE__*/ _interop_require_default(require("fs"));
+const _micromatch = /*#__PURE__*/ _interop_require_default(require("micromatch"));
+const _normalizepath = /*#__PURE__*/ _interop_require_default(require("normalize-path"));
+const _path = /*#__PURE__*/ _interop_require_default(require("path"));
+const _utils = require("./utils.js");
+function _interop_require_default(obj) {
+ return obj && obj.__esModule ? obj : {
+ default: obj
+ };
+}
+function createWatcher(args, { state , rebuild }) {
+ let shouldPoll = args["--poll"];
+ let shouldCoalesceWriteEvents = shouldPoll || process.platform === "win32";
+ // Polling interval in milliseconds
+ // Used only when polling or coalescing add/change events on Windows
+ let pollInterval = 10;
+ let watcher = _chokidar.default.watch([], {
+ // Force checking for atomic writes in all situations
+ // This causes chokidar to wait up to 100ms for a file to re-added after it's been unlinked
+ // This only works when watching directories though
+ atomic: true,
+ usePolling: shouldPoll,
+ interval: shouldPoll ? pollInterval : undefined,
+ ignoreInitial: true,
+ awaitWriteFinish: shouldCoalesceWriteEvents ? {
+ stabilityThreshold: 50,
+ pollInterval: pollInterval
+ } : false
+ });
+ // A queue of rebuilds, file reads, etc… to run
+ let chain = Promise.resolve();
+ /**
+ * A list of files that have been changed since the last rebuild
+ *
+ * @type {{file: string, content: () => Promise<string>, extension: string}[]}
+ */ let changedContent = [];
+ /**
+ * A list of files for which a rebuild has already been queued.
+ * This is used to prevent duplicate rebuilds when multiple events are fired for the same file.
+ * The rebuilt file is cleared from this list when it's associated rebuild has _started_
+ * This is because if the file is changed during a rebuild it won't trigger a new rebuild which it should
+ **/ let pendingRebuilds = new Set();
+ let _timer;
+ let _reject;
+ /**
+ * Rebuilds the changed files and resolves when the rebuild is
+ * complete regardless of whether it was successful or not
+ */ async function rebuildAndContinue() {
+ let changes = changedContent.splice(0);
+ // There are no changes to rebuild so we can just do nothing
+ if (changes.length === 0) {
+ return Promise.resolve();
+ }
+ // Clear all pending rebuilds for the about-to-be-built files
+ changes.forEach((change)=>pendingRebuilds.delete(change.file));
+ // Resolve the promise even when the rebuild fails
+ return rebuild(changes).then(()=>{}, (e)=>{
+ console.error(e.toString());
+ });
+ }
+ /**
+ *
+ * @param {*} file
+ * @param {(() => Promise<string>) | null} content
+ * @param {boolean} skipPendingCheck
+ * @returns {Promise<void>}
+ */ function recordChangedFile(file, content = null, skipPendingCheck = false) {
+ file = _path.default.resolve(file);
+ // Applications like Vim/Neovim fire both rename and change events in succession for atomic writes
+ // In that case rebuild has already been queued by rename, so can be skipped in change
+ if (pendingRebuilds.has(file) && !skipPendingCheck) {
+ return Promise.resolve();
+ }
+ // Mark that a rebuild of this file is going to happen
+ // It MUST happen synchronously before the rebuild is queued for this to be effective
+ pendingRebuilds.add(file);
+ changedContent.push({
+ file,
+ content: content !== null && content !== void 0 ? content : ()=>_fs.default.promises.readFile(file, "utf8"),
+ extension: _path.default.extname(file).slice(1)
+ });
+ if (_timer) {
+ clearTimeout(_timer);
+ _reject();
+ }
+ // If a rebuild is already in progress we don't want to start another one until the 10ms timer has expired
+ chain = chain.then(()=>new Promise((resolve, reject)=>{
+ _timer = setTimeout(resolve, 10);
+ _reject = reject;
+ }));
+ // Resolves once this file has been rebuilt (or the rebuild for this file has failed)
+ // This queues as many rebuilds as there are changed files
+ // But those rebuilds happen after some delay
+ // And will immediately resolve if there are no changes
+ chain = chain.then(rebuildAndContinue, rebuildAndContinue);
+ return chain;
+ }
+ watcher.on("change", (file)=>recordChangedFile(file));
+ watcher.on("add", (file)=>recordChangedFile(file));
+ // Restore watching any files that are "removed"
+ // This can happen when a file is pseudo-atomically replaced (a copy is created, overwritten, the old one is unlinked, and the new one is renamed)
+ // TODO: An an optimization we should allow removal when the config changes
+ watcher.on("unlink", (file)=>{
+ file = (0, _normalizepath.default)(file);
+ // Only re-add the file if it's not covered by a dynamic pattern
+ if (!_micromatch.default.some([
+ file
+ ], state.contentPatterns.dynamic)) {
+ watcher.add(file);
+ }
+ });
+ // Some applications such as Visual Studio (but not VS Code)
+ // will only fire a rename event for atomic writes and not a change event
+ // This is very likely a chokidar bug but it's one we need to work around
+ // We treat this as a change event and rebuild the CSS
+ watcher.on("raw", (evt, filePath, meta)=>{
+ if (evt !== "rename" || filePath === null) {
+ return;
+ }
+ let watchedPath = meta.watchedPath;
+ // Watched path might be the file itself
+ // Or the directory it is in
+ filePath = watchedPath.endsWith(filePath) ? watchedPath : _path.default.join(watchedPath, filePath);
+ // Skip this event since the files it is for does not match any of the registered content globs
+ if (!_micromatch.default.some([
+ filePath
+ ], state.contentPatterns.all)) {
+ return;
+ }
+ // Skip since we've already queued a rebuild for this file that hasn't happened yet
+ if (pendingRebuilds.has(filePath)) {
+ return;
+ }
+ // We'll go ahead and add the file to the pending rebuilds list here
+ // It'll be removed when the rebuild starts unless the read fails
+ // which will be taken care of as well
+ pendingRebuilds.add(filePath);
+ async function enqueue() {
+ try {
+ // We need to read the file as early as possible outside of the chain
+ // because it may be gone by the time we get to it. doing the read
+ // immediately increases the chance that the file is still there
+ let content = await (0, _utils.readFileWithRetries)(_path.default.resolve(filePath));
+ if (content === undefined) {
+ return;
+ }
+ // This will push the rebuild onto the chain
+ // We MUST skip the rebuild check here otherwise the rebuild will never happen on Linux
+ // This is because the order of events and timing is different on Linux
+ // @ts-ignore: TypeScript isn't picking up that content is a string here
+ await recordChangedFile(filePath, ()=>content, true);
+ } catch {
+ // If reading the file fails, it's was probably a deleted temporary file
+ // So we can ignore it and no rebuild is needed
+ }
+ }
+ enqueue().then(()=>{
+ // If the file read fails we still need to make sure the file isn't stuck in the pending rebuilds list
+ pendingRebuilds.delete(filePath);
+ });
+ });
+ return {
+ fswatcher: watcher,
+ refreshWatchedFiles () {
+ watcher.add(Array.from(state.contextDependencies));
+ watcher.add(Array.from(state.configBag.dependencies));
+ watcher.add(state.contentPatterns.all);
+ }
+ };
+}
diff --git a/node_modules/tailwindcss/lib/cli/help/index.js b/node_modules/tailwindcss/lib/cli/help/index.js
new file mode 100644
index 0000000..030997f
--- /dev/null
+++ b/node_modules/tailwindcss/lib/cli/help/index.js
@@ -0,0 +1,73 @@
+// @ts-check
+"use strict";
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+Object.defineProperty(exports, "help", {
+ enumerable: true,
+ get: function() {
+ return help;
+ }
+});
+const _packagejson = /*#__PURE__*/ _interop_require_default(require("../../../package.json"));
+function _interop_require_default(obj) {
+ return obj && obj.__esModule ? obj : {
+ default: obj
+ };
+}
+function help({ message , usage , commands , options }) {
+ let indent = 2;
+ // Render header
+ console.log();
+ console.log(`${_packagejson.default.name} v${_packagejson.default.version}`);
+ // Render message
+ if (message) {
+ console.log();
+ for (let msg of message.split("\n")){
+ console.log(msg);
+ }
+ }
+ // Render usage
+ if (usage && usage.length > 0) {
+ console.log();
+ console.log("Usage:");
+ for (let example of usage){
+ console.log(" ".repeat(indent), example);
+ }
+ }
+ // Render commands
+ if (commands && commands.length > 0) {
+ console.log();
+ console.log("Commands:");
+ for (let command of commands){
+ console.log(" ".repeat(indent), command);
+ }
+ }
+ // Render options
+ if (options) {
+ let groupedOptions = {};
+ for (let [key, value] of Object.entries(options)){
+ if (typeof value === "object") {
+ groupedOptions[key] = {
+ ...value,
+ flags: [
+ key
+ ]
+ };
+ } else {
+ groupedOptions[value].flags.push(key);
+ }
+ }
+ console.log();
+ console.log("Options:");
+ for (let { flags , description , deprecated } of Object.values(groupedOptions)){
+ if (deprecated) continue;
+ if (flags.length === 1) {
+ console.log(" ".repeat(indent + 4 /* 4 = "-i, ".length */ ), flags.slice().reverse().join(", ").padEnd(20, " "), description);
+ } else {
+ console.log(" ".repeat(indent), flags.slice().reverse().join(", ").padEnd(24, " "), description);
+ }
+ }
+ }
+ console.log();
+}
diff --git a/node_modules/tailwindcss/lib/cli/index.js b/node_modules/tailwindcss/lib/cli/index.js
new file mode 100644
index 0000000..e6e2e27
--- /dev/null
+++ b/node_modules/tailwindcss/lib/cli/index.js
@@ -0,0 +1,230 @@
+#!/usr/bin/env node
+"use strict";
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+const _path = /*#__PURE__*/ _interop_require_default(require("path"));
+const _arg = /*#__PURE__*/ _interop_require_default(require("arg"));
+const _fs = /*#__PURE__*/ _interop_require_default(require("fs"));
+const _build = require("./build");
+const _help = require("./help");
+const _init = require("./init");
+function _interop_require_default(obj) {
+ return obj && obj.__esModule ? obj : {
+ default: obj
+ };
+}
+function oneOf(...options) {
+ return Object.assign((value = true)=>{
+ for (let option of options){
+ let parsed = option(value);
+ if (parsed === value) {
+ return parsed;
+ }
+ }
+ throw new Error("...");
+ }, {
+ manualParsing: true
+ });
+}
+let commands = {
+ init: {
+ run: _init.init,
+ args: {
+ "--esm": {
+ type: Boolean,
+ description: `Initialize configuration file as ESM`
+ },
+ "--ts": {
+ type: Boolean,
+ description: `Initialize configuration file as TypeScript`
+ },
+ "--postcss": {
+ type: Boolean,
+ description: `Initialize a \`postcss.config.js\` file`
+ },
+ "--full": {
+ type: Boolean,
+ description: `Include the default values for all options in the generated configuration file`
+ },
+ "-f": "--full",
+ "-p": "--postcss"
+ }
+ },
+ build: {
+ run: _build.build,
+ args: {
+ "--input": {
+ type: String,
+ description: "Input file"
+ },
+ "--output": {
+ type: String,
+ description: "Output file"
+ },
+ "--watch": {
+ type: oneOf(String, Boolean),
+ description: "Watch for changes and rebuild as needed"
+ },
+ "--poll": {
+ type: Boolean,
+ description: "Use polling instead of filesystem events when watching"
+ },
+ "--content": {
+ type: String,
+ description: "Content paths to use for removing unused classes"
+ },
+ "--purge": {
+ type: String,
+ deprecated: true
+ },
+ "--postcss": {
+ type: oneOf(String, Boolean),
+ description: "Load custom PostCSS configuration"
+ },
+ "--minify": {
+ type: Boolean,
+ description: "Minify the output"
+ },
+ "--config": {
+ type: String,
+ description: "Path to a custom config file"
+ },
+ "--no-autoprefixer": {
+ type: Boolean,
+ description: "Disable autoprefixer"
+ },
+ "-c": "--config",
+ "-i": "--input",
+ "-o": "--output",
+ "-m": "--minify",
+ "-w": "--watch",
+ "-p": "--poll"
+ }
+ }
+};
+let sharedFlags = {
+ "--help": {
+ type: Boolean,
+ description: "Display usage information"
+ },
+ "-h": "--help"
+};
+if (process.stdout.isTTY /* Detect redirecting output to a file */ && (process.argv[2] === undefined || process.argv.slice(2).every((flag)=>sharedFlags[flag] !== undefined))) {
+ (0, _help.help)({
+ usage: [
+ "tailwindcss [--input input.css] [--output output.css] [--watch] [options...]",
+ "tailwindcss init [--full] [--postcss] [options...]"
+ ],
+ commands: Object.keys(commands).filter((command)=>command !== "build").map((command)=>`${command} [options]`),
+ options: {
+ ...commands.build.args,
+ ...sharedFlags
+ }
+ });
+ process.exit(0);
+}
+let command = ((arg = "")=>arg.startsWith("-") ? undefined : arg)(process.argv[2]) || "build";
+if (commands[command] === undefined) {
+ if (_fs.default.existsSync(_path.default.resolve(command))) {
+ // TODO: Deprecate this in future versions
+ // Check if non-existing command, might be a file.
+ command = "build";
+ } else {
+ (0, _help.help)({
+ message: `Invalid command: ${command}`,
+ usage: [
+ "tailwindcss <command> [options]"
+ ],
+ commands: Object.keys(commands).filter((command)=>command !== "build").map((command)=>`${command} [options]`),
+ options: sharedFlags
+ });
+ process.exit(1);
+ }
+}
+// Execute command
+let { args: flags , run } = commands[command];
+let args = (()=>{
+ try {
+ let result = (0, _arg.default)(Object.fromEntries(Object.entries({
+ ...flags,
+ ...sharedFlags
+ }).filter(([_key, value])=>{
+ var _value_type;
+ return !(value === null || value === void 0 ? void 0 : (_value_type = value.type) === null || _value_type === void 0 ? void 0 : _value_type.manualParsing);
+ }).map(([key, value])=>[
+ key,
+ typeof value === "object" ? value.type : value
+ ])), {
+ permissive: true
+ });
+ // Manual parsing of flags to allow for special flags like oneOf(Boolean, String)
+ for(let i = result["_"].length - 1; i >= 0; --i){
+ let flag = result["_"][i];
+ if (!flag.startsWith("-")) continue;
+ let [flagName, flagValue] = flag.split("=");
+ let handler = flags[flagName];
+ // Resolve flagName & handler
+ while(typeof handler === "string"){
+ flagName = handler;
+ handler = flags[handler];
+ }
+ if (!handler) continue;
+ let args = [];
+ let offset = i + 1;
+ // --flag value syntax was used so we need to pull `value` from `args`
+ if (flagValue === undefined) {
+ // Parse args for current flag
+ while(result["_"][offset] && !result["_"][offset].startsWith("-")){
+ args.push(result["_"][offset++]);
+ }
+ // Cleanup manually parsed flags + args
+ result["_"].splice(i, 1 + args.length);
+ // No args were provided, use default value defined in handler
+ // One arg was provided, use that directly
+ // Multiple args were provided so pass them all in an array
+ flagValue = args.length === 0 ? undefined : args.length === 1 ? args[0] : args;
+ } else {
+ // Remove the whole flag from the args array
+ result["_"].splice(i, 1);
+ }
+ // Set the resolved value in the `result` object
+ result[flagName] = handler.type(flagValue, flagName);
+ }
+ // Ensure that the `command` is always the first argument in the `args`.
+ // This is important so that we don't have to check if a default command
+ // (build) was used or not from within each plugin.
+ //
+ // E.g.: tailwindcss input.css -> _: ['build', 'input.css']
+ // E.g.: tailwindcss build input.css -> _: ['build', 'input.css']
+ if (result["_"][0] !== command) {
+ result["_"].unshift(command);
+ }
+ return result;
+ } catch (err) {
+ if (err.code === "ARG_UNKNOWN_OPTION") {
+ (0, _help.help)({
+ message: err.message,
+ usage: [
+ "tailwindcss <command> [options]"
+ ],
+ options: sharedFlags
+ });
+ process.exit(1);
+ }
+ throw err;
+ }
+})();
+if (args["--help"]) {
+ (0, _help.help)({
+ options: {
+ ...flags,
+ ...sharedFlags
+ },
+ usage: [
+ `tailwindcss ${command} [options]`
+ ]
+ });
+ process.exit(0);
+}
+run(args);
diff --git a/node_modules/tailwindcss/lib/cli/init/index.js b/node_modules/tailwindcss/lib/cli/init/index.js
new file mode 100644
index 0000000..47caf30
--- /dev/null
+++ b/node_modules/tailwindcss/lib/cli/init/index.js
@@ -0,0 +1,63 @@
+// @ts-check
+"use strict";
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+Object.defineProperty(exports, "init", {
+ enumerable: true,
+ get: function() {
+ return init;
+ }
+});
+const _fs = /*#__PURE__*/ _interop_require_default(require("fs"));
+const _path = /*#__PURE__*/ _interop_require_default(require("path"));
+function _interop_require_default(obj) {
+ return obj && obj.__esModule ? obj : {
+ default: obj
+ };
+}
+function isESM() {
+ const pkgPath = _path.default.resolve("./package.json");
+ try {
+ let pkg = JSON.parse(_fs.default.readFileSync(pkgPath, "utf8"));
+ return pkg.type && pkg.type === "module";
+ } catch (err) {
+ return false;
+ }
+}
+function init(args) {
+ let messages = [];
+ let isProjectESM = args["--ts"] || args["--esm"] || isESM();
+ let syntax = args["--ts"] ? "ts" : isProjectESM ? "js" : "cjs";
+ let extension = args["--ts"] ? "ts" : "js";
+ var _args___;
+ let tailwindConfigLocation = _path.default.resolve((_args___ = args["_"][1]) !== null && _args___ !== void 0 ? _args___ : `./tailwind.config.${extension}`);
+ if (_fs.default.existsSync(tailwindConfigLocation)) {
+ messages.push(`${_path.default.basename(tailwindConfigLocation)} already exists.`);
+ } else {
+ let stubContentsFile = _fs.default.readFileSync(args["--full"] ? _path.default.resolve(__dirname, "../../../stubs/config.full.js") : _path.default.resolve(__dirname, "../../../stubs/config.simple.js"), "utf8");
+ let stubFile = _fs.default.readFileSync(_path.default.resolve(__dirname, `../../../stubs/tailwind.config.${syntax}`), "utf8");
+ // Change colors import
+ stubContentsFile = stubContentsFile.replace("../colors", "tailwindcss/colors");
+ // Replace contents of {ts,js,cjs} file with the stub {simple,full}.
+ stubFile = stubFile.replace("__CONFIG__", stubContentsFile.replace("module.exports =", "").trim()).trim() + "\n\n";
+ _fs.default.writeFileSync(tailwindConfigLocation, stubFile, "utf8");
+ messages.push(`Created Tailwind CSS config file: ${_path.default.basename(tailwindConfigLocation)}`);
+ }
+ if (args["--postcss"]) {
+ let postcssConfigLocation = _path.default.resolve("./postcss.config.js");
+ if (_fs.default.existsSync(postcssConfigLocation)) {
+ messages.push(`${_path.default.basename(postcssConfigLocation)} already exists.`);
+ } else {
+ let stubFile = _fs.default.readFileSync(isProjectESM ? _path.default.resolve(__dirname, "../../../stubs/postcss.config.js") : _path.default.resolve(__dirname, "../../../stubs/postcss.config.cjs"), "utf8");
+ _fs.default.writeFileSync(postcssConfigLocation, stubFile, "utf8");
+ messages.push(`Created PostCSS config file: ${_path.default.basename(postcssConfigLocation)}`);
+ }
+ }
+ if (messages.length > 0) {
+ console.log();
+ for (let message of messages){
+ console.log(message);
+ }
+ }
+}