@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 +22 -0
- package/README.md +59 -0
- package/bin/teacss.mjs +3 -0
- package/dist/cli.d.mts +1 -0
- package/dist/cli.mjs +1 -0
- package/dist/index.d.mts +88 -0
- package/dist/index.mjs +1 -0
- package/dist/src-zC-aFBd6.mjs +2 -0
- package/package.json +47 -0
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
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{};
|
package/dist/index.d.mts
ADDED
|
@@ -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
|
+
}
|