@sugarcube-sh/cli 0.1.5 → 0.1.6
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/dist/index.mjs +76 -74
- package/package.json +2 -2
package/dist/index.mjs
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
var
|
|
2
|
+
var et=Object.defineProperty;var r=(e,t)=>et(e,"name",{value:t,configurable:!0});import{Command as D}from"commander";import a from"picocolors";import{existsSync as P,readFileSync as tt}from"node:fs";import{relative as A,join as R,basename as Se,resolve as U,dirname as nt,isAbsolute as st}from"pathe";import{z as w}from"zod";import ne,{mkdir as G,writeFile as se,readFile as Ee}from"node:fs/promises";import{execa as rt}from"execa";import{select as re,isCancel as W,log as ot,multiselect as it,confirm as at,cancel as be}from"@clack/prompts";import{loadInternalConfig as z,isNoConfigError as Ie,loadAndResolveTokens as ct,extractFileRefs as lt,configFileExists as Te,findResolverDocument as ut,fillDefaults as dt,clearMatchCache as pt,processAndConvertTokens as ft,generateCSSVariables as mt,writeCSSVariablesToDisk as gt,writeCSSUtilitiesToDisk as ht,convertConfigToUnoRules as wt,DEFAULT_CONFIG as oe}from"@sugarcube-sh/core";import yt,{resolve as ve}from"node:path";import{getColumns as St}from"@clack/core";import{wrapAnsi as Et}from"fast-wrap-ansi";import bt from"is-unicode-supported";import*as _e from"node:readline";import Re from"node:readline";import{createLogUpdate as $e}from"log-update";import{detect as It}from"@antfu/ni";import{createGenerator as Tt}from"@unocss/core";import{glob as ie}from"tinyglobby";import{watch as Oe}from"chokidar";var vt="0.1.6",Ce={version:vt};const Z={INIT:"@sugarcube-sh/cli init"},$={INITIALIZATION:"https://sugarcube.sh/docs/getting-started",ISSUES:"https://github.com/sugarcube-sh/sugarcube/issues",RESOLVER:"https://sugarcube.sh/docs/resolver",DESIGN_TOKENS:"https://sugarcube.sh/docs/tokens",COMPONENTS_CLI:"https://sugarcube.sh/docs/reference/cli-commands/#components",DOCS:"https://sugarcube.sh/docs"},S={PROJECT_REQUIRED:`No sugarcube project detected. Please run ${a.cyan(Z.INIT)} first.
|
|
3
3
|
|
|
4
|
-
For more information, visit: ${
|
|
4
|
+
For more information, visit: ${a.cyan($.INITIALIZATION)}`,CONFIG_EXISTS:r(()=>`A sugarcube config file already exists in this project.
|
|
5
5
|
|
|
6
|
-
To start over, remove it and run ${
|
|
6
|
+
To start over, remove it and run ${a.cyan(Z.INIT)} again.`,"CONFIG_EXISTS"),PLUGIN_INSTALL_FAILED:r(e=>{const t=e.packageManager==="npm"?"install":"add";return`Failed to install ${e.pluginToInstall} plugin.
|
|
7
7
|
|
|
8
8
|
This is usually a temporary issue. Try these steps:
|
|
9
9
|
|
|
@@ -12,7 +12,7 @@ This is usually a temporary issue. Try these steps:
|
|
|
12
12
|
3. Install manually: ${e.packageManager} ${t} ${e.pluginToInstall}
|
|
13
13
|
|
|
14
14
|
If the problem continues, please open an issue at:
|
|
15
|
-
${$.ISSUES}`},"PLUGIN_INSTALL_FAILED"),CLI_INSTALL_FAILED:
|
|
15
|
+
${$.ISSUES}`},"PLUGIN_INSTALL_FAILED"),CLI_INSTALL_FAILED:r(e=>{const t=e.packageManager==="npm"?"install":"add";return`Failed to install @sugarcube-sh/cli.
|
|
16
16
|
|
|
17
17
|
This is usually a temporary issue. Try these steps:
|
|
18
18
|
|
|
@@ -21,127 +21,129 @@ This is usually a temporary issue. Try these steps:
|
|
|
21
21
|
3. Install manually: ${e.packageManager} ${t} -D @sugarcube-sh/cli
|
|
22
22
|
|
|
23
23
|
If the problem continues, please open an issue at:
|
|
24
|
-
${$.ISSUES}`},"CLI_INSTALL_FAILED"),INITIALIZATION_INCOMPLETE:
|
|
24
|
+
${$.ISSUES}`},"CLI_INSTALL_FAILED"),INITIALIZATION_INCOMPLETE:r(()=>`The initialization process was not completed properly.
|
|
25
25
|
This is an internal error that should not occur.
|
|
26
26
|
Try running the \`init\` command again.
|
|
27
27
|
|
|
28
28
|
If the problem persists, please report this issue at
|
|
29
|
-
${$.ISSUES}`,"INITIALIZATION_INCOMPLETE"),CONFIG_WRITE_FAILED:
|
|
29
|
+
${$.ISSUES}`,"INITIALIZATION_INCOMPLETE"),CONFIG_WRITE_FAILED:r(()=>"Failed to write configuration file. Check permissions and try again.","CONFIG_WRITE_FAILED"),KIT_INCOMPLETE:r(()=>`The starter kit appears to be incomplete or corrupted.
|
|
30
30
|
|
|
31
|
-
This is likely a temporary issue. Please try running the command again or choose a different starter kit.`,"KIT_INCOMPLETE"),REGISTRY_AUTH_REQUIRED:
|
|
32
|
-
URL: ${
|
|
33
|
-
URL: ${
|
|
34
|
-
URL: ${
|
|
35
|
-
URL: ${
|
|
31
|
+
This is likely a temporary issue. Please try running the command again or choose a different starter kit.`,"KIT_INCOMPLETE"),REGISTRY_AUTH_REQUIRED:r(e=>`Registry access denied: Authentication required
|
|
32
|
+
URL: ${a.cyan(e)}`,"REGISTRY_AUTH_REQUIRED"),REGISTRY_AUTH_INVALID:r(e=>`Registry access denied: Invalid or missing token
|
|
33
|
+
URL: ${a.cyan(e)}`,"REGISTRY_AUTH_INVALID"),REGISTRY_NOT_FOUND:r(e=>`Registry resource not found
|
|
34
|
+
URL: ${a.cyan(e)}`,"REGISTRY_NOT_FOUND"),REGISTRY_REQUEST_FAILED:r((e,t)=>`Registry request failed: ${e}
|
|
35
|
+
URL: ${a.cyan(t)}`,"REGISTRY_REQUEST_FAILED"),REGISTRY_NETWORK_ERROR:r(e=>`Failed to connect to registry
|
|
36
36
|
|
|
37
|
-
URL: ${
|
|
37
|
+
URL: ${a.cyan(e)}
|
|
38
38
|
|
|
39
|
-
The registry server may be temporarily unavailable or there might be network connectivity issues. Please try again in a few minutes.`,"REGISTRY_NETWORK_ERROR"),REGISTRY_INVALID_DATA:
|
|
40
|
-
URL: ${
|
|
41
|
-
Available ${e==="tokens"?"starter kit":e}s: ${n.join(", ")}`,"REGISTRY_ITEM_NOT_FOUND"),REGISTRY_FILE_INVALID:
|
|
42
|
-
File: ${
|
|
39
|
+
The registry server may be temporarily unavailable or there might be network connectivity issues. Please try again in a few minutes.`,"REGISTRY_NETWORK_ERROR"),REGISTRY_INVALID_DATA:r(e=>`Invalid registry data received
|
|
40
|
+
URL: ${a.cyan(e)}`,"REGISTRY_INVALID_DATA"),REGISTRY_ITEM_NOT_FOUND:r((e,t,n)=>`${e==="tokens"?"Starter kit":e}'${a.cyan(t)} ' not found in registry
|
|
41
|
+
Available ${e==="tokens"?"starter kit":e}s: ${n.join(", ")}`,"REGISTRY_ITEM_NOT_FOUND"),REGISTRY_FILE_INVALID:r(e=>`Invalid file content received
|
|
42
|
+
File: ${a.cyan(e)}`,"REGISTRY_FILE_INVALID"),STARTER_KIT_UNAVAILABLE:r(e=>`Starter kit '${a.cyan(e)}' is currently unavailable.
|
|
43
43
|
|
|
44
|
-
Please try a different starter kit or run the command again in a few minutes.`,"STARTER_KIT_UNAVAILABLE"),RESOLVER_NOT_CONFIGURED:
|
|
44
|
+
Please try a different starter kit or run the command again in a few minutes.`,"STARTER_KIT_UNAVAILABLE"),RESOLVER_NOT_CONFIGURED:r(()=>`No resolver path configured.
|
|
45
45
|
|
|
46
46
|
Add a resolver path to your sugarcube config:
|
|
47
47
|
|
|
48
|
-
${
|
|
48
|
+
${a.cyan(`export default {
|
|
49
49
|
resolver: "./tokens.resolver.json",
|
|
50
50
|
// ...
|
|
51
51
|
}`)}
|
|
52
52
|
|
|
53
|
-
See ${
|
|
53
|
+
See ${a.cyan($.RESOLVER)} for more information.`,"RESOLVER_NOT_CONFIGURED"),RESOLVER_NOT_FOUND:r(e=>`No resolver document found in ${a.cyan(e)}.
|
|
54
54
|
|
|
55
55
|
A resolver document (*.resolver.json) is required to define how your tokens are loaded.
|
|
56
56
|
|
|
57
|
-
See ${
|
|
58
|
-
${e.map(t=>` - ${
|
|
57
|
+
See ${a.cyan($.RESOLVER)} to learn how to create one.`,"RESOLVER_NOT_FOUND"),RESOLVER_MULTIPLE_FOUND:r(e=>`Multiple resolver documents found:
|
|
58
|
+
${e.map(t=>` - ${a.cyan(t)}`).join(`
|
|
59
59
|
`)}
|
|
60
60
|
|
|
61
|
-
A project should have only one resolver document. Please remove the extras or consolidate them.`,"RESOLVER_MULTIPLE_FOUND"),TOKEN_LOAD_FAILED:
|
|
61
|
+
A project should have only one resolver document. Please remove the extras or consolidate them.`,"RESOLVER_MULTIPLE_FOUND"),TOKEN_LOAD_FAILED:r(e=>`Failed to load token files:
|
|
62
62
|
|
|
63
63
|
${e.join(`
|
|
64
64
|
`)}
|
|
65
65
|
|
|
66
|
-
Please check your token files and try again.`,"TOKEN_LOAD_FAILED"),TOKEN_VALIDATION_FAILED:
|
|
66
|
+
Please check your token files and try again.`,"TOKEN_LOAD_FAILED"),TOKEN_VALIDATION_FAILED:r(e=>{let t=`Token validation failed:
|
|
67
67
|
|
|
68
|
-
`;for(const[n,
|
|
69
|
-
`;for(const o of
|
|
68
|
+
`;for(const[n,s]of e){t+=`Error(s) in ${a.cyan(n)}:
|
|
69
|
+
`;for(const o of s)t+=` - ${o}
|
|
70
70
|
`;t+=`
|
|
71
|
-
`}return t+=`See ${
|
|
72
|
-
Please check your package manager configuration and try again.`,"DEPENDENCY_INSTALL_FAILED"),VALIDATE_NO_PATH_SPECIFIED:
|
|
71
|
+
`}return t+=`See ${a.cyan($.DESIGN_TOKENS)} for valid token formats`,t},"TOKEN_VALIDATION_FAILED"),TOKEN_FILE_INVALID_JSON:r(e=>`File ${e}: Invalid JSON syntax`,"TOKEN_FILE_INVALID_JSON"),TOKEN_FILE_INCOMPLETE_JSON:r(e=>`File ${e}: Incomplete JSON file`,"TOKEN_FILE_INCOMPLETE_JSON"),TOKEN_FILE_GENERIC_ERROR:r((e,t)=>`File ${e}: ${t}`,"TOKEN_FILE_GENERIC_ERROR"),DEPENDENCY_INSTALL_FAILED:r(e=>`Failed to install dependencies using ${e}.
|
|
72
|
+
Please check your package manager configuration and try again.`,"DEPENDENCY_INSTALL_FAILED"),VALIDATE_NO_PATH_SPECIFIED:r(()=>`No path specified.
|
|
73
73
|
|
|
74
|
-
Run ${
|
|
74
|
+
Run ${a.cyan("sugarcube validate --help")} for more information.`,"VALIDATE_NO_PATH_SPECIFIED"),VALIDATE_PATH_NOT_FOUND:r(e=>`Path not found: ${e}
|
|
75
75
|
|
|
76
|
-
Please check that the specified path exists`,"VALIDATE_PATH_NOT_FOUND"),VALIDATE_NO_TOKEN_FILES:
|
|
76
|
+
Please check that the specified path exists`,"VALIDATE_PATH_NOT_FOUND"),VALIDATE_NO_TOKEN_FILES:r(()=>`No token files found.
|
|
77
77
|
|
|
78
|
-
Please ensure the path contains .json token files`,"VALIDATE_NO_TOKEN_FILES"),COMPONENTS_FRAMEWORK_REQUIRED:
|
|
78
|
+
Please ensure the path contains .json token files`,"VALIDATE_NO_TOKEN_FILES"),COMPONENTS_FRAMEWORK_REQUIRED:r(()=>`Framework is required when specifying components. Use --framework to specify a framework (react, css-only) or run without arguments for interactive mode.
|
|
79
79
|
|
|
80
|
-
See ${
|
|
80
|
+
See ${a.cyan($.COMPONENTS_CLI)} for more information.`,"COMPONENTS_FRAMEWORK_REQUIRED"),COMPONENTS_INVALID_FRAMEWORK:r(()=>"Invalid framework. Must be one of: react, css-only.","COMPONENTS_INVALID_FRAMEWORK"),COMPONENTS_DIRECTORY_NOT_CONFIGURED:r(()=>"Components directory must be configured in non-interactive mode. Please run the 'components' command without arguments first.","COMPONENTS_DIRECTORY_NOT_CONFIGURED"),PLUGIN_DETECTED:r(e=>`Plugin detected: ${e}
|
|
81
81
|
|
|
82
82
|
The 'generate' command is for manual generation without plugins. Since you have a plugin installed, use your development server instead:
|
|
83
83
|
|
|
84
84
|
npm run dev # or your framework's dev command
|
|
85
85
|
|
|
86
|
-
The plugin will automatically generate CSS with hot module replacement.`,"PLUGIN_DETECTED"),GENERATE_NO_CONFIG_OR_RESOLVER:
|
|
86
|
+
The plugin will automatically generate CSS with hot module replacement.`,"PLUGIN_DETECTED"),GENERATE_NO_CONFIG_OR_RESOLVER:r(()=>`No design tokens found.
|
|
87
87
|
|
|
88
|
-
Run ${
|
|
88
|
+
Run ${a.cyan(Z.INIT)} to set up your design tokens.
|
|
89
89
|
|
|
90
|
-
Stuck? ${
|
|
90
|
+
Stuck? ${a.cyan($.DOCS)}`,"GENERATE_NO_CONFIG_OR_RESOLVER"),GENERATE_MULTIPLE_RESOLVERS_NO_CONFIG:r(e=>`No config file found, but multiple resolver files detected:
|
|
91
91
|
${e.map(t=>` - ${t}`).join(`
|
|
92
92
|
`)}
|
|
93
93
|
|
|
94
94
|
Please either:
|
|
95
|
-
- Create a config file with ${
|
|
96
|
-
- Use --resolver flag to specify which resolver to use`,"GENERATE_MULTIPLE_RESOLVERS_NO_CONFIG"),FILENAME_CONTAINS_PATH:
|
|
95
|
+
- Create a config file with ${a.cyan(Z.INIT)}
|
|
96
|
+
- Use --resolver flag to specify which resolver to use`,"GENERATE_MULTIPLE_RESOLVERS_NO_CONFIG"),FILENAME_CONTAINS_PATH:r((e,t)=>`Invalid ${e} value: "${t}". Must be a filename, not a path.
|
|
97
97
|
|
|
98
|
-
Use --variables-dir or --utilities-dir to specify the directory.`,"FILENAME_CONTAINS_PATH")};class
|
|
99
|
-
Available components: ${u}`)}const
|
|
100
|
-
${e.variableCSS.map(
|
|
98
|
+
Use --variables-dir or --utilities-dir to specify the directory.`,"FILENAME_CONTAINS_PATH")};class g extends Error{static{r(this,"CLIError")}constructor(t,n){super(t),this.name="CLIError",this.cause=n}}const ae=w.enum(["react","web-components","css-only"]),ke=w.object({path:w.string(),type:w.string()}),_t=ke.extend({framework:ae}),Rt=w.object({name:w.string(),type:w.string(),description:w.string().optional(),frameworks:w.array(w.string()).optional(),files:w.array(w.union([_t,ke])),tokens:w.record(w.object({type:w.string(),mapping:w.string()})).optional(),dependencies:w.record(ae,w.array(w.string())).optional(),registryDependencies:w.record(ae,w.array(w.string())).optional(),tokenDependencies:w.array(w.string()).optional()}),$t=w.array(Rt),Ot=w.object({content:w.string()}),Ne=process.env.REGISTRY_URL??"https://sugarcube.sh/r";async function Fe(e){try{const t=await fetch(e);if(!t.ok){if(t.status===401)throw new g(S.REGISTRY_AUTH_REQUIRED(e));if(t.status===403)throw new g(S.REGISTRY_AUTH_INVALID(e));if(t.status===404)throw new g(S.REGISTRY_NOT_FOUND(e));const n=await t.json().catch(()=>null),s=n&&typeof n=="object"&&"error"in n?String(n.error):t.statusText;throw new g(S.REGISTRY_REQUEST_FAILED(s,e))}return t.json()}catch(t){throw t instanceof g?t:new g(S.REGISTRY_NETWORK_ERROR(e))}}r(Fe,"fetchRegistry");async function L(){const e=`${Ne}/index.json`,t=await Fe(e);try{return $t.parse(t)}catch{throw new g(S.REGISTRY_INVALID_DATA(e))}}r(L,"getRegistryIndex");async function ce({type:e,name:t,framework:n}){const s=await L(),o=s.find(c=>c.type===e&&c.name===t);if(!o){const c=s.filter(d=>d.type===e).map(d=>d.name);throw new g(S.REGISTRY_ITEM_NOT_FOUND(e,t,c))}let i=o.files;e==="component"&&n&&(i=o.files.filter(c=>"framework"in c&&c.framework===n));const p=await Promise.all(i.map(async c=>{const d=`${Ne}/${c.path}.json`,u=await Fe(d);try{const l=Ot.parse(u);return{path:c.path,type:c.type,framework:"framework"in c?c.framework:void 0,content:l.content}}catch{throw new g(S.REGISTRY_FILE_INVALID(c.path))}}));return{item:o,files:p}}r(ce,"getRegistryFiles");async function Ct(e){const t=await ce({type:"tokens",name:e});if(!t.files[0])throw new g(S.STARTER_KIT_UNAVAILABLE(e));return t}r(Ct,"fetchStarterKit");async function le(e,t,n){const s=[],o=new Set;async function i(p){if(o.has(p))return;o.add(p);const c=e.find(u=>u.name===p);if(!c){const u=e.filter(l=>l.type==="component").map(l=>l.name).join(", ");throw new g(`Component '${p}' not found in registry
|
|
99
|
+
Available components: ${u}`)}const d=c.registryDependencies?.[n]||[];for(const u of d)await i(u);s.push(c)}r(i,"resolveComponent");for(const p of t)await i(p);return s}r(le,"resolveTree");async function kt({selectedComponents:e,componentType:t,componentsOutputDirectory:n}){const s={variableCSS:[],utilityCSS:[],componentFiles:[],componentCSS:[],cubeCSS:[],indexFiles:[]},o=await L(),p=(await le(o,e,t)).map(l=>l.name),c=o.filter(l=>l.type==="component").filter(l=>p.includes(l.name)),d=c.flatMap(l=>l.files.filter(f=>(f.type==="tsx"||f.type==="astro"||f.type==="njk")&&"framework"in f&&f.framework===t).map(f=>A(process.cwd(),R(n,l.name,`${l.name}.${f.type}`))));s.componentFiles=d.filter(l=>P(R(process.cwd(),l)));const u=c.map(l=>{const f=l.name;return A(process.cwd(),R(n,l.name,`${f}.css`))});return s.componentCSS=u.filter(l=>P(R(process.cwd(),l))),s}r(kt,"collectComponentOverwriteWarnings");async function Nt({cubeDirectory:e}){const t={variableCSS:[],utilityCSS:[],componentFiles:[],componentCSS:[],cubeCSS:[],indexFiles:[]},s=(await L()).filter(o=>o.type==="cube").flatMap(o=>o.files).map(o=>{const i=o.path.replace(/^styles\//,"");return A(process.cwd(),R(e,i))});return t.cubeCSS=s.filter(o=>P(R(process.cwd(),o))),t}r(Nt,"collectCubeOverwriteWarnings");function Ae(e){const t=[];if(e.variableCSS.length>0&&t.push(`CSS variables files:
|
|
100
|
+
${e.variableCSS.map(s=>` - ${s}`).join(`
|
|
101
101
|
`)}`),e.utilityCSS.length>0&&t.push(`CSS utility files:
|
|
102
|
-
${e.utilityCSS.map(
|
|
102
|
+
${e.utilityCSS.map(s=>` - ${s}`).join(`
|
|
103
103
|
`)}`),e.cubeCSS.length>0&&t.push(`CUBE CSS files:
|
|
104
|
-
${e.cubeCSS.map(
|
|
105
|
-
`)}`),e.componentFiles.length>0||e.componentCSS.length>0){const
|
|
106
|
-
${
|
|
104
|
+
${e.cubeCSS.map(s=>` - ${s}`).join(`
|
|
105
|
+
`)}`),e.componentFiles.length>0||e.componentCSS.length>0){const s=[...e.componentFiles,...e.componentCSS];t.push(`Component files:
|
|
106
|
+
${s.map(o=>` - ${o}`).join(`
|
|
107
107
|
`)}`)}return e.indexFiles.length>0&&t.push(`Index files:
|
|
108
|
-
${e.indexFiles.map(
|
|
108
|
+
${e.indexFiles.map(s=>` - ${s}`).join(`
|
|
109
109
|
`)}`),t.length===0?void 0:`The following file(s) already exist and will be overwritten:
|
|
110
110
|
|
|
111
111
|
${t.join(`
|
|
112
112
|
|
|
113
|
-
`)}`}
|
|
114
|
-
|
|
115
|
-
${
|
|
116
|
-
`)},"intro"),
|
|
117
|
-
${
|
|
118
|
-
|
|
119
|
-
`)},"outro");function x(e){return new Promise(t=>setTimeout(t,e))}
|
|
120
|
-
`);let
|
|
121
|
-
`);const H=
|
|
122
|
-
`);for(const q of H){const[
|
|
123
|
-
`)}
|
|
124
|
-
`)},"box");function
|
|
125
|
-
${e}`;
|
|
126
|
-
${e}`;
|
|
127
|
-
${e}`;
|
|
128
|
-
`),"renderContent");m(
|
|
129
|
-
`))}else{const y=`${t} ${
|
|
130
|
-
`))}else m([..._,...
|
|
131
|
-
`));await x(1e3),
|
|
132
|
-
`),"rawLog"),E={message:
|
|
133
|
-
`);if(
|
|
113
|
+
`)}`}r(Ae,"formatOverwriteWarnings");async function ue(e,t,n,s={}){if(e.length===0)return;const{devDependency:o=!1}=s,i=n==="npm"?"install":"add",p=(()=>{if(!o)return[];switch(n){case"npm":return["--save-dev"];case"pnpm":return["-D"];case"yarn":return["-D"];case"bun":return["-d"]}})();try{await rt(n,[i,...p,...e],{cwd:t})}catch{throw new g(S.DEPENDENCY_INSTALL_FAILED(n))}}r(ue,"installDependencies");async function Ft(e,t,n){const s=R(n,t.name);if(await G(s,{recursive:!0}),e.path.endsWith(".css")){const i=R(s,`${t.name}.css`);return await se(i,e.content),i}const o=R(s,Se(e.path));return await se(o,e.content),o}r(Ft,"writeComponentFile");async function At({registryIndex:e,selectedComponents:t,componentType:n,componentsOutputDirectory:s,packageManager:o}){const i=[],p=new Set;await G(s,{recursive:!0});const c=await le(e,t,n);for(const d of c){const u=await ce({type:"component",name:d.name,framework:n});for(const f of u.files)if(f)try{const m=await Ft(f,d,s);m&&i.push(m)}catch(m){const b=m instanceof Error?`: ${m.message}`:"";throw new g(`Failed to write component file for "${d.name}"${b}`)}const l=d.dependencies?.[n]||[];for(const f of l)p.add(f)}if(p.size>0)try{await ue(Array.from(p),process.cwd(),o)}catch(d){const u=d instanceof Error?`: ${d.message}`:"";throw new g(`Failed to install component dependencies${u}`)}return{createdFiles:i,npmDependencies:p}}r(At,"installComponents");async function Dt(){const e=await re({message:"Choose a token starter kit",options:[{label:"Fluid",value:"fluid",hint:"Fluid spacing and typography"},{label:"Static",value:"static",hint:"Fixed spacing and typography"},{label:"Skip",value:"skip",hint:"Continue without design tokens"}]});return W(e)&&process.exit(0),e==="skip"?null:e}r(Dt,"promptStarterKit");async function de(e,t){const n=await re({message:e,options:[{label:"Add",value:!0},{label:"Skip",value:!1,hint:t}]});return W(n)&&process.exit(0),n}r(de,"promptOptional");async function De(e=!0){const t=[{label:"React",value:"react",hint:".tsx"},{label:"CSS Only",value:"css-only",hint:".css"},{label:a.dim("Web components"),value:"web-components",hint:"Coming soon!"}];e&&t.push({label:"Skip",value:"skip",hint:"continue without components"});const n=await re({message:"Build with",options:t});return W(n)&&process.exit(0),n==="web-components"?(ot.info(a.blue("Web components are coming soon! Please choose React or CSS Only for now.")),De(e)):n}r(De,"promptComponentFramework");async function Pt(e,t){const n=e.filter(o=>o.type==="component"&&o.frameworks?.includes(t)),s=await it({message:"Select components to add",options:n.map(o=>({label:o.name,value:o.name,hint:o.description})),required:!0});return W(s)&&process.exit(0),s}r(Pt,"promptComponentSelectionFiltered");async function Pe(e,t=!1,{exitOnDecline:n=!0}={}){const s=await at({message:e,initialValue:t});return!s||W(s)?(n&&(be(),process.exit(0)),!1):!0}r(Pe,"confirmOverwrite");function Lt(e=process.cwd()){return P(yt.resolve(e,"src"))}r(Lt,"hasSrcDir");function pe(e){const t=Lt(e);return{isSrcDir:t,tokensDir:t?"src/design-tokens":"design-tokens",stylesDir:t?"src/styles":"styles",componentDir:t?"src/components/ui":"components/ui"}}r(pe,"getProjectInfo");function M(e){return{absolute:U(process.cwd(),e)}}r(M,"resolveDirectoryFromFlag");async function Mt(e){if(e){const{absolute:s}=M(e);return{directory:s}}try{const{config:s}=await z();if(s.cube){const{absolute:o}=M(s.cube);return{directory:o}}}catch(s){if(!Ie(s))throw s}const{stylesDir:t}=pe(process.cwd()),{absolute:n}=M(t);return{directory:n}}r(Mt,"getCubeDir");async function xt(e){if(e){const{absolute:t}=M(e);return{directory:t}}try{const{config:t}=await z(),{absolute:n}=M(t.components??"components/ui");return{directory:n}}catch(t){if(Ie(t)){const{componentDir:n}=pe(process.cwd()),{absolute:s}=M(n);return{directory:s}}throw t}}r(xt,"getComponentsDir");const jt=bt(),v=r((e,t)=>jt?e:t,"unicodeOr"),Ut=v("\u25C7","o"),Le=v("\u250C","T"),N=v("\u2502","|"),fe=v("\u2514","\u2014"),Gt=v("\u2510","T"),Wt=v("\u2518","\u2014"),X=v("\u2500","-"),Bt=v("\u256E","+"),Vt=v("\u256F","+"),Kt=v("\u2570","+"),Yt=v("\u256D","+"),Ht=v("\u25CF","\u2022"),qt=v("\u25C6","*"),Jt=v("\u25B2","!"),zt=v("\u25A0","x"),B=r((e,t=a.bgGreen,n=a.black)=>t(` ${n(e)} `),"label"),V=r(e=>{const t=["[\\u001B\\u009B][[\\]()#;?]*(?:(?:(?:(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]+)*|[a-zA-Z\\d]+(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]*)*)?\\u0007)","(?:(?:\\d{1,4}(?:;\\d{0,4})*)?[\\dA-PRZcf-ntqry=><~]))"].join("|"),n=new RegExp(t,"g");return typeof e=="string"?e.replace(n,""):e},"strip"),K=r((e="",t)=>{process.stdout.write(`
|
|
114
|
+
|
|
115
|
+
${a.gray(Le)}${a.gray(X)} ${e}
|
|
116
|
+
`)},"intro"),Q=r((e="",t)=>{process.stdout.write(`${a.gray(N)}
|
|
117
|
+
${a.gray(fe)}${a.gray(X)} ${e}
|
|
118
|
+
|
|
119
|
+
`)},"outro");function x(e){return new Promise(t=>setTimeout(t,e))}r(x,"sleep");const Zt=[Yt,Bt,Kt,Vt],Xt=[Le,Gt,fe,Wt];function Me(e,t,n,s){let o=n,i=n;return s==="center"?o=Math.floor((t-e)/2):s==="right"&&(o=t-e-n),i=t-o-e,[o,i]}r(Me,"getPaddingForLine");const Qt=r(e=>e,"defaultFormatBorder"),me=r((e="",t="",n)=>{const s=n?.output??process.stdout,o=St(s),p=1*2,c=n?.titlePadding??1,d=n?.contentPadding??2,u=n?.width===void 0||n.width==="auto"?1:Math.min(1,n.width),l=n?.includePrefix?`${N} `:"",f=n?.formatBorder??Qt,m=(n?.rounded?Zt:Xt).map(f),b=f(X),h=f(N),_=o-l.length;let T=Math.floor(o*u)-l.length;if(n?.width==="auto"){const q=e.split(`
|
|
120
|
+
`);let j=V(t).length+c*2;for(const Qe of q){const ye=V(Qe).length+d*2;ye>j&&(j=ye)}const J=j+p;J<T&&(T=J)}T%2!==0&&(T<_?T++:T--);const I=T-p,k=I-c*2,y=V(t).length>k?`${t.slice(0,k-3)}...`:t,[O,C]=Me(V(y).length,I,c,n?.titleAlign),F=Et(e,I-d*2,{hard:!0,trim:!1});s.write(`${l}${m[0]}${b.repeat(O)}${y}${b.repeat(C)}${m[1]}
|
|
121
|
+
`);const H=F.split(`
|
|
122
|
+
`);for(const q of H){const[j,J]=Me(V(q).length,I,d,n?.contentAlign);s.write(`${l}${h}${" ".repeat(j)}${q}${" ".repeat(J)}${h}
|
|
123
|
+
`)}s.write(`${l}${m[2]}${b.repeat(I)}${m[3]}
|
|
124
|
+
`)},"box");function ge(e,t={}){const n=`
|
|
125
|
+
${e}`;me(n,a.black(a.bgRed(" ERROR ")),{width:"auto",titlePadding:2,formatBorder:a.red,...t})}r(ge,"errorBoxWithBadge");function ee(e,t={}){const n=`
|
|
126
|
+
${e}`;me(n,a.black(a.bgYellow(" WARNING ")),{width:"auto",titlePadding:2,formatBorder:a.yellow,...t})}r(ee,"warningBoxWithBadge");function en(e,t={}){const n=`
|
|
127
|
+
${e}`;me(n,a.black(a.bgCyan(" INFO ")),{width:"auto",titlePadding:2,formatBorder:a.cyan,...t})}r(en,"infoBoxWithBadge");const tn=r((e,t)=>{if(!(e.meta&&e.name!=="escape")){if(e.ctrl){if(e.name==="a")return"first";if(e.name==="c"||e.name==="d")return"abort";if(e.name==="e")return"last";if(e.name==="g")return"reset"}return e.name==="return"||e.name==="enter"?"submit":e.name==="backspace"?"delete":e.name==="delete"?"deleteForward":e.name==="abort"?"abort":e.name==="escape"?"exit":e.name==="tab"?"next":e.name==="pagedown"?"nextPage":e.name==="pageup"?"prevPage":e.name==="home"?"home":e.name==="end"?"end":e.name==="up"?"up":e.name==="down"?"down":e.name==="right"?"right":e.name==="left"?"left":!1}},"action"),nn=r(async(e,t={})=>{const{sidebarSymbol:n=a.gray("\u2502"),clear:s=!1,stdin:o=process.stdin,stdout:i=process.stdout}=t,p=Re.createInterface({input:o,escapeCodeTimeout:50}),c=$e(i,{showCursor:!1});Re.emitKeypressEvents(o,p);let d=0,u=!1;const l=r(async()=>{o.off("keypress",f),o.isTTY&&o.setRawMode(!1),p.close(),u=!0,d<e.length-1||s?c.clear():c.done()},"done"),f=r((m,b)=>{o.isTTY&&o.setRawMode(!0);const h=tn(b);if(h==="abort")return l(),process.exit(0);["up","down","left","right"].includes(h)||l()},"handleKeyPress");o.isTTY&&o.setRawMode(!0),o.on("keypress",f);for(const m of e){const b=Array.isArray(m)?m:m.split(" "),h=[];for(const I of[""].concat(b)){I&&h.push(I);const k=h.join(" ").replace(/sugarcube/g,a.cyan("sugarcube")),y=`${n} ${k}`;c(y),u||await new Promise(O=>setTimeout(O,Math.floor(Math.random()*126)+75))}u||await new Promise(I=>setTimeout(I,100));const T=(await Promise.all(b).then(I=>I.join(" "))).replace(/sugarcube/g,a.cyan("sugarcube"));c(`${n} ${T}`),u||await new Promise(I=>setTimeout(I,Math.floor(Math.random()*201)+1200)),d++}o.off("keypress",f),await new Promise(m=>setTimeout(m,100)),l(),o.isTTY&&o.setRawMode(!1),o.removeAllListeners("keypress")},"sayAnimatedInSidebar");function sn(){return Math.floor(Math.random()*551)+200}r(sn,"getRandomTaskDuration");async function rn(e,{sidebarSymbol:t="\u2502",spacing:n=1,stdin:s=process.stdin,stdout:o=process.stdout,initialDelayMs:i=200,minDurationMs:p,successPauseMs:c=300,successMessage:d,successAsOutro:u=!1}={}){const l=r((y,O)=>{let C="";switch(O){case"start":C=`${a.cyan(`\u25B6 ${y.start}`)}`;break;case"pending":C=`${a.dim(`\u25A1 ${y.pending}`)}`;break;case"success":C=`${a.green(`\u2714 ${y.end}`)}`;break;case"end":C=`${a.dim(`\u25A0 ${y.end}`)}`;break}return`${t} ${C}`},"formatWithSidebar"),f=Array.from({length:e.length},()=>"");e.forEach((y,O)=>{f[O]=l(y,"pending")});const m=$e(o),b=_e.createInterface({input:s,escapeCodeTimeout:50});_e.emitKeypressEvents(s,b);const h=r(y=>{y===""&&(m.clear(),b.close(),s.isTTY&&s.setRawMode(!1),process.exit(0)),s.isTTY&&s.setRawMode(!0)},"keypress");s.isTTY&&s.setRawMode(!0),s.on("keypress",h);const _=Array.from({length:Math.max(n,0)},()=>`${t}`),T=r(()=>[..._,...f].join(`
|
|
128
|
+
`),"renderContent");m(T()),await x(i);let I=0;for(const y of e){f[I]=l(y,"start"),m(T());const O=Date.now(),C=y.while();try{await C;const F=Date.now()-O,H=typeof p=="number"?p:sn();F<H&&await x(H-F),f[I]=l(y,"success"),m(T()),await x(c)}catch(F){throw f[I]=`${t} ${a.red(`\u2717 ${y.end} (failed)`)}`,m(T()),y.onError?.(F),s.removeListener("keypress",h),b.close(),s.isTTY&&s.setRawMode(!1),F}I++}const k=e.map(y=>l(y,"end"));if(d)if(u){const y=`${a.gray(fe)}${a.gray(X)} ${a.green(d)}`;m([..._,...k,`${t}`,y].join(`
|
|
129
|
+
`))}else{const y=`${t} ${a.green(d)}`;m([..._,...k,`${t}`,y].join(`
|
|
130
|
+
`))}else m([..._,...k].join(`
|
|
131
|
+
`));await x(1e3),s.removeListener("keypress",h),s.isTTY&&s.setRawMode(!1),b.close(),m.done()}r(rn,"executeTasksInSidebar");const on=r(e=>process.stdout.write(`${e}
|
|
132
|
+
`),"rawLog"),E={message:r((e=[],{symbol:t=a.gray(N),secondarySymbol:n=a.gray(N),output:s=process.stdout,spacing:o=1}={})=>{const i=[];for(let c=0;c<o;c++)i.push(`${n}`);const p=Array.isArray(e)?e:e.split(`
|
|
133
|
+
`);if(p.length>0){const[c,...d]=p;c&&c.length>0?i.push(`${t} ${c}`):i.push(t);for(const u of d)u.length>0?i.push(`${n} ${u}`):i.push(n)}s.write(`${i.join(`
|
|
134
134
|
`)}
|
|
135
|
-
`)},"message"),info:
|
|
136
|
-
`)},"space"),break:
|
|
137
|
-
`)},"break")};function Y(e){if(e instanceof
|
|
135
|
+
`)},"message"),info:r((e,t)=>{E.message(e,{...t,symbol:a.blue(Ht)})},"info"),success:r((e,t)=>{E.message(e,{...t,symbol:a.green(qt)})},"success"),step:r((e,t)=>{E.message(e,{...t,symbol:a.green(Ut)})},"step"),warn:r((e,t)=>{E.message(e,{...t,symbol:a.yellow(Jt)})},"warn"),error:r((e,t)=>{E.message(e,{...t,symbol:a.red(zt)})},"error"),animated:r(async(e,{secondarySymbol:t=a.gray(N),output:n=process.stdout,clear:s=!1,...o}={})=>nn(e,{sidebarSymbol:t,stdout:n,clear:s,...o}),"animated"),tasks:r(async(e,{spacing:t=1,secondarySymbol:n=a.gray(N),output:s=process.stdout,...o}={})=>rn(e,{sidebarSymbol:n,spacing:t,stdout:s,...o}),"tasks"),space:r((e=1)=>{for(let t=0;t<e;t++)process.stdout.write(`${a.gray(N)}
|
|
136
|
+
`)},"space"),break:r((e=1)=>{for(let t=0;t<e;t++)process.stdout.write(`
|
|
137
|
+
`)},"break")};function Y(e){if(e instanceof g)E.space(1),ge(e.message,{});else{const t=`An unexpected error occurred: ${e instanceof Error?e.message:String(e)}
|
|
138
138
|
|
|
139
|
-
If this issue persists, please report it: ${
|
|
139
|
+
If this issue persists, please report it: ${a.cyan("https://github.com/sugarcube-sh/sugarcube/issues")}`;E.space(1),ge(t,{})}process.exit(1)}r(Y,"handleError");function xe(e,t=process.cwd()){try{const n=ve(t,"package.json");if(!P(n))return!1;const s=tt(n,"utf-8"),o=JSON.parse(s),i={...o.dependencies,...o.devDependencies,...o.peerDependencies};return e in i}catch{return!1}}r(xe,"isPackageInstalled");async function je(e,{withFallback:t=!1}={}){const n=await It({programmatic:!0,cwd:e});if(n?.includes("yarn"))return"yarn";if(n?.includes("pnpm"))return"pnpm";if(n?.includes("bun"))return"bun";if(n?.includes("npm"))return"npm";if(t){const s=process.env.npm_config_user_agent||"";if(s.includes("yarn"))return"yarn";if(s.includes("pnpm"))return"pnpm";if(s.includes("bun"))return"bun"}return"npm"}r(je,"getPackageManager");async function Ue(e=[],t={}){!t.silent&&!t.skipIntro&&K(B(a.bgGreen(a.black("Components"))));const{directory:n}=await xt(t.output);let s=[],o;if(e.length>0||t.framework){if(!t.framework)throw new g(S.COMPONENTS_FRAMEWORK_REQUIRED());if(!["react","css-only"].includes(t.framework))throw new g(S.COMPONENTS_INVALID_FRAMEWORK());o=t.framework,s=e}else{o=await De(!1);const h=await L();h||(be("Failed to fetch component list"),process.exit(1)),s=await Pt(h,o)}const i=await je(process.cwd(),{withFallback:!0}),p=await L(),c=await le(p,s,o),d=await kt({selectedComponents:s,componentType:o,componentsOutputDirectory:n}),u=Ae(d);if(u&&!t.overwrite&&!t.silent&&(ee(u,{}),E.space(1),!await Pe("Continue?",!1,{exitOnDecline:!t.continueOnDecline})))return;const l=[],f=[],m=new Set;for(const h of c){const _=h.dependencies?.[o]||[];for(const T of _)m.add(T)}const b=Array.from(m).filter(h=>!xe(h,process.cwd()));b.length>0&&l.push({pending:`Install ${b.length} dependencies`,start:`Installing ${b.join(", ")}...`,end:`Installed ${b.join(", ")}`,while:r(async()=>{await ue(b,process.cwd(),i)},"while")});for(const h of c)l.push({pending:`Write component files for ${h.name}`,start:`Writing component files for ${h.name}...`,end:`Wrote component files for ${h.name}`,while:r(async()=>{const _=await At({registryIndex:p,selectedComponents:[h.name],componentType:o,componentsOutputDirectory:n,overwrite:t.overwrite||!1,packageManager:i});f.push(..._.createdFiles)},"while")});await E.tasks(l,{minDurationMs:0,...t.skipOutro?{}:{successMessage:"Components added successfully! \u{1F389} ",successAsOutro:!0}}),t.skipOutro||on("")}r(Ue,"runComponents");const an=new D().name("components").description("Add components to your project").argument("[components...]","Components to add (e.g., button card)").option("-f, --framework <type>","Framework to use (react, css-only)").option("--output <dir>","Components output directory (e.g., 'src/components')").option("-s, --silent","Suppress logs and prompts").option("-o, --overwrite","Overwrite existing files").action(async(e,t)=>{try{await Ue(e,t)}catch(n){Y(n)}});function cn(e,t){const n=U(e),s=U(t),o=A(s,n);return!o.startsWith("..")&&!st(o)}r(cn,"isWithinDirectory");async function ln(e){const t=[],n=U(process.cwd(),e);await G(n,{recursive:!0});const o=(await L()).filter(i=>i.type==="cube").map(i=>i.name);for(const i of o){const p=await ce({type:"cube",name:i});for(const c of p.files){if(!c)continue;const d=c.path.replace(/^styles\//,""),u=U(n,d);if(!cn(u,n))throw new g(`Invalid file path detected in CUBE module "${i}": path escapes target directory`);const l=nt(u);try{await G(l,{recursive:!0}),await se(u,c.content),t.push(u)}catch(f){const m=f instanceof Error?`: ${f.message}`:"";throw new g(`Failed to write CUBE module "${i}"${m}`)}}}return t}r(ln,"installCUBE");async function Ge(e={}){!e.silent&&!e.skipIntro&&K(B("CUBE CSS"));const{directory:t}=await Mt(e.output);try{await G(t,{recursive:!0})}catch(i){const p=i instanceof Error?`: ${i.message}`:"";throw new g(`Failed to create output directory${p}`)}const n=await Nt({cubeDirectory:t}),s=Ae(n);if(s&&!e.force&&!e.silent&&(E.space(1),ee(s,{}),!await Pe("Continue?",!1,{exitOnDecline:!e.continueOnDecline})))return;const o=await ln(t);if(!e.silent){E.space(1);const i=o,d=[...new Set(i)].map(u=>A(process.cwd(),u)).map(u=>({pending:`Write ${u}`,start:`Writing ${u}`,end:`Wrote ${u}`,while:r(async()=>{},"while")}));await E.tasks(d,{spacing:0,minDurationMs:0,successPauseMs:100,...e.skipOutro?{}:{successMessage:"\u{1F389} Files written!"}}),e.skipOutro||Q(a.green("CUBE added successfully."))}}r(Ge,"runCube");const un=new D().name("cube").description("Add CUBE CSS to your project").option("-s, --silent","Suppress logs and prompts").option("-f, --force","Skip overwrite confirmation").option("-o, --output <dir>","CUBE CSS output directory").action(async e=>{try{await Ge(e)}catch(t){Y(t)}});async function he(e,t){let n;if(t)n={type:"memory",data:t,config:e};else{if(!e.resolver)throw new g(S.RESOLVER_NOT_CONFIGURED());n={type:"resolver",resolverPath:e.resolver,config:e}}const{trees:s,resolved:o,errors:i,warnings:p}=await ct(n);if(i.load.length>0){const c=i.load.map(d=>{const u=d.file.split("/").pop()||"unknown file";let l=`File ${u}: `;return d.message.includes("Unexpected token")?l=S.TOKEN_FILE_INVALID_JSON(u):d.message.includes("Unexpected end")?l=S.TOKEN_FILE_INCOMPLETE_JSON(u):l=S.TOKEN_FILE_GENERIC_ERROR(u,d.message),l});throw new g(S.TOKEN_LOAD_FAILED(c))}if(i.validation.length>0||i.flatten.length>0||i.resolution.length>0){const c=[...i.flatten,...i.validation,...i.resolution],d=new Map;for(const u of c)if(u.source?.sourcePath){const l=d.get(u.source.sourcePath)||[];l.push(u.message),d.set(u.source.sourcePath,l)}throw new g(S.TOKEN_VALIDATION_FAILED(d))}return{trees:s,resolved:o,warnings:p}}r(he,"loadAndResolveTokensForCLI");const We=new Set(["html","htm","js","ts","jsx","tsx","vue","svelte","astro","php","njk","liquid","pug","hbs","handlebars","twig","erb","ejs"]),Be=new Set(["node_modules","dist","build",".next",".nuxt",".astro",".git","coverage",".pnpm",".pnpm-store",".npm",".cache",".turbo",".vercel",".svelte-kit","out","__snapshots__"]),dn=[...Array.from(Be,e=>`**/${e}/**`),"**/*.config.{js,ts,mjs}","**/*.min.js","**/*.bundle.js","**/*.d.ts"],pn=`**/*.{${[...We].join(",")}}`,Ve=1e4,Ke=100,fn=Ke*1024*1024;async function mn(){const e=await ie([pn],{ignore:dn,dot:!1,onlyFiles:!0,absolute:!1});if(e.length>Ve)throw new g(`Found ${e.length} files to scan (limit: ${Ve}). Are you running this from a monorepo root or a directory containing multiple projects? Run the command from within a single project directory instead.`);return e}r(mn,"getMarkupFiles");async function gn(e){const t=[];let n=0;for(const s of e){const o=await Ee(s,"utf8");if(n+=o.length,n>fn)throw new g(`Total source size exceeds ${Ke}MB. Are you running this from a monorepo root or a directory containing multiple projects? Run the command from within a single project directory instead.`);t.push(o)}return t}r(gn,"readMarkupSources");function hn(e,t){let n;const s=r((...o)=>{n&&clearTimeout(n),n=setTimeout(()=>{n=void 0,e(...o)},t)},"debounced");return s.cancel=()=>{n&&(clearTimeout(n),n=void 0)},s}r(hn,"debounce");async function wn(e,t){if(!e.resolver)throw new Error("Resolver path is required for watch mode");const{filePaths:n,resolverPath:s}=await lt(e.resolver),o=[s,...n],i=hn(async u=>{try{await t.onRegenerate(u)}catch(l){t.onError(l instanceof Error?l:new Error(String(l)))}},100),p=Oe(o,{ignoreInitial:!0,awaitWriteFinish:{stabilityThreshold:50,pollInterval:10}}),c=Oe(".",{ignoreInitial:!0,ignored:r((u,l)=>{const f=u.split("/");for(const m of f)if(Be.has(m))return!0;if(l?.isFile()){const m=yn(u);return!We.has(m)}return!1},"ignored"),awaitWriteFinish:{stabilityThreshold:50,pollInterval:10}}),d=r(u=>{i(u)},"handleChange");return p.on("change",d),p.on("add",d),p.on("unlink",d),c.on("change",d),c.on("add",d),c.on("unlink",d),await Promise.all([new Promise(u=>p.once("ready",u)),new Promise(u=>c.once("ready",u))]),t.onReady(o.length),{close:r(async()=>{i.cancel(),await Promise.all([p.close(),c.close()])},"close")}}r(wn,"startWatcher");function yn(e){const t=e.lastIndexOf(".");return t===-1?"":e.slice(t+1).toLowerCase()}r(yn,"getExtension");const Sn=`/* Generated by @sugarcube-sh/cli v${Ce.version} */
|
|
140
140
|
|
|
141
|
-
`;function te(e,t){return e?Number.parseInt(e,10):t}
|
|
142
|
-
`),{css:
|
|
141
|
+
`;function En(e){if(!e||e.length===0)return{};const t={};for(const n of e){const[s,o]=n.split("=");s&&o&&(t[s]=o)}return t}r(En,"parseInputFlags");function te(e,t){return e?Number.parseInt(e,10):t}r(te,"parseFluidValue");function bn(e){if(!(!e.fluidMin&&!e.fluidMax))return{min:te(e.fluidMin,320),max:te(e.fluidMax,1200)}}r(bn,"buildFluidConfig");function Ye(e,t){const n=En(t.input);return Object.keys(n).length===0?e:(e.variables.permutations&&e.variables.permutations.length>0&&(E.space(1),ee("Config permutations ignored due to --input flag")),{...e,variables:{...e.variables,permutations:[{input:n,selector:t.selector??":root"}]}})}r(Ye,"applyInputFlags");function He(e){const t={resolver:e.resolver,variables:{path:e.variables,transforms:{fluid:bn(e),colorFallbackStrategy:e.colorFallback}},utilities:{path:e.utilities}};return Ye(dt(t),e)}r(He,"buildConfigFromFlags");function In(e,t){const n={...e,resolver:t.resolver??e.resolver,variables:{...e.variables,path:t.variables??e.variables.path,transforms:{fluid:{min:te(t.fluidMin,e.variables.transforms.fluid.min),max:te(t.fluidMax,e.variables.transforms.fluid.max)},colorFallbackStrategy:t.colorFallback??e.variables.transforms.colorFallbackStrategy}},utilities:{...e.utilities,path:t.utilities??e.utilities.path}};return Ye(n,t)}r(In,"mergeConfigWithFlags");function Tn(e){return!!(e.resolver||e.variables||e.utilities||e.fluidMin||e.fluidMax||e.colorFallback)}r(Tn,"hasConfigFlags");async function vn(e){if(Te()){const{config:s}=await z();return In(s,e)}if(e.resolver)return He(e);const t=await ut(process.cwd());if(t.found==="multiple")throw new g(S.GENERATE_MULTIPLE_RESOLVERS_NO_CONFIG(t.paths));const n=t.found==="one"?t.path:void 0;if(n||Tn(e))return He({...e,resolver:n});throw new g(S.GENERATE_NO_CONFIG_OR_RESOLVER())}r(vn,"resolveConfig");function qe(e){const t=e.map(s=>s.path);return[...new Set(t)].map(s=>A(process.cwd(),s))}r(qe,"formatOutputPaths");async function _n(e,t){if(!t.utilities.classes||Object.keys(t.utilities.classes).length===0)return[];const s={presets:[{name:"sugarcube",rules:wt(t.utilities.classes,e),preflights:[]}]},o=await Tt(s),i=await mn();if(i.length===0)return[];const c=(await gn(i)).join(`
|
|
142
|
+
`),{css:d}=await o.generate(c,{preflights:!1});return d?.trim()?[{path:t.utilities.path,css:d}]:[]}r(_n,"generateSugarcubeUtilities");function Je(e){return e.map(t=>({...t,css:Sn+t.css}))}r(Je,"addBanner");function ze(e,t){return e.map(n=>{const s=n.css.split(`
|
|
143
143
|
`).map(o=>o.trim()?` ${o}`:o).join(`
|
|
144
144
|
`);return{...n,css:`@layer ${t} {
|
|
145
|
-
${
|
|
146
|
-
`}})}
|
|
147
|
-
|
|
145
|
+
${s}}
|
|
146
|
+
`}})}r(ze,"wrapInLayer");async function Rn(e,t,n,s={}){const o=[],i=await ft(e,t,n);if(!s.utilitiesOnly){let p=await mt(i,n);n.variables.layer&&(p=ze(p,n.variables.layer));const c=Je(p);await gt(c),o.push(...c)}if(!s.variablesOnly){let p=await _n(i,n);n.utilities.layer&&(p=ze(p,n.utilities.layer));const c=Je(p);await ht(c),o.push(...c)}return o}r(Rn,"generateAllCSS");async function we(e,t={}){pt();const{trees:n,resolved:s,warnings:o}=await he(e);return{output:await Rn(n,s,e,t),warnings:o}}r(we,"runGeneration");function $n(e){if(e.length===0)return;const t=e.map(n=>n.message).join(`
|
|
147
|
+
|
|
148
|
+
`);E.space(1),ee(t)}r($n,"displayWarnings");async function On(e){const t=e.map(n=>({pending:`Write ${n}`,start:`Writing ${n}`,end:`Wrote ${n}`,while:r(async()=>{},"while")}));await E.tasks(t,{spacing:1,minDurationMs:0,successPauseMs:100,successMessage:"\u{1F389} Files written!"}),E.space(1),Q(a.green("CSS generated successfully."))}r(On,"logOneTimeResult");async function Cn(e,t){const{output:n,warnings:s}=await we(e,{variablesOnly:t.variablesOnly,utilitiesOnly:t.utilitiesOnly});t.silent||($n(s),await On(qe(n)))}r(Cn,"runOneTimeGeneration");async function kn(e,t){const n=a.cyan("[sugarcube]"),s=a.yellow("[sugarcube]"),o={variablesOnly:t.variablesOnly,utilitiesOnly:t.utilitiesOnly},i=r(f=>{for(const m of f)console.log(`${s} ${m.message}`)},"logWarnings"),p=performance.now(),{output:c,warnings:d}=await we(e,o),u=Math.round(performance.now()-p);i(d),console.log(`${n} Generated in ${u}ms`);const l=await wn(e,{onRegenerate:r(async f=>{const m=performance.now(),{output:b,warnings:h}=await we(e,o),_=Math.round(performance.now()-m);i(h);const T=f.split("/").pop()??f,I=qe(b);console.log(`${n} ${a.dim(T)} \u2192 ${I.join(", ")} ${a.dim(`(${_}ms)`)}`)},"onRegenerate"),onError:r(f=>{console.log(`${a.red("[sugarcube]")} ${f.message}`)},"onError"),onReady:r(f=>{console.log(`${n} Watching ${f} token file${f===1?"":"s"} + markup files...`)},"onReady")});process.on("SIGINT",async()=>{await l.close(),console.log(`${n} Watch mode stopped.`),process.exit(0)}),await new Promise(()=>{})}r(kn,"runWatchMode");const Nn=new D().name("generate").description("Generate CSS from your design tokens").option("--force","Skip overwrite confirmation").option("-s, --silent","Suppress logs and prompts").option("-w, --watch","Watch for changes and regenerate automatically").option("--resolver <path>","Path to token resolver file (.resolver.json)").option("--variables <path>","Output path for CSS variables (default: 'src/styles/tokens.css')").option("--utilities <path>","Output path for utility classes (default: 'src/styles/utilities.css')").option("--fluid-min <number>","Minimum viewport width for fluid scaling (default: 320)").option("--fluid-max <number>","Maximum viewport width for fluid scaling (default: 1200)").option("--color-fallback <strategy>","Color fallback strategy: 'native' or 'polyfill' (default: native)").option("--input <modifier=value>","Select a modifier context for this build (repeatable)",(e,t)=>t.concat([e]),[]).option("--selector <selector>","CSS selector for --input output (default: ':root')").option("--variables-only","Generate only CSS variables, skip utilities").option("--utilities-only","Generate only utilities, skip CSS variables").action(async e=>{try{!e.silent&&!e.watch&&K(B("Generate CSS"));const t=await vn(e);await(e.watch?kn:Cn)(t,e)}catch(t){Y(t)}}),Fn="@sugarcube-sh/vite",Ze="@sugarcube-sh/cli",An="**/*.json",Dn=20;function Xe(e,t=0){if(typeof e!="object"||e===null||t>Dn)return!1;for(const[n,s]of Object.entries(e))if(!n.startsWith("$")&&typeof s=="object"&&s!==null&&("$value"in s||Xe(s,t+1)))return!0;return!1}r(Xe,"hasAnyToken");async function Pn(e){try{const t=await ie([An],{cwd:e,absolute:!0});for(const n of t)try{const s=await ne.readFile(n,"utf-8"),o=JSON.parse(s);if(Xe(o))return!0}catch{}return!1}catch{return!1}}r(Pn,"detectExistingTokens");async function Ln(e,t){await ne.mkdir(t,{recursive:!0});const n=[];for(const s of e)await ne.writeFile(s.path,s.content),n.push(s.path);return n}r(Ln,"writeTokenFiles");async function Mn(e){E.space(2),await x(200);const t=["Next steps",""];e.installedVitePlugin?(t.push(`Add the plugin to your ${a.cyan("vite.config.ts")}:`),t.push(""),t.push(a.dim(" import sugarcube from '@sugarcube-sh/vite'")),t.push(a.dim("")),t.push(a.dim(" export default defineConfig({")),t.push(a.dim(" plugins: [await sugarcube()],")),t.push(a.dim(" })"))):t.push(`Generate styles: ${a.cyan("sugarcube generate")}`),t.push(""),t.push(`Stuck? ${a.cyan($.DOCS)}`),en(t.join(`
|
|
149
|
+
`),{width:.75}),await x(200),E.break(1)}r(Mn,"next");const xn=r(async()=>{const e=["Welcome to sugarcube \u2014 the toolkit for seriously sweet frontends!"];E.space(1),await E.animated(e,{clear:!1})},"welcome");async function jn(){Te()&&(ge(S.CONFIG_EXISTS(),{}),process.exit(1))}r(jn,"preflightInit");async function Un(e){if(!e.starterKit)return;const t=ve(process.cwd(),e.tokensDir),s=(await Ct(e.starterKit)).files.map(i=>({path:R(t,Se(i.path)),content:i.content})),o=await Ln(s,t);e.createdFiles.push(...o)}r(Un,"scaffoldTokens");const Gn=new D().name("init").description("Initialize a new sugarcube project").option("--tokens <dir>","Design tokens directory").option("--cube <dir>","CUBE CSS output directory").option("--components <dir>","Components output directory").action(async e=>{try{process.stdin.isTTY||(console.error("init requires an interactive terminal. Use individual commands (cube, components, generate) for CI."),process.exit(1)),await jn();const{tokensDir:t}=pe(process.cwd()),n=e.tokens??t,s=await Pn(n),o={options:e,tokensDir:n,hasExistingTokens:s,starterKit:null,sugarcubeConfig:{},createdFiles:[]};K(B("sugarcube")),await xn();const i=[{pending:"Detect existing tokens",start:"Detecting existing tokens...",end:s?`Existing design tokens found at ${n} \u2014 using those!`:"No existing design tokens found \u2014 prompting for starter kit",while:r(async()=>{},"while")}];await E.tasks(i),s||(o.starterKit=await Dt()),o.starterKit&&await E.tasks([{pending:"Add design tokens",start:"Adding design tokens...",end:"Design tokens added",while:r(async()=>{await Un(o)},"while")}]),await de("CUBE CSS?",`you can add it later with ${a.cyan("sugarcube cube")}`)&&await Ge({skipIntro:!0,skipOutro:!0,continueOnDecline:!0,output:e.cube}),await de("Components?",`you can add them later with ${a.cyan("sugarcube components")}`)&&await Ue([],{skipIntro:!0,skipOutro:!0,continueOnDecline:!0,output:e.components});const d=await de(`Vite plugin? ${a.dim("(recommended for Vite-based frameworks: Astro, SvelteKit...)")}`,`you can install it later: ${a.cyan("@sugarcube-sh/vite")}`),u=await je(process.cwd(),{withFallback:!0}),l=[];xe(Ze,process.cwd())||l.push(Ze),d&&l.push(Fn),l.length>0&&await E.tasks([{pending:`Install ${l.join(", ")}`,start:`Installing ${l.join(", ")}...`,end:`Installed ${l.join(", ")}`,while:r(async()=>{await ue(l,process.cwd(),u,{devDependency:!0})},"while")}]),E.success("\u{1F389} Project initialized!"),await Mn({installedVitePlugin:d})}catch(t){Y(t)}}),Wn=new D().name("validate").description("Validate design token files").argument("[paths...]","Token files or directories to validate (e.g., src/design-tokens)").action(async e=>{try{if(K(B("Validate")),!e.length)try{const{config:i}=await z();await he(i),Q(a.greenBright("All tokens valid \u2728"));return}catch{throw new g(S.VALIDATE_NO_PATH_SPECIFIED())}for(const i of e)if(!P(i))throw new g(S.VALIDATE_PATH_NOT_FOUND(i));const n=(await ie(e.map(i=>i.endsWith(".json")?i:R(i,"**/*.json")),{absolute:!0})).filter(i=>!i.endsWith(".resolver.json"));if(n.length===0)throw new g(S.VALIDATE_NO_TOKEN_FILES());const s={};for(const i of n){const p=await Ee(i,"utf-8"),c=A(process.cwd(),i);s[c]={content:p}}const o={variables:{path:oe.variables.filename,transforms:oe.variables.transforms},utilities:{path:oe.utilities.filename}};await he(o,s),Q(a.greenBright("All tokens valid \u2728"))}catch(t){Y(t)}});process.on("SIGINT",()=>process.exit(0)),process.on("SIGTERM",()=>process.exit(0));async function Bn(){const e=new D().name("sugarcube").description("CLI for sugarcube").version(Ce.version,"-v, --version","display the version number");e.addCommand(Gn).addCommand(Nn).addCommand(Wn).addCommand(an).addCommand(un),e.parse()}r(Bn,"main"),Bn();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sugarcube-sh/cli",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.6",
|
|
4
4
|
"publishConfig": {
|
|
5
5
|
"access": "public",
|
|
6
6
|
"provenance": false
|
|
@@ -59,7 +59,7 @@
|
|
|
59
59
|
"picocolors": "1.1.1",
|
|
60
60
|
"tinyglobby": "^0.2.9",
|
|
61
61
|
"zod": "^3.23.8",
|
|
62
|
-
"@sugarcube-sh/core": "0.
|
|
62
|
+
"@sugarcube-sh/core": "0.2.0"
|
|
63
63
|
},
|
|
64
64
|
"devDependencies": {
|
|
65
65
|
"cross-env": "7.0.3",
|