@teacss/cli 0.5.2 → 0.6.2

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/README.md CHANGED
@@ -1,6 +1,8 @@
1
1
  # @teacss/cli
2
2
 
3
- Generate a standalone TeaCSS stylesheet from the command line.
3
+ Generate a standalone TeaCSS stylesheet from the command line. The `teacss`
4
+ development tool also includes this command and exposes `build` from
5
+ `teacss/cli`; this independent package remains available for direct use.
4
6
 
5
7
  ```sh
6
8
  npm install --save-dev @teacss/cli
@@ -16,7 +18,7 @@ Configuration comes from `index.css`, `src/index.css`, or
16
18
  `package.json#teacss.entry`:
17
19
 
18
20
  ```css
19
- @preset "standard";
21
+ @presets "standard";
20
22
  @source "./src/**/*.{ts,tsx,html}";
21
23
  @teacss;
22
24
  ```
package/dist/cli.mjs CHANGED
@@ -1 +1 @@
1
- import{a as e,i as t,n,o as r,t as i}from"./src-CL8NfUu5.mjs";import a from"node:process";import{green as o}from"colorette";import{resolve as s}from"pathe";import{cac as c}from"cac";async function l(e=a.cwd(),l=a.argv,u={}){let d=c(`teacss`);d.command(`[...patterns]`,`Glob patterns`,{ignoreOptionDefaultValue:!0}).option(`-o, --out-file <file>`,`Output file`,{default:s(e,`tea.css`)}).option(`--stdout`,`Output to STDOUT`,{default:!1}).option(`-c, --config [path]`,`CSS entry file or project root`).option(`--check`,`Explain the resolved project without generating CSS`,{default:!1}).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`,`Include preflight CSS (disable with --no-preflights)`,{default:!0}).option(`-m, --minify`,`Minify generated CSS`,{default:!1}).option(`--debug`,`Enable debug mode`,{default:!1}).option(`--split-css [mode]`,`CSS source output mode: ${o(`true`)}, ${o(`false`)}, ${o(`multi`)}, or ${o(`single`)}`,{default:!0}).option(`--preset <preset>`,`Use an explicit standalone preset when no CSS entry exists. Available: ${o(`standard`)}.`).option(`--unmatched [mode]`,`Opt-in unmatched-token reporting: ${o(`warn`)}, ${o(`error`)} (fail the build), or ${o(`off`)} (default).`,{default:`off`}).action(async(r,a)=>{if(Object.assign(u,{cwd:e,...a}),String(u.splitCss)===`true`&&(u.splitCss=!0),String(u.splitCss)===`false`&&(u.splitCss=!1),u.splitCss!==void 0&&u.splitCss!==!0&&u.splitCss!==!1&&u.splitCss!==`multi`&&u.splitCss!==`single`)throw new t(`Invalid --split-css mode "${String(u.splitCss)}". Expected true, false, multi, or single.`);if(u.unmatched!==void 0&&u.unmatched!==`warn`&&u.unmatched!==`error`&&u.unmatched!==`off`)throw new t(`Invalid --unmatched mode "${String(u.unmatched)}". Expected warn, error, or off.`);r&&(u.patterns=r),u.check?await n(u):await i(u)}),d.help(),d.version(r),d.parse(l,{run:!1}),await d.runMatchedCommand()}l().catch(e);export{};
1
+ import{a as e,i as t,n,o as r,t as i}from"./src-CJxuXmN8.mjs";import a from"node:process";import{green as o}from"colorette";import{resolve as s}from"pathe";import{cac as c}from"cac";async function l(e=a.cwd(),l=a.argv,u={}){let d=c(`teacss`);d.command(`[...patterns]`,`Glob patterns`,{ignoreOptionDefaultValue:!0}).option(`-o, --out-file <file>`,`Output file`,{default:s(e,`tea.css`)}).option(`--stdout`,`Output to STDOUT`,{default:!1}).option(`-c, --config [path]`,`CSS entry file or project root`).option(`--check`,`Explain the resolved project without generating CSS`,{default:!1}).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`,`Include preflight CSS (disable with --no-preflights)`,{default:!0}).option(`-m, --minify`,`Minify generated CSS`,{default:!1}).option(`--debug`,`Enable debug mode`,{default:!1}).option(`--split-css [mode]`,`CSS source output mode: ${o(`true`)}, ${o(`false`)}, ${o(`multi`)}, or ${o(`single`)}`,{default:!0}).option(`--preset <preset>`,`Use an explicit standalone preset when no CSS entry exists. Available: ${o(`standard`)}.`).option(`--unmatched [mode]`,`Opt-in unmatched-token reporting: ${o(`warn`)}, ${o(`error`)} (fail the build), or ${o(`off`)} (default).`,{default:`off`}).action(async(r,a)=>{if(Object.assign(u,{cwd:e,...a}),String(u.splitCss)===`true`&&(u.splitCss=!0),String(u.splitCss)===`false`&&(u.splitCss=!1),u.splitCss!==void 0&&u.splitCss!==!0&&u.splitCss!==!1&&u.splitCss!==`multi`&&u.splitCss!==`single`)throw new t(`Invalid --split-css mode "${String(u.splitCss)}". Expected true, false, multi, or single.`);if(u.unmatched!==void 0&&u.unmatched!==`warn`&&u.unmatched!==`error`&&u.unmatched!==`off`)throw new t(`Invalid --unmatched mode "${String(u.unmatched)}". Expected warn, error, or off.`);r&&(u.patterns=r),u.check?await n(u):await i(u)}),d.help(),d.version(r),d.parse(l,{run:!1}),await d.runMatchedCommand()}l().catch(e);export{};
package/dist/index.mjs CHANGED
@@ -1 +1 @@
1
- import{n as e,r as t,t as n}from"./src-CL8NfUu5.mjs";export{n as build,e as checkProject,t as initializeConfig};
1
+ import{n as e,r as t,t as n}from"./src-CJxuXmN8.mjs";export{n as build,e as checkProject,t as initializeConfig};
@@ -0,0 +1,3 @@
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.6.2`;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!==void 0&&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!==void 0&&P(e,t)}function te(e,t){I(e,t)&&(e.rewrittenCode=t.transformedCode)}function ne(e,t){return N(t)||L(e,t)}async function L(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!==void 0&&t.rewrittenCode!==i,sourceCode:n,transformedCode:i}}async function R(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 z(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 B(e,t){try{return await Promise.all(t.map(t=>ne(e,t)))}catch(e){for(let e of t)F(e);throw e}}async function V(e,t,n){z(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 B(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 R(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`){if(t.reason?.code===`ENOENT`)continue;throw t.reason}n(i[e],t.value)}}}async function X(e,t){if(e.getConfigFileList().length)return;if(!t)throw new O(`No TeaCSS CSS entry was found. Create an entry with an explicit @presets, or pass ${u(`--preset standard`)} for a standalone CLI build.`);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()],...e.unmatched===void 0?{}:{unmatched:e.unmatched}});return await a.updateRoot(t),await X(a,i),{ctx:a,config:a.generator.config}}async function de(e){let{cwd:t=n.cwd(),config:r,preset:i}=e,a=l(r,{transformers:[s()]});await a.updateRoot(t),!a.getConfigFileList().length&&i&&await X(a,i);let o=a.generator.config,c=a.getConfigFileList(),d=o.presets.map(e=>e.name||`(anonymous)`),f=o.content?.filesystem??[],p=[`TeaCSS project check`,`Root: ${t}`,`Entry: ${c[0]??`not found`}`,`Presets: ${d.length?d.join(`, `):`none`}`,`Sources: ${f.length?f.join(`, `):`implicit build-tool discovery`}`,`Rules: ${o.rulesSize}`,`Shortcuts: ${o.shortcuts.length}`];if(n.stdout.write(`${p.join(`
2
+ `)}\n`),!c.length&&!i)throw new O(`No TeaCSS CSS entry was found. Create an entry with an explicit @presets, or pass ${u(`--preset standard`)} to inspect standalone CLI configuration.`);return{configFiles:c,presets:d,root:t,rules:o.rulesSize,shortcuts:o.shortcuts.length,sources:f}}const fe=/^(.*)-([\da-z]{6})\.css$/;function pe(e){let t=fe.exec(e);return t!==null&&a(`${t[1]}.css`)===t[2]}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`?pe:()=>!1,f=s.filter(e=>e!==l&&e!==u&&!d(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 me(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&&=(await $(o,r),!1),!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 V(e.ctx,t.flatMap(([,e])=>e),i);return Promise.all(t.map(([t,r])=>he(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(),e.preset&&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 he(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(`
3
+ `);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{A as a,O as i,de as n,E as o,Q as r,me as t};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@teacss/cli",
3
- "version": "0.5.2",
3
+ "version": "0.6.2",
4
4
  "description": "Command-line interface for TeaCSS — scan content and generate CSS, with watch mode.",
5
5
  "homepage": "https://css.teasim.com",
6
6
  "funding": "https://github.com/sponsors/billgo",
@@ -9,6 +9,7 @@
9
9
  "type": "module",
10
10
  "exports": {
11
11
  ".": "./dist/index.mjs",
12
+ "./cli": "./dist/cli.mjs",
12
13
  "./package.json": "./package.json"
13
14
  },
14
15
  "types": "./dist/index.d.mts",
@@ -25,11 +26,11 @@
25
26
  "dev": "tsdown --config-loader unrun --watch"
26
27
  },
27
28
  "dependencies": {
28
- "@teacss/config": "0.5.2",
29
- "@teacss/core": "0.5.2",
30
- "@teacss/directives": "0.5.2",
31
- "@teacss/preset-standard": "0.5.2",
32
- "@teacss/runtime": "0.5.2",
29
+ "@teacss/config": "0.6.2",
30
+ "@teacss/core": "0.6.2",
31
+ "@teacss/directives": "0.6.2",
32
+ "@teacss/preset-standard": "0.6.2",
33
+ "@teacss/runtime": "0.6.2",
33
34
  "cac": "^7.0.0",
34
35
  "chokidar": "^5.0.0",
35
36
  "colorette": "^2.0.20",
@@ -1,3 +0,0 @@
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.5.2`;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!==void 0&&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!==void 0&&P(e,t)}function te(e,t){I(e,t)&&(e.rewrittenCode=t.transformedCode)}function ne(e,t){return N(t)||L(e,t)}async function L(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!==void 0&&t.rewrittenCode!==i,sourceCode:n,transformedCode:i}}async function R(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 z(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 B(e,t){try{return await Promise.all(t.map(t=>ne(e,t)))}catch(e){for(let e of t)F(e);throw e}}async function V(e,t,n){z(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 B(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 R(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`){if(t.reason?.code===`ENOENT`)continue;throw t.reason}n(i[e],t.value)}}}async function X(e,t){if(e.getConfigFileList().length)return;if(!t)throw new O(`No TeaCSS CSS entry was found. Create an entry with an explicit @preset, or pass ${u(`--preset standard`)} for a standalone CLI build.`);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()],...e.unmatched===void 0?{}:{unmatched:e.unmatched}});return await a.updateRoot(t),await X(a,i),{ctx:a,config:a.generator.config}}async function de(e){let{cwd:t=n.cwd(),config:r,preset:i}=e,a=l(r,{transformers:[s()]});await a.updateRoot(t),!a.getConfigFileList().length&&i&&await X(a,i);let o=a.generator.config,c=a.getConfigFileList(),d=o.presets.map(e=>e.name||`(anonymous)`),f=o.content?.filesystem??[],p=[`TeaCSS project check`,`Root: ${t}`,`Entry: ${c[0]??`not found`}`,`Presets: ${d.length?d.join(`, `):`none`}`,`Sources: ${f.length?f.join(`, `):`implicit build-tool discovery`}`,`Rules: ${o.rulesSize}`,`Shortcuts: ${o.shortcuts.length}`];if(n.stdout.write(`${p.join(`
2
- `)}\n`),!c.length&&!i)throw new O(`No TeaCSS CSS entry was found. Create an entry with an explicit @preset, or pass ${u(`--preset standard`)} to inspect standalone CLI configuration.`);return{configFiles:c,presets:d,root:t,rules:o.rulesSize,shortcuts:o.shortcuts.length,sources:f}}const fe=/^(.*)-([\da-z]{6})\.css$/;function pe(e){let t=fe.exec(e);return t!==null&&a(`${t[1]}.css`)===t[2]}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`?pe:()=>!1,f=s.filter(e=>e!==l&&e!==u&&!d(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 me(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&&=(await $(o,r),!1),!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 V(e.ctx,t.flatMap(([,e])=>e),i);return Promise.all(t.map(([t,r])=>he(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(),e.preset&&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 he(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(`
3
- `);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{A as a,O as i,de as n,E as o,Q as r,me as t};