@sugarcube-org/cli 0.0.0-alpha.35 → 0.0.0-alpha.37
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/exports.d.mts +1 -0
- package/dist/exports.mjs +1 -0
- package/dist/index.mjs +83 -100
- package/package.json +8 -5
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { SugarcubeConfig, defineConfig } from '@sugarcube-org/core';
|
package/dist/exports.mjs
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{defineConfig as o}from"@sugarcube-org/core";export{o as defineConfig};
|
package/dist/index.mjs
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
var et=Object.defineProperty;var
|
|
2
|
+
var et=Object.defineProperty;var r=(e,t)=>et(e,"name",{value:t,configurable:!0});import{Command as P}from"commander";import{relative as D,join as R,basename as ye,resolve as U,dirname as tt,isAbsolute as nt,normalize as st}from"pathe";import c from"picocolors";import{existsSync as N,readFileSync as Te}from"node:fs";import{z as y}from"zod";import se,{mkdir as V,writeFile as Q,readFile as Ie}from"node:fs/promises";import{execa as rt}from"execa";import{loadAndResolveTokens as it,findResolverDocument as re,loadInternalConfig as X,isNoConfigError as be,configFileExists as Se,processAndConvertTokens as ie,generateCSSVariables as Ee,writeCSSVariablesToDisk as ke,writeCSSUtilitiesToDisk as ve,fillDefaults as Re,convertConfigToUnoRules as ot,DEFAULT_CONFIG as _e}from"@sugarcube-org/core";import{select as at,isCancel as oe,log as ct,multiselect as lt,confirm as ut,cancel as $e}from"@clack/prompts";import{getColumns as dt}from"@clack/core";import{wrapAnsi as ft}from"fast-wrap-ansi";import pt from"is-unicode-supported";import*as Ce from"node:readline";import De from"node:readline";import{createLogUpdate as Ne}from"log-update";import ae,{resolve as mt}from"node:path";import{detect as gt}from"@antfu/ni";import{createGenerator as ht}from"@unocss/core";import{glob as ce}from"tinyglobby";import{getTsconfig as wt}from"get-tsconfig";var yt="0.0.0-alpha.37",Tt={version:yt};const le="fluid",It="**/*.json",Fe="@sugarcube-org/vite",bt="@sugarcube-org/cli",St=["node_modules",".git",".next","dist","build"],Et=5,F={INIT:"make-sugarcube init",COMPONENTS:"make-sugarcube components",CUBE:"make-sugarcube cube"},Oe={INITIALIZATION:"https://sugarcube.sh/docs/setup",CONFIGURATION:"https://sugarcube.sh/docs/configuration"},g={PROJECT_REQUIRED:`No sugarcube project detected. Please run ${c.cyan(F.INIT)} first.
|
|
3
3
|
|
|
4
|
-
For more information, visit: ${c.cyan(
|
|
4
|
+
For more information, visit: ${c.cyan(Oe.INITIALIZATION)}`,CONFIG_EXISTS:r(()=>`A sugarcube config file already exists in this project.
|
|
5
5
|
|
|
6
|
-
To start over, remove it and run ${c.cyan(
|
|
6
|
+
To start over, remove it and run ${c.cyan(F.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,30 +12,39 @@ 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
|
-
https://github.com/sugarcube-org/sugarcube/issues`},"PLUGIN_INSTALL_FAILED"),
|
|
15
|
+
https://github.com/sugarcube-org/sugarcube/issues`},"PLUGIN_INSTALL_FAILED"),CLI_INSTALL_FAILED:r(e=>{const t=e.packageManager==="npm"?"install":"add";return`Failed to install @sugarcube-org/cli.
|
|
16
|
+
|
|
17
|
+
This is usually a temporary issue. Try these steps:
|
|
18
|
+
|
|
19
|
+
1. Run the command again
|
|
20
|
+
2. Check your internet connection
|
|
21
|
+
3. Install manually: ${e.packageManager} ${t} -D @sugarcube-org/cli
|
|
22
|
+
|
|
23
|
+
If the problem continues, please open an issue at:
|
|
24
|
+
https://github.com/sugarcube-org/sugarcube/issues`},"CLI_INSTALL_FAILED"),INITIALIZATION_INCOMPLETE:r(()=>`The initialization process was not completed properly.
|
|
16
25
|
This is an internal error that should not occur.
|
|
17
26
|
Try running the \`init\` command again.
|
|
18
27
|
|
|
19
28
|
If the problem persists, please report this issue at
|
|
20
|
-
https://github.com/sugarcube-org/sugarcube/issues`,"INITIALIZATION_INCOMPLETE"),CONFIG_WRITE_FAILED:
|
|
29
|
+
https://github.com/sugarcube-org/sugarcube/issues`,"INITIALIZATION_INCOMPLETE"),CONFIG_WRITE_FAILED:r(()=>"Failed to write configuration file. Check permissions and try again.","CONFIG_WRITE_FAILED"),DIRECTORY_PATH_EMPTY:r(e=>`${e} cannot be empty. Please provide a valid directory path.`,"DIRECTORY_PATH_EMPTY"),DIRECTORY_PATH_RESERVED:r((e,t)=>`Option: ${e}
|
|
21
30
|
Value: "${t}"
|
|
22
31
|
|
|
23
|
-
${e} cannot be in a reserved directory`,"DIRECTORY_PATH_RESERVED"),KIT_INCOMPLETE:
|
|
32
|
+
${e} cannot be in a reserved directory`,"DIRECTORY_PATH_RESERVED"),KIT_INCOMPLETE:r(()=>`The starter kit appears to be incomplete or corrupted.
|
|
24
33
|
|
|
25
|
-
This is likely a temporary issue. Please try running the command again or choose a different starter kit.`,"KIT_INCOMPLETE"),REGISTRY_AUTH_REQUIRED:
|
|
26
|
-
URL: ${c.cyan(e)}`,"REGISTRY_AUTH_REQUIRED"),REGISTRY_AUTH_INVALID:
|
|
27
|
-
URL: ${c.cyan(e)}`,"REGISTRY_AUTH_INVALID"),REGISTRY_NOT_FOUND:
|
|
28
|
-
URL: ${c.cyan(e)}`,"REGISTRY_NOT_FOUND"),REGISTRY_REQUEST_FAILED:
|
|
29
|
-
URL: ${c.cyan(t)}`,"REGISTRY_REQUEST_FAILED"),REGISTRY_NETWORK_ERROR:
|
|
34
|
+
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
|
|
35
|
+
URL: ${c.cyan(e)}`,"REGISTRY_AUTH_REQUIRED"),REGISTRY_AUTH_INVALID:r(e=>`Registry access denied: Invalid or missing token
|
|
36
|
+
URL: ${c.cyan(e)}`,"REGISTRY_AUTH_INVALID"),REGISTRY_NOT_FOUND:r(e=>`Registry resource not found
|
|
37
|
+
URL: ${c.cyan(e)}`,"REGISTRY_NOT_FOUND"),REGISTRY_REQUEST_FAILED:r((e,t)=>`Registry request failed: ${e}
|
|
38
|
+
URL: ${c.cyan(t)}`,"REGISTRY_REQUEST_FAILED"),REGISTRY_NETWORK_ERROR:r(e=>`Failed to connect to registry
|
|
30
39
|
|
|
31
40
|
URL: ${c.cyan(e)}
|
|
32
41
|
|
|
33
|
-
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:
|
|
34
|
-
URL: ${c.cyan(e)}`,"REGISTRY_INVALID_DATA"),REGISTRY_ITEM_NOT_FOUND:
|
|
35
|
-
Available ${e==="tokens"?"starter kit":e}s: ${n.join(", ")}`,"REGISTRY_ITEM_NOT_FOUND"),REGISTRY_FILE_INVALID:
|
|
36
|
-
File: ${c.cyan(e)}`,"REGISTRY_FILE_INVALID"),STARTER_KIT_UNAVAILABLE:
|
|
42
|
+
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
|
|
43
|
+
URL: ${c.cyan(e)}`,"REGISTRY_INVALID_DATA"),REGISTRY_ITEM_NOT_FOUND:r((e,t,n)=>`${e==="tokens"?"Starter kit":e}'${c.cyan(t)} ' not found in registry
|
|
44
|
+
Available ${e==="tokens"?"starter kit":e}s: ${n.join(", ")}`,"REGISTRY_ITEM_NOT_FOUND"),REGISTRY_FILE_INVALID:r(e=>`Invalid file content received
|
|
45
|
+
File: ${c.cyan(e)}`,"REGISTRY_FILE_INVALID"),STARTER_KIT_UNAVAILABLE:r(e=>`Starter kit '${c.cyan(e)}' is currently unavailable.
|
|
37
46
|
|
|
38
|
-
Please try a different starter kit or run the command again in a few minutes.`,"STARTER_KIT_UNAVAILABLE"),RESOLVER_NOT_CONFIGURED:
|
|
47
|
+
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.
|
|
39
48
|
|
|
40
49
|
Add a resolver path to your sugarcube config:
|
|
41
50
|
|
|
@@ -44,131 +53,103 @@ ${c.cyan(`export default {
|
|
|
44
53
|
// ...
|
|
45
54
|
}`)}
|
|
46
55
|
|
|
47
|
-
See ${c.cyan("https://sugarcube.sh/docs/resolver")} for more information.`,"RESOLVER_NOT_CONFIGURED"),RESOLVER_NOT_FOUND:
|
|
56
|
+
See ${c.cyan("https://sugarcube.sh/docs/resolver")} for more information.`,"RESOLVER_NOT_CONFIGURED"),RESOLVER_NOT_FOUND:r(e=>`No resolver document found in ${c.cyan(e)}.
|
|
48
57
|
|
|
49
58
|
A resolver document (*.resolver.json) is required to define how your tokens are loaded.
|
|
50
59
|
|
|
51
|
-
See ${c.cyan("https://sugarcube.sh/docs/resolver")} to learn how to create one.`,"RESOLVER_NOT_FOUND"),RESOLVER_MULTIPLE_FOUND:
|
|
60
|
+
See ${c.cyan("https://sugarcube.sh/docs/resolver")} to learn how to create one.`,"RESOLVER_NOT_FOUND"),RESOLVER_MULTIPLE_FOUND:r(e=>`Multiple resolver documents found:
|
|
52
61
|
${e.map(t=>` - ${c.cyan(t)}`).join(`
|
|
53
62
|
`)}
|
|
54
63
|
|
|
55
|
-
A project should have only one resolver document. Please remove the extras or consolidate them.`,"RESOLVER_MULTIPLE_FOUND"),TOKEN_LOAD_FAILED:
|
|
64
|
+
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:
|
|
56
65
|
|
|
57
66
|
${e.join(`
|
|
58
67
|
`)}
|
|
59
68
|
|
|
60
|
-
Please check your token files and try again.`,"TOKEN_LOAD_FAILED"),TOKEN_VALIDATION_FAILED:
|
|
69
|
+
Please check your token files and try again.`,"TOKEN_LOAD_FAILED"),TOKEN_VALIDATION_FAILED:r(e=>{let t=`Token validation failed:
|
|
61
70
|
|
|
62
71
|
`;for(const[n,s]of e){t+=`Error(s) in ${c.cyan(n)}:
|
|
63
|
-
`;for(const
|
|
72
|
+
`;for(const i of s)t+=` - ${i}
|
|
64
73
|
`;t+=`
|
|
65
|
-
`}return t+=`See ${c.cyan("https://sugarcube.sh/docs/design-tokens")} for valid token formats`,t},"TOKEN_VALIDATION_FAILED"),TOKEN_FILE_INVALID_JSON:
|
|
66
|
-
Please check your package manager configuration and try again.`,"DEPENDENCY_INSTALL_FAILED"),VALIDATE_NO_PATH_SPECIFIED:
|
|
74
|
+
`}return t+=`See ${c.cyan("https://sugarcube.sh/docs/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}.
|
|
75
|
+
Please check your package manager configuration and try again.`,"DEPENDENCY_INSTALL_FAILED"),VALIDATE_NO_PATH_SPECIFIED:r(()=>`No path specified.
|
|
67
76
|
|
|
68
|
-
Run ${c.cyan("make-sugarcube validate --help")} for more information.`,"VALIDATE_NO_PATH_SPECIFIED"),VALIDATE_PATH_NOT_FOUND:
|
|
77
|
+
Run ${c.cyan("make-sugarcube validate --help")} for more information.`,"VALIDATE_NO_PATH_SPECIFIED"),VALIDATE_PATH_NOT_FOUND:r(e=>`Path not found: ${e}
|
|
69
78
|
|
|
70
|
-
Please check that the specified path exists`,"VALIDATE_PATH_NOT_FOUND"),VALIDATE_NO_TOKEN_FILES:
|
|
79
|
+
Please check that the specified path exists`,"VALIDATE_PATH_NOT_FOUND"),VALIDATE_NO_TOKEN_FILES:r(()=>`No token files found.
|
|
71
80
|
|
|
72
|
-
Please ensure the path contains .json token files`,"VALIDATE_NO_TOKEN_FILES"),COMPONENTS_FRAMEWORK_REQUIRED:
|
|
81
|
+
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.
|
|
73
82
|
|
|
74
|
-
See ${c.cyan("https://sugarcube.sh/docs/cli/components")} for more information.`,"COMPONENTS_FRAMEWORK_REQUIRED"),COMPONENTS_INVALID_FRAMEWORK:
|
|
83
|
+
See ${c.cyan("https://sugarcube.sh/docs/cli/components")} 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}
|
|
75
84
|
|
|
76
85
|
The 'generate' command is for manual generation without plugins. Since you have a plugin installed, use your development server instead:
|
|
77
86
|
|
|
78
87
|
npm run dev # or your framework's dev command
|
|
79
88
|
|
|
80
|
-
The plugin will automatically generate CSS with hot module replacement.`,"PLUGIN_DETECTED"),GENERATE_NO_CONFIG_OR_RESOLVER:
|
|
89
|
+
The plugin will automatically generate CSS with hot module replacement.`,"PLUGIN_DETECTED"),GENERATE_NO_CONFIG_OR_RESOLVER:r(()=>`No design tokens found.
|
|
81
90
|
|
|
82
|
-
|
|
91
|
+
Run ${c.cyan(F.INIT)} to set up your design tokens.
|
|
83
92
|
|
|
84
|
-
Stuck? ${c.cyan("https://sugarcube.sh")}`,"GENERATE_NO_CONFIG_OR_RESOLVER"),GENERATE_MULTIPLE_RESOLVERS_NO_CONFIG:
|
|
93
|
+
Stuck? ${c.cyan("https://sugarcube.sh")}`,"GENERATE_NO_CONFIG_OR_RESOLVER"),GENERATE_MULTIPLE_RESOLVERS_NO_CONFIG:r(e=>`No config file found, but multiple resolver files detected:
|
|
85
94
|
${e.map(t=>` - ${t}`).join(`
|
|
86
95
|
`)}
|
|
87
96
|
|
|
88
97
|
Please either:
|
|
89
|
-
- Create a config file with ${c.cyan(
|
|
90
|
-
- Use --resolver flag to specify which resolver to use`,"GENERATE_MULTIPLE_RESOLVERS_NO_CONFIG")};class p extends Error{static{
|
|
91
|
-
Available components: ${d}`)}const f=l.registryDependencies?.[n]||[];for(const d of f)await
|
|
98
|
+
- Create a config file with ${c.cyan(F.INIT)}
|
|
99
|
+
- Use --resolver flag to specify which resolver to use`,"GENERATE_MULTIPLE_RESOLVERS_NO_CONFIG")};class p extends Error{static{r(this,"CLIError")}constructor(t,n){super(t),this.name="CLIError",this.cause=n}}const ue=y.enum(["react","web-components","css-only"]),Ae=y.object({path:y.string(),type:y.string()}),kt=Ae.extend({framework:ue}),vt=y.object({name:y.string(),type:y.string(),description:y.string().optional(),frameworks:y.array(y.string()).optional(),files:y.array(y.union([kt,Ae])),tokens:y.record(y.object({type:y.string(),mapping:y.string()})).optional(),dependencies:y.record(ue,y.array(y.string())).optional(),registryDependencies:y.record(ue,y.array(y.string())).optional(),tokenDependencies:y.array(y.string()).optional()}),Rt=y.array(vt),_t=y.object({content:y.string()}),Le=process.env.REGISTRY_URL??"https://sugarcube.sh/r";async function Me(e){try{const t=await fetch(e);if(!t.ok){if(t.status===401)throw new p(g.REGISTRY_AUTH_REQUIRED(e));if(t.status===403)throw new p(g.REGISTRY_AUTH_INVALID(e));if(t.status===404)throw new p(g.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 p(g.REGISTRY_REQUEST_FAILED(s,e))}return t.json()}catch(t){throw t instanceof p?t:new p(g.REGISTRY_NETWORK_ERROR(e))}}r(Me,"fetchRegistry");async function j(){const e=`${Le}/index.json`,t=await Me(e);try{return Rt.parse(t)}catch{throw new p(g.REGISTRY_INVALID_DATA(e))}}r(j,"getRegistryIndex");async function de({type:e,name:t,framework:n}){const s=await j(),i=s.find(l=>l.type===e&&l.name===t);if(!i){const l=s.filter(f=>f.type===e).map(f=>f.name);throw new p(g.REGISTRY_ITEM_NOT_FOUND(e,t,l))}let o=i.files;e==="component"&&n&&(o=i.files.filter(l=>"framework"in l&&l.framework===n));const a=await Promise.all(o.map(async l=>{const f=`${Le}/${l.path}.json`,d=await Me(f);try{const u=_t.parse(d);return{path:l.path,type:l.type,framework:"framework"in l?l.framework:void 0,content:u.content}}catch{throw new p(g.REGISTRY_FILE_INVALID(l.path))}}));return{item:i,files:a}}r(de,"getRegistryFiles");async function $t(e){const t=await de({type:"tokens",name:e});if(!t.files[0])throw new p(g.STARTER_KIT_UNAVAILABLE(e));return t}r($t,"fetchStarterKit");async function fe(e,t,n){const s=[],i=new Set;async function o(a){if(i.has(a))return;i.add(a);const l=e.find(d=>d.name===a);if(!l){const d=e.filter(u=>u.type==="component").map(u=>u.name).join(", ");throw new p(`Component '${a}' not found in registry
|
|
100
|
+
Available components: ${d}`)}const f=l.registryDependencies?.[n]||[];for(const d of f)await o(d);s.push(l)}r(o,"resolveComponent");for(const a of t)await o(a);return s}r(fe,"resolveTree");async function Ct({selectedComponents:e,componentType:t,componentsOutputDirectory:n}){const s={variableCSS:[],utilityCSS:[],componentFiles:[],componentCSS:[],cubeCSS:[],indexFiles:[]},i=await j(),a=(await fe(i,e,t)).map(u=>u.name),l=i.filter(u=>u.type==="component").filter(u=>a.includes(u.name)),f=l.flatMap(u=>u.files.filter(m=>(m.type==="tsx"||m.type==="astro"||m.type==="njk")&&"framework"in m&&m.framework===t).map(m=>D(process.cwd(),R(n,u.name,`${u.name}.${m.type}`))));s.componentFiles=f.filter(u=>N(R(process.cwd(),u)));const d=l.map(u=>{const m=u.name;return D(process.cwd(),R(n,u.name,`${m}.css`))});return s.componentCSS=d.filter(u=>N(R(process.cwd(),u))),s}r(Ct,"collectComponentOverwriteWarnings");async function Dt({cubeDirectory:e}){const t={variableCSS:[],utilityCSS:[],componentFiles:[],componentCSS:[],cubeCSS:[],indexFiles:[]},s=(await j()).filter(i=>i.type==="cube").flatMap(i=>i.files).map(i=>{const o=i.path.replace(/^styles\//,"");return D(process.cwd(),R(e,o))});return t.cubeCSS=s.filter(i=>N(R(process.cwd(),i))),t}r(Dt,"collectCubeOverwriteWarnings");function Pe(e){const t=[];if(e.variableCSS.length>0&&t.push(`CSS variables files:
|
|
92
101
|
${e.variableCSS.map(s=>` - ${s}`).join(`
|
|
93
102
|
`)}`),e.utilityCSS.length>0&&t.push(`CSS utility files:
|
|
94
103
|
${e.utilityCSS.map(s=>` - ${s}`).join(`
|
|
95
104
|
`)}`),e.cubeCSS.length>0&&t.push(`CUBE CSS files:
|
|
96
105
|
${e.cubeCSS.map(s=>` - ${s}`).join(`
|
|
97
106
|
`)}`),e.componentFiles.length>0||e.componentCSS.length>0){const s=[...e.componentFiles,...e.componentCSS];t.push(`Component files:
|
|
98
|
-
${s.map(
|
|
107
|
+
${s.map(i=>` - ${i}`).join(`
|
|
99
108
|
`)}`)}return e.indexFiles.length>0&&t.push(`Index files:
|
|
100
109
|
${e.indexFiles.map(s=>` - ${s}`).join(`
|
|
101
110
|
`)}`),t.length===0?void 0:`The following file(s) already exist and will be overwritten:
|
|
102
111
|
|
|
103
112
|
${t.join(`
|
|
104
113
|
|
|
105
|
-
`)}`}
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
${c.cyan(_.INIT)}
|
|
127
|
-
|
|
128
|
-
Stuck? ${c.cyan("https://sugarcube.sh")}`)}o(Gt,"getComponentsDir");const Bt=mt(),E=o((e,t)=>Bt?e:t,"unicodeOr"),Vt=E("\u25C7","o"),xe=E("\u250C","T"),A=E("\u2502","|"),he=E("\u2514","\u2014"),Wt=E("\u2510","T"),Yt=E("\u2518","\u2014"),ne=E("\u2500","-"),Kt=E("\u256E","+"),Ht=E("\u256F","+"),zt=E("\u2570","+"),Jt=E("\u256D","+"),qt=E("\u25CF","\u2022"),Zt=E("\u25C6","*"),Qt=E("\u25B2","!"),Xt=E("\u25A0","x"),K=o((e,t=c.bgGreen,n=c.black)=>t(` ${n(e)} `),"label"),H=o(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"),z=o((e="",t)=>{process.stdout.write(`
|
|
129
|
-
|
|
130
|
-
${c.gray(xe)}${c.gray(ne)} ${e}
|
|
131
|
-
`)},"intro"),se=o((e="",t)=>{process.stdout.write(`${c.gray(A)}
|
|
132
|
-
${c.gray(he)}${c.gray(ne)} ${e}
|
|
133
|
-
|
|
134
|
-
`)},"outro");function x(e){return new Promise(t=>setTimeout(t,e))}o(x,"sleep");const en=[Jt,Kt,zt,Ht],tn=[xe,Wt,he,Yt];function Ge(e,t,n,s){let r=n,i=n;return s==="center"?r=Math.floor((t-e)/2):s==="right"&&(r=t-e-n),i=t-r-e,[r,i]}o(Ge,"getPaddingForLine");const nn=o(e=>e,"defaultFormatBorder"),we=o((e="",t="",n)=>{const s=n?.output??process.stdout,r=dt(s),a=1*2,l=n?.titlePadding??1,f=n?.contentPadding??2,d=n?.width===void 0||n.width==="auto"?1:Math.min(1,n.width),u=n?.includePrefix?`${A} `:"",m=n?.formatBorder??nn,h=(n?.rounded?en:tn).map(m),b=m(ne),v=m(A),S=r-u.length;let k=Math.floor(r*d)-u.length;if(n?.width==="auto"){const Z=e.split(`
|
|
135
|
-
`);let B=H(t).length+l*2;for(const Xe of Z){const Te=H(Xe).length+f*2;Te>B&&(B=Te)}const Q=B+a;Q<k&&(k=Q)}k%2!==0&&(k<S?k++:k--);const I=k-a,D=I-l*2,y=H(t).length>D?`${t.slice(0,D-3)}...`:t,[C,N]=Ge(H(y).length,I,l,n?.titleAlign),P=pt(e,I-f*2,{hard:!0,trim:!1});s.write(`${u}${h[0]}${b.repeat(C)}${y}${b.repeat(N)}${h[1]}
|
|
136
|
-
`);const q=P.split(`
|
|
137
|
-
`);for(const Z of q){const[B,Q]=Ge(H(Z).length,I,f,n?.contentAlign);s.write(`${u}${v}${" ".repeat(B)}${Z}${" ".repeat(Q)}${v}
|
|
138
|
-
`)}s.write(`${u}${h[2]}${b.repeat(I)}${h[3]}
|
|
139
|
-
`)},"box");function ye(e,t={}){const n=`
|
|
140
|
-
${e}`;we(n,c.black(c.bgRed(" ERROR ")),{width:"auto",titlePadding:2,formatBorder:c.red,...t})}o(ye,"errorBoxWithBadge");function Be(e,t={}){const n=`
|
|
141
|
-
${e}`;we(n,c.black(c.bgYellow(" WARNING ")),{width:"auto",titlePadding:2,formatBorder:c.yellow,...t})}o(Be,"warningBoxWithBadge");function sn(e,t={}){const n=`
|
|
142
|
-
${e}`;we(n,c.black(c.bgCyan(" INFO ")),{width:"auto",titlePadding:2,formatBorder:c.cyan,...t})}o(sn,"infoBoxWithBadge");const on=o((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"),rn=o(async(e,t={})=>{const{sidebarSymbol:n=c.gray("\u2502"),clear:s=!1,stdin:r=process.stdin,stdout:i=process.stdout}=t,a=Ne.createInterface({input:r,escapeCodeTimeout:50}),l=De(i,{showCursor:!1});Ne.emitKeypressEvents(r,a);let f=0,d=!1;const u=o(async()=>{r.off("keypress",m),r.isTTY&&r.setRawMode(!1),a.close(),d=!0,f<e.length-1||s?l.clear():l.done()},"done"),m=o((h,b)=>{r.isTTY&&r.setRawMode(!0);const v=on(b);if(v==="abort")return u(),process.exit(0);["up","down","left","right"].includes(v)||u()},"handleKeyPress");r.isTTY&&r.setRawMode(!0),r.on("keypress",m);for(const h of e){const b=Array.isArray(h)?h:h.split(" "),v=[];for(const I of[""].concat(b)){I&&v.push(I);const D=v.join(" ").replace(/sugarcube/g,c.cyan("sugarcube")),y=`${n} ${D}`;l(y),d||await new Promise(C=>setTimeout(C,Math.floor(Math.random()*126)+75))}d||await new Promise(I=>setTimeout(I,100));const k=(await Promise.all(b).then(I=>I.join(" "))).replace(/sugarcube/g,c.cyan("sugarcube"));l(`${n} ${k}`),d||await new Promise(I=>setTimeout(I,Math.floor(Math.random()*201)+1200)),f++}r.off("keypress",m),await new Promise(h=>setTimeout(h,100)),u(),r.isTTY&&r.setRawMode(!1),r.removeAllListeners("keypress")},"sayAnimatedInSidebar");function an(){return Math.floor(Math.random()*551)+200}o(an,"getRandomTaskDuration");async function cn(e,{sidebarSymbol:t="\u2502",spacing:n=1,stdin:s=process.stdin,stdout:r=process.stdout,initialDelayMs:i=200,minDurationMs:a,successPauseMs:l=300,successMessage:f,successAsOutro:d=!1}={}){const u=o((y,C)=>{let N="";switch(C){case"start":N=`${c.cyan(`\u25B6 ${y.start}`)}`;break;case"pending":N=`${c.dim(`\u25A1 ${y.pending}`)}`;break;case"success":N=`${c.green(`\u2714 ${y.end}`)}`;break;case"end":N=`${c.dim(`\u25A0 ${y.end}`)}`;break}return`${t} ${N}`},"formatWithSidebar"),m=Array.from({length:e.length},()=>"");e.forEach((y,C)=>{m[C]=u(y,"pending")});const h=De(r),b=Ce.createInterface({input:s,escapeCodeTimeout:50});Ce.emitKeypressEvents(s,b);const v=o(y=>{y===""&&(h.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",v);const S=Array.from({length:Math.max(n,0)},()=>`${t}`),k=o(()=>[...S,...m].join(`
|
|
143
|
-
`),"renderContent");h(k()),await x(i);let I=0;for(const y of e){m[I]=u(y,"start"),h(k());const C=Date.now(),N=y.while();try{await N;const P=Date.now()-C,q=typeof a=="number"?a:an();P<q&&await x(q-P),m[I]=u(y,"success"),h(k()),await x(l)}catch(P){throw m[I]=`${t} ${c.red(`\u2717 ${y.end} (failed)`)}`,h(k()),y.onError?.(P),s.removeListener("keypress",v),b.close(),s.isTTY&&s.setRawMode(!1),P}I++}const D=e.map(y=>u(y,"end"));if(f)if(d){const y=`${c.gray(he)}${c.gray(ne)} ${c.green(f)}`;h([...S,...D,`${t}`,y].join(`
|
|
144
|
-
`))}else{const y=`${t} ${c.green(f)}`;h([...S,...D,`${t}`,y].join(`
|
|
145
|
-
`))}else h([...S,...D].join(`
|
|
146
|
-
`));await x(1e3),s.removeListener("keypress",v),s.isTTY&&s.setRawMode(!1),b.close(),h.done()}o(cn,"executeTasksInSidebar");const ln=o(e=>process.stdout.write(`${e}
|
|
147
|
-
`),"rawLog"),T={message:o((e=[],{symbol:t=c.gray(A),secondarySymbol:n=c.gray(A),output:s=process.stdout,spacing:r=1}={})=>{const i=[];for(let l=0;l<r;l++)i.push(`${n}`);const a=Array.isArray(e)?e:e.split(`
|
|
148
|
-
`);if(a.length>0){const[l,...f]=a;l&&l.length>0?i.push(`${t} ${l}`):i.push(t);for(const d of f)d.length>0?i.push(`${n} ${d}`):i.push(n)}s.write(`${i.join(`
|
|
114
|
+
`)}`}r(Pe,"formatOverwriteWarnings");async function ee(e,t,n,s={}){if(e.length===0)return;const{devDependency:i=!1}=s,o=n==="npm"?"install":"add",a=(()=>{if(!i)return[];switch(n){case"npm":return["--save-dev"];case"pnpm":return["-D"];case"yarn":return["-D"];case"bun":return["-d"]}})();try{await rt(n,[o,...a,...e],{cwd:t})}catch{throw new p(g.DEPENDENCY_INSTALL_FAILED(n))}}r(ee,"installDependencies");async function Nt(e,t,n){const s=R(n,t.name);if(await V(s,{recursive:!0}),e.path.endsWith(".css")){const o=R(s,`${t.name}.css`);return await Q(o,e.content),o}const i=R(s,ye(e.path));return await Q(i,e.content),i}r(Nt,"writeComponentFile");async function Ft({registryIndex:e,selectedComponents:t,componentType:n,componentsOutputDirectory:s,packageManager:i}){const o=[],a=new Set;await V(s,{recursive:!0});const l=await fe(e,t,n);for(const f of l){const d=await de({type:"component",name:f.name,framework:n});for(const m of d.files)if(m)try{const h=await Nt(m,f,s);h&&o.push(h)}catch(h){const b=h instanceof Error?`: ${h.message}`:"";throw new p(`Failed to write component file for "${f.name}"${b}`)}const u=f.dependencies?.[n]||[];for(const m of u)a.add(m)}if(a.size>0)try{await ee(Array.from(a),process.cwd(),i)}catch(f){const d=f instanceof Error?`: ${f.message}`:"";throw new p(`Failed to install component dependencies${d}`)}return{createdFiles:o,npmDependencies:a}}r(Ft,"installComponents");function Ot(e,t){const n=U(e),s=U(t),i=D(s,n);return!i.startsWith("..")&&!nt(i)}r(Ot,"isWithinDirectory");async function At(e){const t=[],n=U(process.cwd(),e);await V(n,{recursive:!0});const i=(await j()).filter(o=>o.type==="cube").map(o=>o.name);for(const o of i){const a=await de({type:"cube",name:o});for(const l of a.files){if(!l)continue;const f=l.path.replace(/^styles\//,""),d=U(n,f);if(!Ot(d,n))throw new p(`Invalid file path detected in CUBE module "${o}": path escapes target directory`);const u=tt(d);try{await V(u,{recursive:!0}),await Q(d,l.content),t.push(d)}catch(m){const h=m instanceof Error?`: ${m.message}`:"";throw new p(`Failed to write CUBE module "${o}"${h}`)}}}return t}r(At,"installCUBE");async function Lt(e,t){await se.mkdir(t,{recursive:!0});const n=[];for(const s of e)await se.writeFile(s.path,s.content),n.push(s.path);return n}r(Lt,"writeTokenFiles");async function W(e,t){let n;if(t)n={type:"memory",data:t,config:e};else{if(!e.resolver)throw new p(g.RESOLVER_NOT_CONFIGURED());n={type:"resolver",resolverPath:e.resolver,config:e}}const{trees:s,resolved:i,modifiers:o,errors:a}=await it(n);if(a.load.length>0){const l=a.load.map(f=>{const d=f.file.split("/").pop()||"unknown file";let u=`File ${d}: `;return f.message.includes("Unexpected token")?u=g.TOKEN_FILE_INVALID_JSON(d):f.message.includes("Unexpected end")?u=g.TOKEN_FILE_INCOMPLETE_JSON(d):u=g.TOKEN_FILE_GENERIC_ERROR(d,f.message),u});throw new p(g.TOKEN_LOAD_FAILED(l))}if(a.validation.length>0||a.flatten.length>0||a.resolution.length>0){const l=[...a.flatten,...a.validation,...a.resolution],f=new Map;for(const d of l)if(d.source?.sourcePath){const u=f.get(d.source.sourcePath)||[];u.push(d.message),f.set(d.source.sourcePath,u)}throw new p(g.TOKEN_VALIDATION_FAILED(f))}return{trees:s,resolved:i,modifiers:o}}r(W,"loadAndResolveTokensForCLI");const Mt=r(async(e,t,n)=>{const s=await $t(e),i=U(process.cwd(),t),o=s.files.map(a=>({path:R(i,ye(a.path)),content:a.content}));return{config:n,tokenFiles:o,tokensDir:i,createdTokenPaths:o.map(a=>D(process.cwd(),a.path))}},"prepareStarterKitForInstall");async function Pt(e){const t=await Mt(e.starterKit??"",e.tokensDir,e.config),n=await Lt(t.tokenFiles,e.tokensDir),s=await re(e.tokensDir);if(s.found==="none")throw new p(g.RESOLVER_NOT_FOUND(e.tokensDir));if(s.found==="multiple")throw new p(g.RESOLVER_MULTIPLE_FOUND(s.paths));const i={...e.config,resolver:s.path},{trees:o,resolved:a}=await W(i);e.setupResult={config:i,createdTokenPaths:t.createdTokenPaths,trees:o,resolved:a,tokenFiles:t.tokenFiles,tokensDir:t.tokensDir},e.createdFiles.push(...n),e.config=i,e.sugarcubeConfig={...e.sugarcubeConfig,resolver:s.path}}r(Pt,"installFromStarterKit");async function Ue(e=!0){const t=[{label:"React",value:"react",hint:".tsx"},{label:"CSS Only",value:"css-only",hint:".css"},{label:c.dim("Web components"),value:"web-components",hint:"Coming soon!"}];e&&t.push({label:"Skip",value:"skip",hint:"continue without components"});const n=await at({message:"Build with",options:t});return oe(n)&&process.exit(0),n==="web-components"?(ct.info(c.blue("Web components are coming soon! Please choose React or CSS Only for now.")),Ue(e)):n}r(Ue,"promptComponentFramework");async function Ut(e,t){const n=e.filter(i=>i.type==="component"&&i.frameworks?.includes(t)),s=await lt({message:"Select components to add",options:n.map(i=>({label:i.name,value:i.name,hint:i.description})),required:!0});return oe(s)&&process.exit(0),s}r(Ut,"promptComponentSelectionFiltered");async function je(e,t=!1){const n=await ut({message:e,initialValue:t});return(!n||oe(n))&&($e(),process.exit(0)),!0}r(je,"confirmOverwrite");function x(e){return{absolute:U(process.cwd(),e)}}r(x,"resolveDirectoryFromFlag");async function jt(e){if(e){const{absolute:t}=x(e);return{directory:t}}try{const{config:t}=await X(),n=t.output.cube||t.output.cssRoot,{absolute:s}=x(n);return{directory:s}}catch(t){if(be(t)){const{absolute:n}=x("src/styles");return{directory:n}}throw t}}r(jt,"getCubeDir");async function xt(e){if(e){const{absolute:t}=x(e);return{directory:t}}try{const{config:t}=await X(),n=t.output.components??"src/components/ui",{absolute:s}=x(n);return{directory:s}}catch(t){if(be(t)){const{absolute:n}=x("src/components/ui");return{directory:n}}throw t}}r(xt,"getComponentsDir");const Gt=pt(),S=r((e,t)=>Gt?e:t,"unicodeOr"),Bt=S("\u25C7","o"),xe=S("\u250C","T"),O=S("\u2502","|"),pe=S("\u2514","\u2014"),Vt=S("\u2510","T"),Wt=S("\u2518","\u2014"),te=S("\u2500","-"),Kt=S("\u256E","+"),Yt=S("\u256F","+"),zt=S("\u2570","+"),Ht=S("\u256D","+"),Jt=S("\u25CF","\u2022"),qt=S("\u25C6","*"),Zt=S("\u25B2","!"),Qt=S("\u25A0","x"),K=r((e,t=c.bgGreen,n=c.black)=>t(` ${n(e)} `),"label"),Y=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"),z=r((e="",t)=>{process.stdout.write(`
|
|
115
|
+
|
|
116
|
+
${c.gray(xe)}${c.gray(te)} ${e}
|
|
117
|
+
`)},"intro"),ne=r((e="",t)=>{process.stdout.write(`${c.gray(O)}
|
|
118
|
+
${c.gray(pe)}${c.gray(te)} ${e}
|
|
119
|
+
|
|
120
|
+
`)},"outro");function G(e){return new Promise(t=>setTimeout(t,e))}r(G,"sleep");const Xt=[Ht,Kt,zt,Yt],en=[xe,Vt,pe,Wt];function Ge(e,t,n,s){let i=n,o=n;return s==="center"?i=Math.floor((t-e)/2):s==="right"&&(i=t-e-n),o=t-i-e,[i,o]}r(Ge,"getPaddingForLine");const tn=r(e=>e,"defaultFormatBorder"),me=r((e="",t="",n)=>{const s=n?.output??process.stdout,i=dt(s),a=1*2,l=n?.titlePadding??1,f=n?.contentPadding??2,d=n?.width===void 0||n.width==="auto"?1:Math.min(1,n.width),u=n?.includePrefix?`${O} `:"",m=n?.formatBorder??tn,h=(n?.rounded?Xt:en).map(m),b=m(te),w=m(O),v=i-u.length;let k=Math.floor(i*d)-u.length;if(n?.width==="auto"){const q=e.split(`
|
|
121
|
+
`);let B=Y(t).length+l*2;for(const Xe of q){const we=Y(Xe).length+f*2;we>B&&(B=we)}const Z=B+a;Z<k&&(k=Z)}k%2!==0&&(k<v?k++:k--);const E=k-a,C=E-l*2,T=Y(t).length>C?`${t.slice(0,C-3)}...`:t,[_,$]=Ge(Y(T).length,E,l,n?.titleAlign),A=ft(e,E-f*2,{hard:!0,trim:!1});s.write(`${u}${h[0]}${b.repeat(_)}${T}${b.repeat($)}${h[1]}
|
|
122
|
+
`);const J=A.split(`
|
|
123
|
+
`);for(const q of J){const[B,Z]=Ge(Y(q).length,E,f,n?.contentAlign);s.write(`${u}${w}${" ".repeat(B)}${q}${" ".repeat(Z)}${w}
|
|
124
|
+
`)}s.write(`${u}${h[2]}${b.repeat(E)}${h[3]}
|
|
125
|
+
`)},"box");function ge(e,t={}){const n=`
|
|
126
|
+
${e}`;me(n,c.black(c.bgRed(" ERROR ")),{width:"auto",titlePadding:2,formatBorder:c.red,...t})}r(ge,"errorBoxWithBadge");function Be(e,t={}){const n=`
|
|
127
|
+
${e}`;me(n,c.black(c.bgYellow(" WARNING ")),{width:"auto",titlePadding:2,formatBorder:c.yellow,...t})}r(Be,"warningBoxWithBadge");function nn(e,t={}){const n=`
|
|
128
|
+
${e}`;me(n,c.black(c.bgCyan(" INFO ")),{width:"auto",titlePadding:2,formatBorder:c.cyan,...t})}r(nn,"infoBoxWithBadge");const sn=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"),rn=r(async(e,t={})=>{const{sidebarSymbol:n=c.gray("\u2502"),clear:s=!1,stdin:i=process.stdin,stdout:o=process.stdout}=t,a=De.createInterface({input:i,escapeCodeTimeout:50}),l=Ne(o,{showCursor:!1});De.emitKeypressEvents(i,a);let f=0,d=!1;const u=r(async()=>{i.off("keypress",m),i.isTTY&&i.setRawMode(!1),a.close(),d=!0,f<e.length-1||s?l.clear():l.done()},"done"),m=r((h,b)=>{i.isTTY&&i.setRawMode(!0);const w=sn(b);if(w==="abort")return u(),process.exit(0);["up","down","left","right"].includes(w)||u()},"handleKeyPress");i.isTTY&&i.setRawMode(!0),i.on("keypress",m);for(const h of e){const b=Array.isArray(h)?h:h.split(" "),w=[];for(const E of[""].concat(b)){E&&w.push(E);const C=w.join(" ").replace(/sugarcube/g,c.cyan("sugarcube")),T=`${n} ${C}`;l(T),d||await new Promise(_=>setTimeout(_,Math.floor(Math.random()*126)+75))}d||await new Promise(E=>setTimeout(E,100));const k=(await Promise.all(b).then(E=>E.join(" "))).replace(/sugarcube/g,c.cyan("sugarcube"));l(`${n} ${k}`),d||await new Promise(E=>setTimeout(E,Math.floor(Math.random()*201)+1200)),f++}i.off("keypress",m),await new Promise(h=>setTimeout(h,100)),u(),i.isTTY&&i.setRawMode(!1),i.removeAllListeners("keypress")},"sayAnimatedInSidebar");function on(){return Math.floor(Math.random()*551)+200}r(on,"getRandomTaskDuration");async function an(e,{sidebarSymbol:t="\u2502",spacing:n=1,stdin:s=process.stdin,stdout:i=process.stdout,initialDelayMs:o=200,minDurationMs:a,successPauseMs:l=300,successMessage:f,successAsOutro:d=!1}={}){const u=r((T,_)=>{let $="";switch(_){case"start":$=`${c.cyan(`\u25B6 ${T.start}`)}`;break;case"pending":$=`${c.dim(`\u25A1 ${T.pending}`)}`;break;case"success":$=`${c.green(`\u2714 ${T.end}`)}`;break;case"end":$=`${c.dim(`\u25A0 ${T.end}`)}`;break}return`${t} ${$}`},"formatWithSidebar"),m=Array.from({length:e.length},()=>"");e.forEach((T,_)=>{m[_]=u(T,"pending")});const h=Ne(i),b=Ce.createInterface({input:s,escapeCodeTimeout:50});Ce.emitKeypressEvents(s,b);const w=r(T=>{T===""&&(h.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",w);const v=Array.from({length:Math.max(n,0)},()=>`${t}`),k=r(()=>[...v,...m].join(`
|
|
129
|
+
`),"renderContent");h(k()),await G(o);let E=0;for(const T of e){m[E]=u(T,"start"),h(k());const _=Date.now(),$=T.while();try{await $;const A=Date.now()-_,J=typeof a=="number"?a:on();A<J&&await G(J-A),m[E]=u(T,"success"),h(k()),await G(l)}catch(A){throw m[E]=`${t} ${c.red(`\u2717 ${T.end} (failed)`)}`,h(k()),T.onError?.(A),s.removeListener("keypress",w),b.close(),s.isTTY&&s.setRawMode(!1),A}E++}const C=e.map(T=>u(T,"end"));if(f)if(d){const T=`${c.gray(pe)}${c.gray(te)} ${c.green(f)}`;h([...v,...C,`${t}`,T].join(`
|
|
130
|
+
`))}else{const T=`${t} ${c.green(f)}`;h([...v,...C,`${t}`,T].join(`
|
|
131
|
+
`))}else h([...v,...C].join(`
|
|
132
|
+
`));await G(1e3),s.removeListener("keypress",w),s.isTTY&&s.setRawMode(!1),b.close(),h.done()}r(an,"executeTasksInSidebar");const cn=r(e=>process.stdout.write(`${e}
|
|
133
|
+
`),"rawLog"),I={message:r((e=[],{symbol:t=c.gray(O),secondarySymbol:n=c.gray(O),output:s=process.stdout,spacing:i=1}={})=>{const o=[];for(let l=0;l<i;l++)o.push(`${n}`);const a=Array.isArray(e)?e:e.split(`
|
|
134
|
+
`);if(a.length>0){const[l,...f]=a;l&&l.length>0?o.push(`${t} ${l}`):o.push(t);for(const d of f)d.length>0?o.push(`${n} ${d}`):o.push(n)}s.write(`${o.join(`
|
|
149
135
|
`)}
|
|
150
|
-
`)},"message"),info:
|
|
151
|
-
`)},"space"),break:
|
|
152
|
-
`)},"break")};function
|
|
136
|
+
`)},"message"),info:r((e,t)=>{I.message(e,{...t,symbol:c.blue(Jt)})},"info"),success:r((e,t)=>{I.message(e,{...t,symbol:c.green(qt)})},"success"),step:r((e,t)=>{I.message(e,{...t,symbol:c.green(Bt)})},"step"),warn:r((e,t)=>{I.message(e,{...t,symbol:c.yellow(Zt)})},"warn"),error:r((e,t)=>{I.message(e,{...t,symbol:c.red(Qt)})},"error"),animated:r(async(e,{secondarySymbol:t=c.gray(O),output:n=process.stdout,clear:s=!1,...i}={})=>rn(e,{sidebarSymbol:t,stdout:n,clear:s,...i}),"animated"),tasks:r(async(e,{spacing:t=1,secondarySymbol:n=c.gray(O),output:s=process.stdout,...i}={})=>an(e,{sidebarSymbol:n,spacing:t,stdout:s,...i}),"tasks"),space:r((e=1)=>{for(let t=0;t<e;t++)process.stdout.write(`${c.gray(O)}
|
|
137
|
+
`)},"space"),break:r((e=1)=>{for(let t=0;t<e;t++)process.stdout.write(`
|
|
138
|
+
`)},"break")};function H(e){if(e instanceof p)I.space(1),ge(e.message,{});else{const t=`An unexpected error occurred: ${e instanceof Error?e.message:String(e)}
|
|
153
139
|
|
|
154
|
-
If this issue persists, please report it: ${c.cyan("https://github.com/sugarcube-org/sugarcube/issues")}`;
|
|
155
|
-
|
|
140
|
+
If this issue persists, please report it: ${c.cyan("https://github.com/sugarcube-org/sugarcube/issues")}`;I.space(1),ge(t,{})}process.exit(1)}r(H,"handleError");function L(e,t=process.cwd()){try{const n=mt(t,"package.json");if(!N(n))return!1;const s=Te(n,"utf-8"),i=JSON.parse(s),o={...i.dependencies,...i.devDependencies,...i.peerDependencies};return e in o}catch{return!1}}r(L,"isPackageInstalled");async function Ve(e,{withFallback:t=!1}={}){const n=await gt({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(Ve,"getPackageManager");const ln=new P().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("--components-dir <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{t.silent||z(K(c.bgGreen(c.black("Components"))));const{directory:n}=await xt(t.componentsDir);let s=[],i;if(e.length>0||t.framework){if(!t.framework)throw new p(g.COMPONENTS_FRAMEWORK_REQUIRED());if(!["react","css-only"].includes(t.framework))throw new p(g.COMPONENTS_INVALID_FRAMEWORK());i=t.framework,s=e}else{i=await Ue(!1);const w=await j();w||($e("Failed to fetch component list"),process.exit(1)),s=await Ut(w,i)}const o=await Ve(process.cwd(),{withFallback:!0}),a=await j(),l=await fe(a,s,i),f=await Ct({selectedComponents:s,componentType:i,componentsOutputDirectory:n}),d=Pe(f);if(d&&!t.force&&!t.silent){const w=Be(d,{});I.space(1),await je("Continue?",!1)}const u=[],m=[],h=new Set;for(const w of l){const v=w.dependencies?.[i]||[];for(const k of v)h.add(k)}const b=Array.from(h).filter(w=>!L(w,process.cwd()));b.length>0&&u.push({pending:`Install ${b.length} dependencies`,start:`Installing ${b.join(", ")}...`,end:`Installed ${b.join(", ")}`,while:r(async()=>{await ee(b,process.cwd(),o)},"while")});for(const w of l)u.push({pending:`Write component files for ${w.name}`,start:`Writing component files for ${w.name}...`,end:`Wrote component files for ${w.name}`,while:r(async()=>{const v=await Ft({registryIndex:a,selectedComponents:[w.name],componentType:i,componentsOutputDirectory:n,overwrite:t.overwrite||!1,packageManager:o});m.push(...v.createdFiles)},"while")});await I.tasks(u,{successMessage:"Components added successfully! \u{1F389} ",minDurationMs:0,successAsOutro:!0}),cn("")}catch(n){H(n)}}),un=new P().name("cube").description("Add CUBE CSS to your project").option("-s, --silent","Suppress logs and prompts").option("-f, --force","Skip overwrite confirmation").option("--cube-dir <dir>","CUBE CSS output directory (defaults to cssRoot)").action(async e=>{try{e.silent||z(K("CUBE CSS"));const{directory:t}=await jt(e.cubeDir);try{await V(t,{recursive:!0})}catch(o){const a=o instanceof Error?`: ${o.message}`:"";throw new p(`Failed to create output directory${a}`)}const n=await Dt({cubeDirectory:t}),s=Pe(n);if(s&&!e.force&&!e.silent){I.space(1);const o=Be(s,{});await je("Continue?",!1)}const i=await At(t);if(!e.silent){I.space(1);const o=i,f=[...new Set(o)].map(d=>D(process.cwd(),d)).map(d=>({pending:`Write ${d}`,start:`Writing ${d}`,end:`Wrote ${d}`,while:r(async()=>{},"while")}));await I.tasks(f,{spacing:0,minDurationMs:0,successPauseMs:100,successMessage:"\u{1F389} Files written!"}),ne(c.green("CUBE added successfully."))}}catch(t){H(t)}}),dn="**/*.{html,htm,js,ts,jsx,tsx,vue,svelte,astro,php,njk,liquid,pug,hbs,handlebars,twig,erb,ejs}",fn=["**/node_modules/**","**/dist/**","**/build/**","**/.next/**","**/.nuxt/**","**/.astro/**","**/.git/**","**/coverage/**","**/.pnpm/**","**/.pnpm-store/**","**/.npm/**","**/.cache/**","**/.turbo/**","**/.vercel/**","**/.svelte-kit/**","**/out/**","**/__snapshots__/**","**/*.config.{js,ts,mjs}","**/*.min.js","**/*.bundle.js","**/*.d.ts"],We=1e4,Ke=100;async function Ye(e,t){const n={name:"sugarcube",rules:ot(t.utilities??{},e),preflights:[]},s=await ht({presets:[n]}),i=await ce([dn],{ignore:fn,dot:!1,onlyFiles:!0,absolute:!1});if(i.length===0)return[];if(i.length>We)throw new p(`Found ${i.length} files to scan (limit: ${We}). Are you running this from a monorepo root or a directory containing multiple projects? Run the command from within a single project directory instead.`);const o=[];let a=0;const l=Ke*1024*1024;for(const u of i){const m=await Ie(u,"utf8");if(a+=m.length,a>l)throw new p(`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.`);o.push(m)}const f=o.join(`
|
|
141
|
+
`),{css:d}=await s.generate(f,{preflights:!1});return d?.trim()?[{path:`${t.output.utilities}/utilities.gen.css`,css:d}]:[]}r(Ye,"generateSugarcubeUtilities");async function pn(e,t,n,s){const i=[],o=await ie(e,t,n),a=await Ee(o,n,s);await ke(a),i.push(...a);const l=await Ye(o,n);return await ve(l),i.push(...l),i}r(pn,"generateAllCSS");function mn(e){let t;(e.fluidMin||e.fluidMax)&&(t={min:e.fluidMin?Number.parseInt(e.fluidMin,10):320,max:e.fluidMax?Number.parseInt(e.fluidMax,10):1200});const n={resolver:e.resolver,output:{cssRoot:e.stylesDir,variables:e.variablesDir,utilities:e.utilitiesDir},transforms:{fluid:t,colorFallbackStrategy:e.colorFallback}};return Re(n)}r(mn,"buildConfigFromFlags");function gn(e,t){const n={min:t.fluidMin?Number.parseInt(t.fluidMin,10):e.transforms.fluid.min,max:t.fluidMax?Number.parseInt(t.fluidMax,10):e.transforms.fluid.max};return{...e,resolver:t.resolver??e.resolver,transforms:{fluid:n,colorFallbackStrategy:t.colorFallback??e.transforms.colorFallbackStrategy},output:{...e.output,cssRoot:t.stylesDir??e.output.cssRoot,variables:t.variablesDir??e.output.variables,utilities:t.utilitiesDir??e.output.utilities}}}r(gn,"mergeConfigWithFlags");function hn(e){return!!(e.resolver||e.stylesDir||e.variablesDir||e.utilitiesDir||e.fluidMin||e.fluidMax||e.colorFallback)}r(hn,"hasRelevantFlags");function wn(e){if(e.colorFallback&&!["native","polyfill"].includes(e.colorFallback))throw new p(`Invalid --color-fallback value: "${e.colorFallback}". Must be "native" or "polyfill".`);if(e.fluidMin){const t=Number.parseInt(e.fluidMin,10);if(Number.isNaN(t)||t<=0)throw new p(`Invalid --fluid-min value: "${e.fluidMin}". Must be a positive number.`)}if(e.fluidMax){const t=Number.parseInt(e.fluidMax,10);if(Number.isNaN(t)||t<=0)throw new p(`Invalid --fluid-max value: "${e.fluidMax}". Must be a positive number.`)}}r(wn,"validateFlags");async function yn(e){if(Se()){const{config:s}=await X();return gn(s,e)}const t=await re(process.cwd());if(t.found==="multiple")throw new p(g.GENERATE_MULTIPLE_RESOLVERS_NO_CONFIG(t.paths));const n=e.resolver??(t.found==="one"?t.path:void 0);if(n||hn(e))return mn({...e,resolver:n});throw new p(g.GENERATE_NO_CONFIG_OR_RESOLVER())}r(yn,"resolveConfig");const Tn=new P().name("generate").description("Generate CSS from your design tokens").option("--force","Skip overwrite confirmation").option("-s, --silent","Suppress logs and prompts").option("--resolver <path>","Path to token resolver file (.resolver.json)").option("--styles-dir <dir>","CSS output directory (default: 'src/styles')").option("--variables-dir <dir>","Token variables output directory (default: 'src/styles/global')").option("--utilities-dir <dir>","Utilities output directory (default: 'src/styles/utilities')").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)").action(async e=>{try{if(e.silent||z(K("Generate CSS")),wn(e),L("@sugarcube-org/vite"))throw new p("Sugarcube vite plugin detected. When using the plugin, CSS is generated automatically during your build process. Remove the plugin to use CLI generation instead.");const t=await yn(e),{trees:n,resolved:s,modifiers:i}=await W(t),o=await pn(n,s,t,i);if(!e.silent){const a=o.map(u=>u.path),d=[...new Set(a)].map(u=>D(process.cwd(),u)).map(u=>({pending:`Write ${u}`,start:`Writing ${u}`,end:`Wrote ${u}`,while:r(async()=>{},"while")}));await I.tasks(d,{spacing:1,minDurationMs:0,successPauseMs:100,successMessage:"\u{1F389} Files written!"}),I.space(1),ne(c.green("CSS generated successfully."))}}catch(t){H(t)}});async function In(e){const t={};return(e.stylesDir||e.variablesDir||e.utilitiesDir)&&(t.output={},e.stylesDir&&(t.output.cssRoot=e.stylesDir),e.variablesDir&&(t.output.variables=e.variablesDir),e.utilitiesDir&&(t.output.utilities=e.utilitiesDir)),(e.fluidMin!==void 0||e.colorFallback)&&(t.transforms={},e.fluidMin!==void 0&&e.fluidMax!==void 0&&(t.transforms.fluid={min:Number(e.fluidMin),max:Number(e.fluidMax)}),e.colorFallback&&(t.transforms.colorFallbackStrategy=e.colorFallback)),t}r(In,"buildSugarcubeConfig");function ze(e){try{const t=ae.resolve(e,"package.json");if(!N(t))return null;const n=Te(t,"utf-8");return JSON.parse(n)}catch{return null}}r(ze,"getPackageJson");function M(e,t){if(!e)return!1;const n=e.dependencies,s=e.devDependencies;return!!(n?.[t]||s?.[t])}r(M,"hasDependency");function bn(e,t){if(!e)return!1;const n=e.dependencies,s=e.devDependencies,i={...n,...s};return Object.keys(i).some(o=>o.startsWith(t))}r(bn,"hasDependencyStartingWith");function Sn(e){const t=N(ae.resolve(e,"src")),n=ze(e),s=t?"src/design-tokens":"design-tokens",i=t?"src/styles":"styles",o=t?"src/components":"components";let a="none";return M(n,"next")?a=N(ae.resolve(e,`${t?"src/":""}app`))?"next-app":"next-pages":M(n,"astro")?a="astro":M(n,"nuxt")?a="nuxt":M(n,"@sveltejs/kit")?a="sveltekit":bn(n,"@remix-run/")?a="remix":M(n,"@11ty/eleventy")?a="eleventy":M(n,"vite")&&(a="vite"),{framework:a,isSrcDir:t,tokensDir:s,stylesDir:i,componentDir:o}}r(Sn,"getProjectInfo");function En(e,t){if(["vite","astro","nuxt","sveltekit","remix"].includes(e))return!0;if(e==="eleventy"){const s=ze(t);return M(s,"vite")}return!1}r(En,"shouldInstallVitePlugin");function He(e,t=0){if(typeof e!="object"||e===null||t>Et)return!1;for(const[n,s]of Object.entries(e))if(!n.startsWith("$")&&typeof s=="object"&&s!==null&&("$value"in s||He(s,t+1)))return!0;return!1}r(He,"hasAnyToken");async function kn(e){try{const t=await ce([It],{cwd:e,absolute:!0});for(const n of t)try{const s=await se.readFile(n,"utf-8"),i=JSON.parse(s);if(He(i))return!0}catch{}return!1}catch{return!1}}r(kn,"detectExistingTokens");function vn(e=process.cwd()){return wt(e)!==null}r(vn,"isTypeScriptProject");async function Je(e=process.cwd()){return vn(e)?"sugarcube.config.ts":"sugarcube.config.js"}r(Je,"getConfigFileName");function Rn(e){return/^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(e)}r(Rn,"isValidIdentifier");function he(e,t=0){const n=" ".repeat(t);if(e===null)return"null";if(e===void 0)return"undefined";if(typeof e=="string")return JSON.stringify(e);if(typeof e=="number"||typeof e=="boolean")return String(e);if(Array.isArray(e))return e.length===0?"[]":`[
|
|
142
|
+
${e.map(i=>`${n} ${he(i,t+1)}`).join(`,
|
|
156
143
|
`)}
|
|
157
144
|
${n}]`;if(typeof e=="object"){const s=Object.entries(e);return s.length===0?"{}":`{
|
|
158
|
-
${s.map(([
|
|
145
|
+
${s.map(([o,a])=>{const l=Rn(o)?o:JSON.stringify(o);return`${n} ${l}: ${he(a,t+1)}`}).join(`,
|
|
159
146
|
`)}
|
|
160
|
-
${n}}`}return JSON.stringify(e)}
|
|
147
|
+
${n}}`}return JSON.stringify(e)}r(he,"formatValue");function _n(e,t){const n=he(e,0);return t?`import { defineConfig } from "${t}";
|
|
161
148
|
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
const config = `:r=`// Configuration reference: ${Fe.CONFIGURATION}
|
|
167
|
-
const config = `,`${r}${s};
|
|
168
|
-
|
|
169
|
-
export default config;
|
|
170
|
-
`}o(dn,"formatConfigAsCode");async function Ye(e,t){try{const n=await We(),s=n.endsWith(".ts"),r=dn(e,s,t);await X(n,r,"utf-8")}catch(n){const s=n instanceof Error?`: ${n.message}`:"";throw new p(`Failed to write config file${s}`)}}o(Ye,"writeSugarcubeConfig");function pn(e,t){return{...e,...t,output:{...e.output??{},...t.output??{}},transforms:{...e.transforms??{},...t.transforms??{}}}}o(pn,"mergeSugarcubeConfig");async function Ke(e){const{config:t}=await it(),n=pn(t,e),s=G(le);await Ye(n,s)}o(Ke,"mergeConfigIntoFile");const mn=new U().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("--components-dir <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{t.silent||z(K(c.bgGreen(c.black("Components"))));const{directory:n,fromConfig:s}=await Gt(t.componentsDir);let r=[],i;if(e.length>0||t.framework){if(!t.framework)throw new p(g.COMPONENTS_FRAMEWORK_REQUIRED());if(!["react","css-only"].includes(t.framework))throw new p(g.COMPONENTS_INVALID_FRAMEWORK());i=t.framework,r=e}else{i=await Me(!1);const S=await j();S||($e("Failed to fetch component list"),process.exit(1)),r=await Ut(S,i)}const a=await Ve(process.cwd(),{withFallback:!0}),l=await j(),f=await de(l,r,i),d=await Ct({selectedComponents:r,componentType:i,componentsOutputDirectory:n}),u=Le(d);if(u&&!t.force&&!t.silent){const S=Be(u,{});T.space(1),await Ue("Continue?",!1)}const m=[],h=[],b=new Set;for(const S of f){const k=S.dependencies?.[i]||[];for(const I of k)b.add(I)}const v=Array.from(b).filter(S=>!G(S,process.cwd()));v.length>0&&m.push({pending:`Install ${v.length} dependencies`,start:`Installing ${v.join(", ")}...`,end:`Installed ${v.join(", ")}`,while:o(async()=>{await pe(v,process.cwd(),a)},"while")});for(const S of f)m.push({pending:`Write component files for ${S.name}`,start:`Writing component files for ${S.name}...`,end:`Wrote component files for ${S.name}`,while:o(async()=>{const k=await Ft({registryIndex:l,selectedComponents:[S.name],componentType:i,componentsOutputDirectory:n,overwrite:t.overwrite||!1,packageManager:a});h.push(...k.createdFiles)},"while")});if(await T.tasks(m,{successMessage:"Components added successfully! \u{1F389} ",minDurationMs:0,successAsOutro:!0}),ln(""),!s&&O()){const S=R(process.cwd(),n);await Ke({output:{components:S}})}}catch(n){J(n)}}),gn=new U().name("cube").description("Add CUBE CSS to your project").option("-s, --silent","Suppress logs and prompts").option("-f, --force","Skip overwrite confirmation").option("--cube-dir <dir>","CUBE CSS output directory (defaults to cssRoot)").action(async e=>{try{e.silent||z(K("CUBE CSS"));const{directory:t,fromConfig:n}=await xt(e.cubeDir);try{await V(t,{recursive:!0})}catch(a){const l=a instanceof Error?`: ${a.message}`:"";throw new p(`Failed to create output directory${l}`)}const s=await Nt({cubeDirectory:t}),r=Le(s);if(r&&!e.force&&!e.silent){T.space(1);const a=Be(r,{});await Ue("Continue?",!1)}const i=await At(t);if(!e.silent){T.space(1);const a=i,d=[...new Set(a)].map(u=>R(process.cwd(),u)).map(u=>({pending:`Write ${u}`,start:`Writing ${u}`,end:`Wrote ${u}`,while:o(async()=>{},"while")}));await T.tasks(d,{spacing:0,minDurationMs:0,successPauseMs:100,successMessage:"\u{1F389} Files written!"}),se(c.green("CUBE added successfully."))}if(!n&&O()){const a=R(process.cwd(),t),{config:l}=await W(),f=l.output.cssRoot;a!==f&&await Ke({output:{cube:a}})}}catch(t){J(t)}}),hn="**/*.{html,htm,js,ts,jsx,tsx,vue,svelte,astro,php,njk,liquid,pug,hbs,handlebars,twig,erb,ejs}",wn=["**/node_modules/**","**/dist/**","**/build/**","**/.next/**","**/.nuxt/**","**/.astro/**","**/.git/**","**/coverage/**","**/.pnpm/**","**/.pnpm-store/**","**/.npm/**","**/.cache/**","**/.turbo/**","**/.vercel/**","**/.svelte-kit/**","**/out/**","**/__snapshots__/**","**/*.config.{js,ts,mjs}","**/*.min.js","**/*.bundle.js","**/*.d.ts"],He=1e4,ze=100;async function Je(e,t){const n={name:"sugarcube",rules:at(t.utilities??{},e),preflights:[]},s=await yt({presets:[n]}),r=await ee(hn,{ignore:wn,dot:!1,onlyFiles:!0,absolute:!1});if(r.length===0)return[];if(r.length>He)throw new p(`Found ${r.length} files to scan (limit: ${He}). Are you running this from a monorepo root or a directory containing multiple projects? Run the command from within a single project directory instead.`);const i=[];let a=0;const l=ze*1024*1024;for(const u of r){const m=await be(u,"utf8");if(a+=m.length,a>l)throw new p(`Total source size exceeds ${ze}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.`);i.push(m)}const f=i.join(`
|
|
171
|
-
`),{css:d}=await s.generate(f,{preflights:!1});return d?.trim()?[{path:`${t.output.utilities}/utilities.gen.css`,css:d}]:[]}o(Je,"generateSugarcubeUtilities");async function yn(e,t,n,s){const r=[],i=await re(e,t,n),a=await ve(i,n,s);await ke(a),r.push(...a);const l=await Je(i,n);return await Re(l),r.push(...l),r}o(yn,"generateAllCSS");function Sn(e){let t;(e.fluidMin||e.fluidMax)&&(t={min:e.fluidMin?Number.parseInt(e.fluidMin,10):320,max:e.fluidMax?Number.parseInt(e.fluidMax,10):1200});const n={resolver:e.resolver,output:{cssRoot:e.stylesDir,variables:e.variablesDir,utilities:e.utilitiesDir},transforms:{fluid:t,colorFallbackStrategy:e.colorFallback}};return _e(n)}o(Sn,"buildConfigFromFlags");function Tn(e,t){const n={min:t.fluidMin?Number.parseInt(t.fluidMin,10):e.transforms.fluid.min,max:t.fluidMax?Number.parseInt(t.fluidMax,10):e.transforms.fluid.max};return{...e,resolver:t.resolver??e.resolver,transforms:{fluid:n,colorFallbackStrategy:t.colorFallback??e.transforms.colorFallbackStrategy},output:{...e.output,cssRoot:t.stylesDir??e.output.cssRoot,variables:t.variablesDir??e.output.variables,utilities:t.utilitiesDir??e.output.utilities}}}o(Tn,"mergeConfigWithFlags");function In(e){return!!(e.resolver||e.stylesDir||e.variablesDir||e.utilitiesDir||e.fluidMin||e.fluidMax||e.colorFallback)}o(In,"hasRelevantFlags");function En(e){if(e.colorFallback&&!["native","polyfill"].includes(e.colorFallback))throw new p(`Invalid --color-fallback value: "${e.colorFallback}". Must be "native" or "polyfill".`);if(e.fluidMin){const t=Number.parseInt(e.fluidMin,10);if(Number.isNaN(t)||t<=0)throw new p(`Invalid --fluid-min value: "${e.fluidMin}". Must be a positive number.`)}if(e.fluidMax){const t=Number.parseInt(e.fluidMax,10);if(Number.isNaN(t)||t<=0)throw new p(`Invalid --fluid-max value: "${e.fluidMax}". Must be a positive number.`)}}o(En,"validateFlags");async function bn(e){if(O()){const{config:s}=await W();return Tn(s,e)}const t=await me(process.cwd());if(t.found==="multiple")throw new p(g.GENERATE_MULTIPLE_RESOLVERS_NO_CONFIG(t.paths));const n=e.resolver??(t.found==="one"?t.path:void 0);if(n||In(e))return Sn({...e,resolver:n});throw new p(g.GENERATE_NO_CONFIG_OR_RESOLVER())}o(bn,"resolveConfig");const vn=new U().name("generate").description("Generate CSS from your design tokens").option("--force","Skip overwrite confirmation").option("-s, --silent","Suppress logs and prompts").option("--resolver <path>","Path to token resolver file (.resolver.json)").option("--styles-dir <dir>","CSS output directory (default: 'src/styles')").option("--variables-dir <dir>","Token variables output directory (default: 'src/styles/global')").option("--utilities-dir <dir>","Utilities output directory (default: 'src/styles/utilities')").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)").action(async e=>{try{if(e.silent||z(K("Generate CSS")),En(e),G("@sugarcube-org/vite"))throw new p("Sugarcube vite plugin detected. When using the plugin, CSS is generated automatically during your build process. Remove the plugin to use CLI generation instead.");const t=await bn(e),{trees:n,resolved:s,modifiers:r}=await Y(t),i=await yn(n,s,t,r);if(!e.silent){const a=i.map(u=>u.path),d=[...new Set(a)].map(u=>R(process.cwd(),u)).map(u=>({pending:`Write ${u}`,start:`Writing ${u}`,end:`Wrote ${u}`,while:o(async()=>{},"while")}));await T.tasks(d,{spacing:1,minDurationMs:0,successPauseMs:100,successMessage:"\u{1F389} Files written!"}),T.space(1),se(c.green("CSS generated successfully."))}}catch(t){J(t)}});async function kn(e){const t=R(process.cwd(),e.actualStylesDir),n=e.isSrcDir?te.output.components:te.output.components.replace(/^src\//,"");return{resolver:e.resolverPath,output:{cssRoot:t,components:n}}}o(kn,"buildSugarcubeConfig");function qe(e){try{const t=ae.resolve(e,"package.json");if(!F(t))return null;const n=Ee(t,"utf-8");return JSON.parse(n)}catch{return null}}o(qe,"getPackageJson");function M(e,t){if(!e)return!1;const n=e.dependencies,s=e.devDependencies;return!!(n?.[t]||s?.[t])}o(M,"hasDependency");function Rn(e,t){if(!e)return!1;const n=e.dependencies,s=e.devDependencies,r={...n,...s};return Object.keys(r).some(i=>i.startsWith(t))}o(Rn,"hasDependencyStartingWith");function _n(e){const t=F(ae.resolve(e,"src")),n=qe(e),s=t?"src/design-tokens":"design-tokens",r=t?"src/styles":"styles",i=t?"src/components":"components";let a="none";return M(n,"next")?a=F(ae.resolve(e,`${t?"src/":""}app`))?"next-app":"next-pages":M(n,"astro")?a="astro":M(n,"nuxt")?a="nuxt":M(n,"@sveltejs/kit")?a="sveltekit":Rn(n,"@remix-run/")?a="remix":M(n,"@11ty/eleventy")?a="eleventy":M(n,"vite")&&(a="vite"),{framework:a,isSrcDir:t,tokensDir:s,stylesDir:r,componentDir:i}}o(_n,"getProjectInfo");function $n(e,t){if(["vite","astro","nuxt","sveltekit","remix"].includes(e))return!0;if(e==="eleventy"){const s=qe(t);return M(s,"vite")}return!1}o($n,"shouldInstallVitePlugin");function Ze(e,t=0){if(typeof e!="object"||e===null||t>bt)return!1;for(const[n,s]of Object.entries(e))if(!n.startsWith("$")&&typeof s=="object"&&s!==null&&("$value"in s||Ze(s,t+1)))return!0;return!1}o(Ze,"hasAnyToken");async function Cn(e){try{const t=await ee(It,{cwd:e,absolute:!0});for(const n of t)try{const s=await oe.readFile(n,"utf-8"),r=JSON.parse(s);if(Ze(r))return!0}catch{}return!1}catch{return!1}}o(Cn,"detectExistingTokens");const Nn=o(async e=>{T.space(2),await x(200);let t="Next steps";if(e.pluginToInstall===le)t+=`
|
|
149
|
+
export default defineConfig(${n});
|
|
150
|
+
`:`${`// Configuration reference: ${Oe.CONFIGURATION}
|
|
151
|
+
export default `}${n};
|
|
152
|
+
`}r(_n,"formatConfigAsCode");async function $n(e,t){try{const n=await Je(),s=_n(e,t);await Q(n,s,"utf-8")}catch(n){const s=n instanceof Error?`: ${n.message}`:"";throw new p(`Failed to write config file${s}`)}}r($n,"writeSugarcubeConfig");const Cn=r(async e=>{I.space(2),await G(200);let t="Next steps";if(e.pluginToInstall===Fe)t+=`
|
|
172
153
|
|
|
173
154
|
`,t+=`1. Configure the plugin
|
|
174
155
|
`,t+=` Add the plugin to your build configuration:
|
|
@@ -180,18 +161,20 @@ export default config;
|
|
|
180
161
|
`,t+=`
|
|
181
162
|
|
|
182
163
|
`,t+=`3. (Optional) Add CUBE CSS
|
|
183
|
-
`,t+=` ${c.cyan(
|
|
164
|
+
`,t+=` ${c.cyan(F.CUBE)}`,t+=`
|
|
184
165
|
|
|
185
166
|
`,t+=`4. (Optional) Add components
|
|
186
|
-
`,t+=` ${c.cyan(
|
|
167
|
+
`,t+=` ${c.cyan(F.COMPONENTS)}`;else{const n=`${e.stylesDir}/global/tokens.variables.gen.css`;t+=`
|
|
187
168
|
|
|
188
169
|
`,t+=`1. Import the generated CSS
|
|
189
170
|
`;const s=e.isSrcDir?`"${n}"`:`"./${n}"`;t+=` ${c.cyan(`import ${s}`)}`,t+=`
|
|
190
171
|
|
|
191
172
|
`,t+=`2. (Optional) Add CUBE CSS
|
|
192
|
-
`,t+=` ${c.cyan(
|
|
173
|
+
`,t+=` ${c.cyan(F.CUBE)}`,t+=`
|
|
193
174
|
|
|
194
175
|
`,t+=`3. (Optional) Add components
|
|
195
|
-
`,t+=` ${c.cyan(
|
|
176
|
+
`,t+=` ${c.cyan(F.COMPONENTS)}`}t+=`
|
|
177
|
+
|
|
178
|
+
`,t+=`Docs: ${c.cyan("https://sugarcube.sh")}`,nn(t,{width:.75}),await G(200),I.break(1)},"nextSteps");async function Dn(e){await Cn(e)}r(Dn,"next");const Nn=r(async()=>{const e=["Welcome to sugarcube \u2014 the toolkit for seriously sweet frontends!"];I.space(1),await I.animated(e,{clear:!1})},"welcome");function qe(e,t){if(!e||e.trim()==="")throw new p(g.DIRECTORY_PATH_EMPTY(t));const s=st(e).split("/")[0];if(s&&St.includes(s))throw new p(g.DIRECTORY_PATH_RESERVED(t,e))}r(qe,"validateDirectoryPath");function Fn(e){e.tokensDir&&qe(e.tokensDir,"tokens-dir"),e.stylesDir&&qe(e.stylesDir,"styles-dir");const t=e.fluidMin!==void 0,n=e.fluidMax!==void 0;if(t!==n)throw new p(`Both --fluid-min and --fluid-max must be provided together.
|
|
196
179
|
|
|
197
|
-
|
|
180
|
+
Either specify both flags or omit both to use defaults (320px - 1200px).`)}r(Fn,"validateOptions");async function On(){Se()&&(ge(g.CONFIG_EXISTS(),{}),process.exit(1))}r(On,"preflightInit");async function An(e){const t=Sn(process.cwd()),n=e.tokensDir||t.tokensDir,s=e.stylesDir||t.stylesDir,i=await kn(n);let o=null;if(i){const a=await re(n);if(a.found==="none")throw new p(g.RESOLVER_NOT_FOUND(n));if(a.found==="multiple")throw new p(g.RESOLVER_MULTIPLE_FOUND(a.paths));o=a.path}return{tokensDir:n,stylesDir:s,isSrcDir:t.isSrcDir,hasExistingTokens:i,resolverPath:o,framework:t.framework}}r(An,"initializeProjectContext");function Ln(e,t,n){const s=t?null:e.kit||le;if(e.skipDeps)return{starterKit:s,pluginToInstall:null,cliToInstall:null};const i=Mn(n,process.cwd());return{starterKit:s,pluginToInstall:i,cliToInstall:i?null:bt}}r(Ln,"determineInstallationTargets");function Mn(e,t){return En(e,t)?Fe:null}r(Mn,"determinePlugin");async function Pn(e,t,n,s,i){const o=await Ve(process.cwd(),{withFallback:!0});return{options:e,...t,isSrcDir:t.isSrcDir,config:n,sugarcubeConfig:s,...i,packageManager:o,createdFiles:[],createdDirectories:[],installedDependencies:[],tasks:[]}}r(Pn,"buildInitContext");async function Un(e){const{trees:t,resolved:n}=await W(e.config);e.setupResult={config:e.config,createdTokenPaths:[],trees:t,resolved:n,tokenFiles:[],tokensDir:e.tokensDir}}r(Un,"processExistingTokens");async function jn(e){!e.hasExistingTokens&&e.starterKit?await Pt(e):await Un(e)}r(jn,"setupDesignTokens");async function xn(e){if(!e.setupResult)throw new p(g.INITIALIZATION_INCOMPLETE());const{trees:t,resolved:n}=e.setupResult,s=await ie(t,n,e.config),i=await Ee(s,e.config);await ke(i)}r(xn,"writeCSSVariables");async function Gn(e){if(!e.setupResult)throw new p(g.INITIALIZATION_INCOMPLETE());const{trees:t,resolved:n}=e.setupResult,s=await ie(t,n,e.config),i=await Ye(s,e.config);i.length&&await ve(i)}r(Gn,"writeCSSUtilities");async function Bn(e){if(e.pluginToInstall&&!L(e.pluginToInstall))try{await ee([e.pluginToInstall],process.cwd(),e.packageManager,{devDependency:!0}),e.installedDependencies.push(e.pluginToInstall)}catch{throw new p(g.PLUGIN_INSTALL_FAILED({pluginToInstall:e.pluginToInstall,packageManager:e.packageManager}))}}r(Bn,"installPlugins");async function Vn(e){if(e.cliToInstall&&!L(e.cliToInstall))try{await ee([e.cliToInstall],process.cwd(),e.packageManager,{devDependency:!0}),e.installedDependencies.push(e.cliToInstall)}catch{throw new p(g.CLI_INSTALL_FAILED({packageManager:e.packageManager}))}}r(Vn,"installCLI");function Ze(e){return!!(e.stylesDir||e.variablesDir||e.utilitiesDir||e.fluidMin||e.fluidMax||e.colorFallback)}r(Ze,"hasCustomizationFlags");function Wn(e){return e.pluginToInstall?"@sugarcube-org/vite":e.cliToInstall?"@sugarcube-org/cli":null}r(Wn,"getTypeSource");async function Qe(e){if(Ze(e.options))try{await $n(e.sugarcubeConfig,Wn(e));const t=await Je();e.createdFiles.push(t)}catch{throw new p(g.CONFIG_WRITE_FAILED())}}r(Qe,"finalize");function Kn(e){const t=[];if(e.hasExistingTokens?t.push({pending:"Looking for existing tokens",start:"Looking for existing tokens...",end:`Existing tokens found at ${e.tokensDir} ${S("\u2192","->")} using them`,while:r(async()=>{},"while")}):e.starterKit&&t.push({pending:"Looking for existing tokens",start:"Looking for existing tokens...",end:`No existing tokens detected ${S("\u2192","->")} adding starter kit`,while:r(async()=>{},"while")}),e.pluginToInstall){const n="Vite";L(e.pluginToInstall)?t.push({pending:`Checking for ${n} compatibility`,start:`Checking for ${n} compatibility...`,end:`${n} plugin already installed ${S("\u2192","->")} skipping plugin installation`,while:r(async()=>{},"while")}):t.push({pending:"Checking for Vite compatibility",start:"Checking for Vite compatibility...",end:`Vite detected ${S("\u2192","->")} plugin will be installed`,while:r(async()=>{},"while")})}else{const n=e.options.skipDeps;t.push({pending:"Checking for Vite compatibility",start:"Checking for Vite compatibility...",end:n?`Dependencies skipped ${S("\u2192","->")} no plugins or CLI will be installed`:`No Vite detected ${S("\u2192","->")} CSS will be generated as file(s)`,while:r(async()=>{},"while")})}return t}r(Kn,"buildDetectionTasks");async function Yn(e){if(e.tasks.push({pending:e.hasExistingTokens?"Process existing design tokens":"Add design tokens",start:e.hasExistingTokens?"Processing existing design tokens...":"Adding design tokens...",end:e.hasExistingTokens?"Design tokens processed":"Design tokens added",while:r(async()=>{await jn(e)},"while")}),!e.pluginToInstall)e.tasks.push({pending:"Generate CSS variables",start:"Generating CSS variables...",end:"CSS variables generated",while:r(async()=>{await xn(e)},"while")}),e.tasks.push({pending:"Generate CSS utilities",start:"Generating CSS utilities...",end:"CSS utilities generated",while:r(async()=>{await Gn(e)},"while")}),e.cliToInstall&&!L(e.cliToInstall)&&e.tasks.push({pending:"Install CLI",start:"Installing CLI...",end:"CLI installed",while:r(async()=>{await Vn(e)},"while")});else if(e.pluginToInstall&&!L(e.pluginToInstall)){const t="Vite";e.tasks.push({pending:`Install ${t} plugin`,start:`Installing ${t} plugin...`,end:`${t} plugin installed`,while:r(async()=>{await Bn(e)},"while")})}Ze(e.options)?e.tasks.push({pending:"Write configuration file",start:"Writing configuration file...",end:"Configuration file written",while:r(async()=>{await Qe(e)},"while")}):e.tasks.push({pending:"Finalize setup",start:"Finalizing...",end:"Setup complete",while:r(async()=>{await Qe(e)},"while")})}r(Yn,"buildExecutionTasks");const zn=new P().name("init").description("Initialize a new sugarcube project").option("--kit <kit>",`Starter kit to use (default: ${le})`,le).option("--tokens-dir <dir>","Design tokens directory (e.g., 'src/design-tokens')").option("--styles-dir <dir>","Styles output directory (e.g., 'src/styles')").option("--variables-dir <dir>","Token variables directory (e.g., 'src/styles/global')").option("--utilities-dir <dir>","Utilities directory (e.g., 'src/styles/utilities')").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("--skip-deps","Don't install any sugarcube packages").action(async e=>{let t;try{Fn(e),await On();const n=await An(e),s=await In(e),i=Re(s),o=Ln(e,n.hasExistingTokens,n.framework);t=await Pn(e,n,i,s,o),z(K("sugarcube")),await Nn();const a=Kn(t);a.length>0&&(I.message("Detecting project\u2026"),await I.tasks(a,{minDurationMs:1e3})),t.tasks=[],await Yn(t),t.tasks.length>0&&(I.message("Setting things up\u2026"),await I.tasks(t.tasks,{successMessage:"\u{1F389} Tasks completed successfully!"})),await Dn(t)}catch(n){H(n)}}),Hn=new P().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(z(K("Validate")),!e.length)try{const{config:o}=await X();await W(o),ne(c.greenBright("All tokens valid \u2728"));return}catch{throw new p(g.VALIDATE_NO_PATH_SPECIFIED())}for(const o of e)if(!N(o))throw new p(g.VALIDATE_PATH_NOT_FOUND(o));const n=(await ce(e.map(o=>o.endsWith(".json")?o:R(o,"**/*.json")),{absolute:!0})).filter(o=>!o.endsWith(".resolver.json"));if(n.length===0)throw new p(g.VALIDATE_NO_TOKEN_FILES());const s={};for(const o of n){const a=await Ie(o,"utf-8"),l=D(process.cwd(),o);s[l]={content:a}}const i={output:_e.output,transforms:_e.transforms};await W(i,s),ne(c.greenBright("All tokens valid \u2728"))}catch(t){H(t)}});process.on("SIGINT",()=>process.exit(0)),process.on("SIGTERM",()=>process.exit(0));async function Jn(){const e=new P().name("make-sugarcube").description("CLI for sugarcube").version(Tt.version,"-v, --version","display the version number");e.addCommand(zn).addCommand(Tn).addCommand(Hn).addCommand(ln).addCommand(un),e.parse()}r(Jn,"main"),Jn();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sugarcube-org/cli",
|
|
3
|
-
"version": "0.0.0-alpha.
|
|
3
|
+
"version": "0.0.0-alpha.37",
|
|
4
4
|
"publishConfig": {
|
|
5
5
|
"access": "public",
|
|
6
6
|
"provenance": false
|
|
@@ -31,26 +31,29 @@
|
|
|
31
31
|
"type": "module",
|
|
32
32
|
"main": "./dist/index.mjs",
|
|
33
33
|
"exports": {
|
|
34
|
-
".":
|
|
34
|
+
".": {
|
|
35
|
+
"types": "./dist/exports.d.mts",
|
|
36
|
+
"import": "./dist/exports.mjs"
|
|
37
|
+
}
|
|
35
38
|
},
|
|
36
39
|
"bin": {
|
|
37
|
-
"sugarcube": "./dist/index.mjs"
|
|
40
|
+
"make-sugarcube": "./dist/index.mjs"
|
|
38
41
|
},
|
|
39
42
|
"dependencies": {
|
|
40
43
|
"@antfu/ni": "23.3.0",
|
|
41
44
|
"@clack/core": "1.0.0-alpha.3",
|
|
42
45
|
"@clack/prompts": "1.0.0-alpha.3",
|
|
43
|
-
"@sugarcube-org/core": "0.1.0-alpha.
|
|
46
|
+
"@sugarcube-org/core": "0.1.0-alpha.21",
|
|
44
47
|
"@unocss/core": "66.5.2",
|
|
45
48
|
"commander": "12.1.0",
|
|
46
49
|
"execa": "9.5.2",
|
|
47
|
-
"fast-glob": "3.3.2",
|
|
48
50
|
"fast-wrap-ansi": "0.1.3",
|
|
49
51
|
"get-tsconfig": "4.7.2",
|
|
50
52
|
"is-unicode-supported": "2.1.0",
|
|
51
53
|
"log-update": "6.1.0",
|
|
52
54
|
"pathe": "2.0.3",
|
|
53
55
|
"picocolors": "1.1.1",
|
|
56
|
+
"tinyglobby": "^0.2.9",
|
|
54
57
|
"zod": "^3.23.8"
|
|
55
58
|
},
|
|
56
59
|
"devDependencies": {
|