@teacss/cli 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ # MIT License
2
+
3
+ Copyright (c) 2021-PRESENT Anthony Fu <https://github.com/antfu>
4
+ Copyright (c) 2026-PRESENT Billgo <hi@billgo.me>
5
+
6
+ Permission is hereby granted, free of charge, to any person obtaining a copy
7
+ of this software and associated documentation files (the "Software"), to deal
8
+ in the Software without restriction, including without limitation the rights
9
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
+ copies of the Software, and to permit persons to whom the Software is
11
+ furnished to do so, subject to the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be included in all
14
+ copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,59 @@
1
+ # @teacss/cli
2
+
3
+ **Command-line tools for TeaCSS.**
4
+
5
+ ## Purpose
6
+
7
+ The CLI scans source files, generates CSS, and watches for changes.
8
+
9
+ Use this package from a shell, build script, or Node process when TeaCSS should
10
+ write a standalone CSS file without a bundler integration. It owns command-line
11
+ arguments, output files, and CLI watch sessions; Vite, Astro, Rsbuild, Bun, and
12
+ PostCSS projects should use their matching integrations for build-pipeline
13
+ lifecycle and invalidation.
14
+
15
+ ## Usage
16
+
17
+ ```sh
18
+ bun add -d @teacss/cli
19
+ ```
20
+
21
+ ```sh
22
+ bun run teacss "src/**/*.{ts,tsx,html}" -o tea.css
23
+ bun run teacss "src/**/*.{ts,tsx,html}" -o tea.css --watch
24
+ ```
25
+
26
+ Programmatic watch calls return an independently owned session:
27
+
28
+ ```ts
29
+ import { build } from "@teacss/cli";
30
+
31
+ const session = await build({
32
+ patterns: ["src/**/*.{ts,tsx,html}"],
33
+ outFile: "tea.css",
34
+ watch: true,
35
+ });
36
+
37
+ await session.dispose();
38
+ ```
39
+
40
+ Each session closes only its own watcher. `dispose()` cancels queued builds and
41
+ waits for active event/build work, so no output is written after it resolves.
42
+ When a CSS-entry configuration reloads, the CLI adds its new dependencies and
43
+ stops treating dependencies removed from the active graph as configuration
44
+ sources. Recoverable errors after a watch session starts are logged without
45
+ changing the embedding process's exit code; command startup failures still set
46
+ the CLI exit status.
47
+
48
+ Configuration is resolved from `index.css` or `src/index.css`:
49
+
50
+ ```css
51
+ @preset "standard";
52
+ @source "./src/**/*.{ts,tsx,html}";
53
+ @teacss;
54
+ ```
55
+
56
+ ## Status
57
+
58
+ Pre-1.0. Run `bun run teacss --help` for the full option list. Class sorting is
59
+ intentionally editor-owned, not a CLI command.
package/bin/teacss.mjs ADDED
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+
3
+ import("../dist/cli.mjs");
package/dist/cli.d.mts ADDED
@@ -0,0 +1 @@
1
+ export {}
package/dist/cli.mjs ADDED
@@ -0,0 +1 @@
1
+ import{a as e,i as t,r as n,t as r}from"./src-zC-aFBd6.mjs";import i from"node:process";import{green as a}from"colorette";import{resolve as o}from"pathe";import{cac as s}from"cac";async function c(t=i.cwd(),c=i.argv,l={}){let u=s(`teacss`);u.command(`[...patterns]`,`Glob patterns`,{ignoreOptionDefaultValue:!0}).option(`-o, --out-file <file>`,`Output file`,{default:o(t,`tea.css`)}).option(`--stdout`,`Output to STDOUT`,{default:!1}).option(`-c, --config [path]`,`CSS entry file or project root`).option(`-w, --watch`,`Watch for file changes`).option(`--rewrite`,`Update source files with transformed utilities`,{default:!1}).option(`--write-transformed`,`Update source files with transformed utilities (deprecated, use --rewrite)`,{default:!1}).option(`--preflights`,`Enable preflights`,{default:!0}).option(`-m, --minify`,`Minify generated CSS`,{default:!1}).option(`--debug`,`Enable debug mode`,{default:!1}).option(`--split-css [mode]`,`Whether to output CSS files scanned from patterns to outFile. Options: ${a(`true`)}, ${a(`false`)}, ${a(`multi`)}, ${a(`single`)}`,{default:!0}).option(`--preset [default-preset]`,`Use the ${a(`standard`)} preset as a fallback when the config supplies none.`,{default:`standard`}).action(async(e,i)=>{if(Object.assign(l,{cwd:t,...i}),String(l.splitCss)===`true`&&(l.splitCss=!0),String(l.splitCss)===`false`&&(l.splitCss=!1),l.splitCss!==void 0&&l.splitCss!==!0&&l.splitCss!==!1&&l.splitCss!==`multi`&&l.splitCss!==`single`)throw new n(`Invalid --split-css mode "${String(l.splitCss)}". Expected true, false, multi, or single.`);e&&(l.patterns=e),await r(l)}),u.help(),u.version(e),u.parse(c,{run:!1}),await u.runMatchedCommand()}c().catch(t);export{};
@@ -0,0 +1,88 @@
1
+ import { ResolvedConfig, UserConfig } from "@teacss/core";
2
+ //#region src/types.d.ts
3
+ interface CliGenericOptions {
4
+ /**
5
+ * Enable preflights
6
+ */
7
+ preflights?: boolean;
8
+ /**
9
+ * Minify generated CSS
10
+ */
11
+ minify?: boolean;
12
+ }
13
+ interface CliOptions extends CliGenericOptions {
14
+ /**
15
+ * Current working directory
16
+ *
17
+ * @default process.cwd()
18
+ */
19
+ cwd?: string;
20
+ /**
21
+ * Glob patterns to scan for files
22
+ */
23
+ patterns?: Array<string>;
24
+ /**
25
+ * Output file path
26
+ */
27
+ outFile?: string;
28
+ /**
29
+ * Watch mode to rebuild on change
30
+ */
31
+ watch?: boolean;
32
+ /**
33
+ * CSS entry file path or project root to discover the entry from.
34
+ */
35
+ config?: string;
36
+ /**
37
+ * Output to standard output
38
+ */
39
+ stdout?: boolean;
40
+ /**
41
+ * Update source files with transformed utilities
42
+ */
43
+ rewrite?: boolean;
44
+ /**
45
+ * Update source files with transformed utilities (deprecated, use --rewrite)
46
+ *
47
+ * @deprecated use `rewrite` instead
48
+ */
49
+ writeTransformed?: boolean;
50
+ /**
51
+ * Enable debug mode
52
+ */
53
+ debug?: boolean;
54
+ /**
55
+ * Whether to output CSS files scanned from patterns to outFile
56
+ *
57
+ * - false: Do not output CSS files
58
+ * - true: Transform and output scanned CSS file contents to outFile
59
+ * - 'multi': Output each CSS file separately with filename format `${originFile}-[hash]`
60
+ * - 'single': Merge multiple CSS files into one output file named `outFile-merged.css`
61
+ *
62
+ * @default true
63
+ */
64
+ splitCss?: boolean | "multi" | "single";
65
+ /**
66
+ * Built-in preset to use as a fallback when the resolved config supplies none.
67
+ */
68
+ preset?: "standard";
69
+ }
70
+ interface CliWatchSession {
71
+ /** Stop this watch invocation without affecting any other watch session. */
72
+ dispose(): Promise<void>;
73
+ }
74
+ //#endregion
75
+ //#region src/index.d.ts
76
+ declare function initializeConfig(options: CliOptions): Promise<{
77
+ ctx: import("@teacss/core").TeacssPluginContext<UserConfig<object>>;
78
+ config: ResolvedConfig<object>;
79
+ }>;
80
+ declare function build(options: CliOptions & {
81
+ watch: true;
82
+ }): Promise<CliWatchSession>;
83
+ declare function build(options: CliOptions & {
84
+ watch?: false;
85
+ }): Promise<void[] | undefined>;
86
+ declare function build(options: CliOptions): Promise<void[] | CliWatchSession | undefined>;
87
+ //#endregion
88
+ export { type CliOptions, type CliWatchSession, build, initializeConfig };
package/dist/index.mjs ADDED
@@ -0,0 +1 @@
1
+ import{n as e,t}from"./src-zC-aFBd6.mjs";export{t as build,e as initializeConfig};
@@ -0,0 +1,2 @@
1
+ import{existsSync as e,promises as t}from"node:fs";import n from"node:process";import{SKIP_END_COMMENT as r,SKIP_START_COMMENT as i,hash as a,toArray as o}from"@teacss/core";import s from"@teacss/directives";import{applyTransformerPipeline as c,createContext as l}from"@teacss/runtime";import{cyan as u,dim as d,green as f,yellow as p}from"colorette";import m,{consola as h,createConsola as g}from"consola";import{basename as _,dirname as v,normalize as y,relative as b,resolve as x}from"pathe";import{glob as S,isDynamicPattern as C}from"tinyglobby";import{entryDiscoveryFiles as w}from"@teacss/config";import{debounce as T}from"perfect-debounce";var E=`0.3.0`;function D(e,t,n){let r=[[`Output File`,`Source Files (${n.length})`]];n.forEach((n,i)=>{r.push([i===0?b(e.cwd,t):``,b(e.cwd,n.id)])});let i=r[0].map((e,t)=>Math.max(...r.map(e=>e[t].length))),a=i.map(e=>`-`.repeat(e+3)).join(`+`);m.log(p(`File Generation Details:`)),m.log(a);for(let e of r){let t=e.map((e,t)=>` ${e.padEnd(i[t])} `).join(`|`);m.log(`|${t}|`),m.log(a)}}var O=class extends Error{constructor(e){super(e),this.name=this.constructor.name,typeof Error.captureStackTrace==`function`?Error.captureStackTrace(this,this.constructor):this.stack=Error(e).stack}};function k(e){e instanceof O?h.error(e.message):h.error(e)}function A(e){k(e),n.exitCode=1}const j=RegExp(`(//\\s*?${i}\\s*?|\\/\\*\\s*?${i}\\s*?\\*\\/|<!--\\s*?${i}\\s*?-->)[\\s\\S]*?(//\\s*?${r}\\s*?|\\/\\*\\s*?${r}\\s*?\\*\\/|<!--\\s*?${r}\\s*?-->)`,`g`);function M(e){return!e.includes(i)||!e.includes(r)?e:e.replace(j,``)}function N(e){if(e.processedCode===e.code&&e.input!==void 0)return{cacheRevision:e.cacheRevision??0,input:e.input,shouldRewrite:e.rewrite&&!!e.transformedCode&&e.rewrittenCode!==e.transformedCode,sourceCode:e.processedCode,transformedCode:e.transformedCode}}function P(e,t){return e.code===t.sourceCode&&e.processedCode===t.sourceCode&&(e.cacheRevision??0)===t.cacheRevision&&e.input===t.input&&e.transformedCode===t.transformedCode}function ee(){return{entries:new Set,initialized:!1,invalidated:!1,tokenEpoch:0}}function F(e){e.cacheRevision=(e.cacheRevision??0)+1,e.processedCode=void 0,e.input=void 0,e.tokenEpoch=void 0,e.tokens=void 0,e.transformedCode=void 0}function I(e,t){return!!(t.shouldRewrite&&t.transformedCode&&P(e,t))}function te(e,t){I(e,t)&&(e.rewrittenCode=t.transformedCode)}function L(e,t){return N(t)||R(e,t)}async function R(e,t){let n=t.code,r=t.cacheRevision??0,i=(await c(e,n,t.id))?.code,a=M(i||n),o=t.code===n&&(t.cacheRevision??0)===r;return o&&(t.processedCode=n,t.input=a,t.tokenEpoch=void 0,t.tokens=void 0,t.transformedCode=i),{cacheRevision:r,input:a,shouldRewrite:o&&t.rewrite&&!!i&&t.rewrittenCode!==i,sourceCode:n,transformedCode:i}}async function z(e,t,n,r){if(P(t,n)&&t.tokens!==void 0&&t.tokenEpoch===r)return{...n,tokens:t.tokens};let i=new Set;return n.input&&!t.id.endsWith(`.css`)&&(i=(await e.generator.generate(n.input,{preflights:!1,safelist:!1,minify:!0,id:t.id})).matched),P(t,n)&&(t.tokenEpoch=r,t.tokens=i),{...n,tokens:i}}function B(e,t){if(t.context===e)return;let n=t.context!==void 0;t.disposeInvalidation?.(),t.context=e,t.initialized=!1,t.invalidated=n,t.disposeInvalidation=e.onInvalidate(()=>{t.invalidated=!0})}async function V(e,t){try{return await Promise.all(t.map(t=>L(e,t)))}catch(e){for(let e of t)F(e);throw e}}async function ne(e,t,n){B(e,n);let r=new Set(t),i=r.size===t.length?t:[...r],a=!1;if(n.initialized){for(let e of n.entries)if(!r.has(e)){a=!0;break}}let o=n.invalidated;if(a||o)for(let e of i)F(e);let s=[],c=!1;for(let t=1;t<=64;t++){n.invalidated=!1;try{s=await V(e,i)}catch(e){throw n.entries=new Set,n.initialized=!1,e}if(!n.invalidated)break;c=!0;for(let e of i)F(e);if(t===64)throw n.entries=new Set,n.initialized=!1,Error(`CLI transformer state did not stabilize after 64 passes`)}(!n.initialized||a||o||c)&&n.tokenEpoch++,n.entries=r,n.initialized=!0;let l=new Map;for(let t=0;t<s.length;t++){let r=i[t];l.set(r,await z(e,r,s[t],n.tokenEpoch))}return l}async function re(e,t,n){let r=new Set(n);await Promise.all([...new Set(t)].filter(e=>!r.has(e)).map(t=>e.extract(``,t)))}let H;const U=new WeakMap;function ie(e,t,n=100){return T(()=>e().catch(t),n)}function ae(e,t){let n=Promise.resolve(void 0),r=(...r)=>{let i=n.then(()=>e(...r));return n=i.then(()=>void 0,e=>t(e)),i};return r.drain=async()=>{await n},r}function W(e){let t=new Set,n=[];for(let r of e.entries.flatMap(e=>e.patterns)){let i=r;for(;C(i);)i=v(i);i=x(e.cwd,i),!t.has(i)&&(t.add(i),n.push(i))}return n}function G(e,t=[],n=[]){let r=new Set,i=[];for(let a of[...W(e),...t,...n])r.has(a)||(r.add(a),i.push(a));return i}function K(t){let n=new Set;for(let r of t){let t=y(r);for(;!e(t);){let e=v(t);if(e===t)break;t=e}n.add(t)}let r=[...n].sort((e,t)=>e.length-t.length);return r.filter((e,t)=>{for(let n=0;n<t;n++){let t=r[n],i=t.endsWith(`/`)?t:`${t}/`;if(e.startsWith(i))return!1}return!0})}function q(e,t){if(e===t)return!0;let n=e.endsWith(`/`)?e:`${e}/`;return t.startsWith(n)}function oe(e,t){let n=y(e);for(let e of t){let t=y(e);if(q(t,n)||q(n,t))return!0}return!1}function se(e,t){let n=[...e],r=[...t],i=n.filter(e=>r.some(t=>q(e,t)||q(t,e))),a=r.filter(e=>!i.some(t=>q(t,e))),o=[...i,...a],s=n.filter(e=>!i.includes(e)&&!o.some(t=>q(t,e)));return{added:a,removed:s,watched:[...n.filter(e=>!s.includes(e)),...a]}}function J(e,t,n){let r=n.map(y),i=y(x(e,t||`.`));return r.includes(i)?r:Array.from(new Set([...r,...w.map(e=>x(i,e))]))}function ce(e,t,n){let r=x(e,n);for(let n of t)if(x(e,n)===r)return!0;return!1}function le(e){return U.get(e)??Promise.resolve()}async function ue(e,t,r){if(H&&!e)return H;if(!e)return{close:()=>{}};let{watch:i}=await import(`chokidar`),a=[`**/{.git,node_modules}/**`],o=K(r??W({...e,cwd:e.cwd||n.cwd()})),s=i([],{ignoreInitial:!1,ignorePermissionErrors:!0,ignored:a});t&&s.on(`all`,t),U.set(s,new Promise((e,t)=>{let n=()=>{s.off(`ready`,r),s.off(`error`,i)},r=()=>{n(),e()},i=e=>{n(),t(e)};s.once(`ready`,r),s.once(`error`,i)}));try{s.add(o)}catch(e){throw await s.close(),e}return H=s,s}async function Y(e,n){for(let r=0;r<e.length;r+=32){let i=e.slice(r,r+32),a=await Promise.allSettled(i.map(e=>t.readFile(e,`utf-8`)));for(let e=0;e<a.length;e++){let t=a[e];if(t.status===`rejected`)throw t.reason;n(i[e],t.value)}}}async function X(e,t){if(e.getConfigFileList().length||!t)return;let n={standard:async()=>(await import(`@teacss/preset-standard`)).presetStandard()};if(!Object.hasOwn(n,t))throw new O(`Unknown preset "${t}". Available preset: standard.`);await e.generator.setConfig({presets:[await n[t]()],transformers:[s()]})}async function Z(e,t,n){let r=[];e.patterns?.length&&r.push({patterns:e.patterns,outFile:e.outFile??x(e.cwd,`tea.css`),rewrite:(e.rewrite||e.writeTransformed)??!1,splitCss:e.splitCss??!0});let i=o(t.cli?.entry||[]).map(t=>({...t,rewrite:t.rewrite===void 0?(e.rewrite||e.writeTransformed)??!1:t.rewrite,splitCss:t.splitCss===void 0?e.splitCss??!0:t.splitCss}));if(r.push(...i),!r.length)throw new O(`No glob patterns provided. Pass them directly, e.g. ${u(`teacss <path/to/**/*>`)}.`);return e.writeTransformed&&h.warn(`--write-transformed is deprecated, please use ${p(`--rewrite`)} instead.`),{...e,cwd:e.cwd,entries:r,ctx:n,debug:e.debug||!1}}async function Q(e){let{cwd:t=n.cwd(),config:r,preset:i}=e,a=l(r,{transformers:[s()]});return await a.updateRoot(t),await X(a,i),{ctx:a,config:a.generator.config}}async function $(e,t){let n=new Map,r=new Map,i=new Set;for(let e of t.values())for(let t of e){i.add(t.id);let e=r.get(t.id);e||(e=[],r.set(t.id,e)),e.push(t)}for(let t of e.entries){let{outFile:i,rewrite:o}=t,s=await S(t.patterns,{cwd:e.cwd,absolute:!0,expandDirectories:!1}),c=i.replace(/(\.css)?$/,`-merged.css`),l=x(e.cwd,i),u=x(e.cwd,c),d=t.splitCss===`multi`?new Set(s.filter(e=>e.endsWith(`.css`)).map(e=>e.replace(/(\.css)?$/,`-${a(e)}.css`))):void 0,f=s.filter(e=>e!==l&&e!==u&&!d?.has(e)),p=f.filter(e=>e.endsWith(`.css`)),m=f.filter(e=>!e.endsWith(`.css`)),h=(e,t,i)=>{let a=n.get(i);a||(a=[],n.set(i,a));let s=r.get(e),c=s?.findIndex(e=>(e.code===t||e.rewrittenCode===t||e.pendingRewrittenCode===t)&&e.rewrite===o)??-1,l=c>=0?s.splice(c,1)[0]:{id:e,code:t,rewrite:o};s?.length===0&&r.delete(e),a.push(l)};await Y(m,(e,t)=>h(e,t,i)),await Y(p,(e,n)=>{if(t.splitCss===!0)h(e,n,i);else if(t.splitCss===`single`)h(e,n,c);else if(t.splitCss===`multi`){let t=a(e),r=e.replace(/(\.css)?$/,`-${t}.css`);h(e,n,f.length>1?r:i)}})}for(let e of r.values())for(let t of e)F(t);let o=new Set;for(let e of n.values())for(let t of e)o.add(t.id);await re(e.ctx,i,o),t.clear();for(let[e,r]of n)t.set(e,r)}async function de(e){e.cwd??=n.cwd();let r=new Map,i=ee(),a=await Q(e),o=await Z(e,a.config,a.ctx),s=o.stdout?g({stderr:n.stderr,stdout:n.stderr}):h;if(o.stdout&&o.outFile)throw new O(`Cannot use --stdout and --out-file at the same time`);if(s.log(f(`TeaCSS v${E}`)),o.watch?s.start(`TeaCSS in watch mode...`):s.start(`TeaCSS for production...`),await $(o,r),r.size===0&&(s.warn(`No files matched the provided patterns.`),!o.watch))return;if(!o.watch)return await b(o);let c=!1,l,p=!1,m,v=ie(async()=>{if(c)return;let e=(async()=>{if(p&&(p=!1,await $(o,r)),!c)return b(o)})();m=e;try{return await e}finally{m===e&&(m=void 0)}},k);return await S();async function b(e){let t=Array.from(r.entries()),n=await ne(e.ctx,t.flatMap(([,e])=>e),i);return Promise.all(t.map(([t,r])=>fe(e,t,r,n)))}async function S(){let{ctx:n}=o,i=[],a=!1,h=ae(P,k),g=Array.from(r.values()).flatMap(e=>e.map(e=>e.id)),b=new Set(J(o.cwd,e.config,n.getConfigFileList())),S=G(o,g,Array.from(b)),C=new Set(S.map(y)),w=new Set(K(S)),T=await ue(o,(e,t)=>{if(!c&&oe(x(o.cwd,t),C)){if(!a){i.push([e,t]);return}h(e,t)}},[...w]);try{await le(T)}catch(e){throw c=!0,i.length=0,await T.close(),e}T.on(`error`,k);let E=i.splice(0);a=!0;let D=new Map,O=!1,A;for(let[e,t]of E){let n=x(o.cwd,t);b.has(n)?A=[e,t]:e===`add`||e===`addDir`||e===`unlinkDir`?O=!0:D.set(n,e)}if(A)h(...A);else if(O)h(`addDir`,o.cwd);else for(let[e,t]of D)h(t,e);i.length=0;async function j(){if(c)return;let t=J(o.cwd,e.config,n.getConfigFileList()).map(y);b.clear();for(let e of t)b.add(e);let i=Array.from(r.values()).flatMap(e=>e.map(e=>e.id)),a=G(o,i,t),s=new Set(K(a)),l=se(w,s);l.added.length&&T.add(l.added),!c&&(C=new Set(a.map(y)),w=new Set(l.watched),l.removed.length&&await T.unwatch(l.removed))}async function M(t,i){for(let e of r.values())for(let t of e)F(t);let a;try{await n.reloadConfig(),await X(n,e.preset);let t=await Z(e,n.generator.config,n);Object.assign(o,t),await $(o,r)}catch(e){a=e}try{await j()}catch(e){throw a?AggregateError([a,e],`Failed to reload the TeaCSS configuration and reconcile its watch sources`):e}if(a)throw a;if(c)return;let l=n.getConfigFileList().map(y);t===`change`&&s.info(`${u(_(i))} changed, setting new config`),s.info(`Watching for changes in ${[...o.entries.flatMap(e=>e.patterns),...l].map(u).join(`, `)}`)}async function N(e,i,a){if(e===`change`){s.log(`${f(e)} ${d(i)}`);let n=await t.readFile(a,`utf8`),o=Array.from(r.values()).flatMap(e=>e.filter(e=>e.id===a));if(!o.some(e=>e.rewrittenCode===n||e.pendingRewrittenCode===n))for(let e of o)(e.code!==n||e.rewrittenCode!==void 0)&&(F(e),e.rewrittenCode=void 0,e.code=n)}else if(e===`unlink`){s.log(`${f(e)} ${d(i)}`);for(let[,e]of r.entries())for(let t=e.length-1;t>=0;t--){let n=e[t];n.id===a&&(F(n),e.splice(t,1))}await n.extract(``,a)}else e===`add`&&(s.log(`${f(e)} ${d(i)}`),await $(o,r))}async function P(e,t){if(c)return;let n=x(o.cwd,t);if(e===`addDir`||e===`unlinkDir`){p=!0,v();return}ce(o.cwd,r.keys(),n)||(b.has(n)?await M(e,t):await N(e,t,n),c||v())}return{dispose(){return l??=(async()=>{c=!0,a=!1,i.length=0,v.cancel(),await T.close(),await h.drain(),v.cancel(),await m?.catch(()=>void 0),await T.close()})(),l}}}}async function fe(r,i,a,o){let s=performance.now(),{ctx:c}=r,l=new Set,d=[],p=[],m=!n.env.CI&&n.env.NODE_ENV!==`test`&&!r.minify;for(let e of a){let n=o.get(e),{input:i}=n;i&&(e.id.endsWith(`.css`)?p.push(m?`/* Source: ${b(r.cwd,e.id)} */\n${i}`.trim():i):n.tokens.forEach(e=>l.add(e)),n.shouldRewrite&&d.push((async()=>{if(!I(e,n))return;let r;try{r=await t.readFile(e.id,`utf8`)}catch(e){if(e.code===`ENOENT`)return;throw e}if(r!==n.sourceCode&&r!==e.rewrittenCode||!I(e,n))return;let i=n.transformedCode;e.pendingRewrittenCode=i;try{await t.writeFile(e.id,i,`utf-8`),te(e,n)}finally{e.pendingRewrittenCode===i&&(e.pendingRewrittenCode=void 0)}})()))}await Promise.all(d);let g=await c.generator.generate(l,{preflights:r.preflights,minify:r.minify});g.css&&p.push(g.css);let _=g.matched.size,y=p.join(`
2
+ `);if(r.stdout){n.stdout.write(y);return}r.debug&&D(r,i,a);let S=x(r.cwd,i),C=v(S);if(e(C)||await t.mkdir(C,{recursive:!0}),await t.writeFile(S,y,`utf-8`),!r.watch){let e=(performance.now()-s).toFixed(2);d.length>0&&h.success(`${d.length} file${d.length>1?`s`:``} rewritten in ${f(e)}ms`),_>0&&h.success(`${_} utilities generated to ${u(b(n.cwd(),S))} in ${f(e)}ms\n`)}}export{E as a,A as i,Q as n,O as r,de as t};
package/package.json ADDED
@@ -0,0 +1,47 @@
1
+ {
2
+ "name": "@teacss/cli",
3
+ "version": "0.3.0",
4
+ "description": "Command-line interface for TeaCSS — scan content and generate CSS, with watch mode.",
5
+ "homepage": "https://css.teasim.com",
6
+ "funding": "https://github.com/sponsors/billgo",
7
+ "license": "MIT",
8
+ "author": "Billgo <hi@billgo.me>",
9
+ "type": "module",
10
+ "exports": {
11
+ ".": "./dist/index.mjs",
12
+ "./package.json": "./package.json"
13
+ },
14
+ "types": "./dist/index.d.mts",
15
+ "bin": {
16
+ "teacss": "./bin/teacss.mjs"
17
+ },
18
+ "files": [
19
+ "bin",
20
+ "dist",
21
+ "README.md"
22
+ ],
23
+ "scripts": {
24
+ "build": "bunx rimraf dist && bunx tsdown --config tsdown.config.mts",
25
+ "dev": "tsdown --config-loader unrun --watch"
26
+ },
27
+ "dependencies": {
28
+ "@teacss/config": "0.3.0",
29
+ "@teacss/core": "0.3.0",
30
+ "@teacss/directives": "0.3.0",
31
+ "@teacss/preset-standard": "0.3.0",
32
+ "@teacss/runtime": "0.3.0",
33
+ "cac": "^7.0.0",
34
+ "chokidar": "^5.0.0",
35
+ "colorette": "^2.0.20",
36
+ "consola": "^3.4.2",
37
+ "pathe": "^2.0.3",
38
+ "perfect-debounce": "^2.1.0",
39
+ "tinyglobby": "^0.2.17"
40
+ },
41
+ "engines": {
42
+ "node": ">=22.12.0"
43
+ },
44
+ "publishConfig": {
45
+ "access": "public"
46
+ }
47
+ }