@sugarcube-org/cli 0.0.0-alpha.2 → 0.0.0-alpha.20
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE.md +31 -0
- package/README.md +4 -6
- package/dist/index.mjs +158 -49
- package/package.json +35 -24
package/LICENSE.md
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# Sugarcube Private Alpha License
|
|
2
|
+
|
|
3
|
+
Copyright © 2025 Mark Tomlinson. All rights reserved.
|
|
4
|
+
|
|
5
|
+
**Version 1.0 – December 2025**
|
|
6
|
+
|
|
7
|
+
This software is provided under a temporary, non-exclusive, non-transferable
|
|
8
|
+
license for private evaluation and internal use as part of the Sugarcube
|
|
9
|
+
Private Alpha Program.
|
|
10
|
+
|
|
11
|
+
## Permitted
|
|
12
|
+
|
|
13
|
+
- Use in internal and client projects for the purpose of evaluating Sugarcube
|
|
14
|
+
- Reporting bugs, performance issues, and usability feedback
|
|
15
|
+
|
|
16
|
+
## Not Permitted
|
|
17
|
+
|
|
18
|
+
- Redistribution of the software or any derivative works
|
|
19
|
+
- Public hosting of the source code
|
|
20
|
+
- Sublicensing, resale, or commercial distribution of Sugarcube itself
|
|
21
|
+
- Reverse engineering for the purpose of creating a competing product
|
|
22
|
+
|
|
23
|
+
## Disclaimer
|
|
24
|
+
|
|
25
|
+
This software is provided "as is", without warranty of any kind, express or
|
|
26
|
+
implied. The author assumes no liability for damages arising from its use.
|
|
27
|
+
|
|
28
|
+
## Future Licensing
|
|
29
|
+
|
|
30
|
+
This license will be replaced by an open-source license at public beta or
|
|
31
|
+
general availability.
|
package/README.md
CHANGED
|
@@ -1,9 +1,7 @@
|
|
|
1
|
-
#
|
|
1
|
+
# @sugarcube-org/cli
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
> ⚠️ **Private Alpha** — This package is under active development and not yet ready for public use.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
## License
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
Follow our progress on [GitHub](https://github.com/sugarcube-org)
|
|
7
|
+
See [LICENSE.md](./LICENSE.md) for terms.
|
package/dist/index.mjs
CHANGED
|
@@ -1,50 +1,159 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
var
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
${o
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
${
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
Please check
|
|
50
|
-
|
|
2
|
+
var qe=Object.defineProperty;var o=(e,t)=>qe(e,"name",{value:t,configurable:!0});import{Command as M}from"commander";import{relative as $,join as R,basename as G,resolve as L,dirname as ze,normalize as Ze}from"pathe";import c from"picocolors";import{existsSync as F,readFileSync as Te}from"node:fs";import Qe from"node-fetch";import{z as m}from"zod";import se,{mkdir as B,writeFile as X,readFile as Xe}from"node:fs/promises";import{execa as et}from"execa";import{loadAndResolveTokens as tt,validateConfig as nt,configFileExists as A,loadInternalConfig as ee,loadUserConfig as st,processAndConvertTokens as oe,generateCSSVariables as Se,writeCSSVariablesToDisk as Ie,writeCSSUtilitiesToDisk as ke,convertConfigToUnoRules as ot,DEFAULT_STYLES_PATH as rt,DEFAULT_CONFIG as re,fillDefaults as it}from"@sugarcube-org/core";import at from"is-unicode-supported";import ie,{resolve as ct}from"node:path";import{select as lt,isCancel as ae,log as ut,multiselect as ft,confirm as pt,cancel as Ee}from"@clack/prompts";import{getColumns as dt}from"@clack/core";import{wrapAnsi as gt}from"fast-wrap-ansi";import*as be from"node:readline";import Ce from"node:readline";import{createLogUpdate as $e}from"log-update";import{detect as mt}from"@antfu/ni";import{getTsconfig as ht}from"get-tsconfig";import{createGenerator as wt}from"@unocss/core";import V from"fast-glob";var yt="0.0.0-alpha.20",Tt={version:yt};const ce="fluid",Re="**/*.json",le="@sugarcube-org/vite",St=["node_modules",".git",".next","dist","build"],It=5,v={INIT:"make-sugarcube init",COMPONENTS:"make-sugarcube components",GENERATE:"make-sugarcube generate",CUBE:"make-sugarcube cube"},_e={INITIALIZATION:"https://sugarcube.sh/docs/setup",CONFIGURATION:"https://sugarcube.sh/docs/configuration"},w={PROJECT_REQUIRED:`No sugarcube project detected. Please run ${c.cyan(v.INIT)} first.
|
|
3
|
+
|
|
4
|
+
For more information, visit: ${c.cyan(_e.INITIALIZATION)}`,CONFIG_EXISTS:o(()=>`A sugarcube config file already exists in this projct.
|
|
5
|
+
|
|
6
|
+
To start over, remove it and run ${c.cyan(v.INIT)} again.`,"CONFIG_EXISTS"),PLUGIN_INSTALL_FAILED:o(e=>`Failed to install ${e.pluginToInstall} plugin.
|
|
7
|
+
|
|
8
|
+
This is usually a temporary issue. Try these steps:
|
|
9
|
+
|
|
10
|
+
1. Run the command again
|
|
11
|
+
2. Check your internet connection
|
|
12
|
+
3. Install manually: ${e.packageManager} add ${e.pluginToInstall}
|
|
13
|
+
|
|
14
|
+
If the problem continues, please open an issue at:
|
|
15
|
+
https://github.com/sugarcube-org/sugarcube/issues`,"PLUGIN_INSTALL_FAILED"),INITIALIZATION_INCOMPLETE:o(()=>`The initialization process was not completed properly.
|
|
16
|
+
This is an internal error that should not occur.
|
|
17
|
+
Try running the \`init\` command again.
|
|
18
|
+
|
|
19
|
+
If the problem persists, please report this issue at
|
|
20
|
+
https://github.com/sugarcube-org/sugarcube/issues`,"INITIALIZATION_INCOMPLETE"),CONFIG_WRITE_FAILED:o(()=>"Failed to write configuration file. Check permissions and try again.","CONFIG_WRITE_FAILED"),DIRECTORY_PATH_EMPTY:o(e=>`${e} cannot be empty. Please provide a valid directory path.`,"DIRECTORY_PATH_EMPTY"),DIRECTORY_PATH_RESERVED:o((e,t)=>`Option: ${e}
|
|
21
|
+
Value: "${t}"
|
|
22
|
+
|
|
23
|
+
${e} cannot be in a reserved directory`,"DIRECTORY_PATH_RESERVED"),KIT_INCOMPLETE:o(()=>`The starter kit appears to be incomplete or corrupted.
|
|
24
|
+
|
|
25
|
+
This is likely a temporary issue. Please try running the command again or choose a different starter kit.`,"KIT_INCOMPLETE"),REGISTRY_AUTH_REQUIRED:o(e=>`Registry access denied: Authentication required
|
|
26
|
+
URL: ${c.cyan(e)}`,"REGISTRY_AUTH_REQUIRED"),REGISTRY_AUTH_INVALID:o(e=>`Registry access denied: Invalid or missing token
|
|
27
|
+
URL: ${c.cyan(e)}`,"REGISTRY_AUTH_INVALID"),REGISTRY_NOT_FOUND:o(e=>`Registry resource not found
|
|
28
|
+
URL: ${c.cyan(e)}`,"REGISTRY_NOT_FOUND"),REGISTRY_REQUEST_FAILED:o((e,t)=>`Registry request failed: ${e}
|
|
29
|
+
URL: ${c.cyan(t)}`,"REGISTRY_REQUEST_FAILED"),REGISTRY_NETWORK_ERROR:o(e=>`Failed to connect to registry
|
|
30
|
+
|
|
31
|
+
URL: ${c.cyan(e)}
|
|
32
|
+
|
|
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:o(e=>`Invalid registry data received
|
|
34
|
+
URL: ${c.cyan(e)}`,"REGISTRY_INVALID_DATA"),REGISTRY_ITEM_NOT_FOUND:o((e,t,n)=>`${e==="tokens"?"Starter kit":e}'${c.cyan(t)} ' not found in registry
|
|
35
|
+
Available ${e==="tokens"?"starter kit":e}s: ${n.join(", ")}`,"REGISTRY_ITEM_NOT_FOUND"),REGISTRY_FILE_INVALID:o(e=>`Invalid file content received
|
|
36
|
+
File: ${c.cyan(e)}`,"REGISTRY_FILE_INVALID"),STARTER_KIT_UNAVAILABLE:o(e=>`Starter kit '${c.cyan(e)}' is currently unavailable.
|
|
37
|
+
|
|
38
|
+
Please try a different starter kit or run the command again in a few minutes.`,"STARTER_KIT_UNAVAILABLE"),TOKEN_LOAD_FAILED:o(e=>`Failed to load token files:
|
|
39
|
+
|
|
40
|
+
${e.join(`
|
|
41
|
+
`)}
|
|
42
|
+
|
|
43
|
+
Please check your token files and try again.`,"TOKEN_LOAD_FAILED"),TOKEN_VALIDATION_FAILED:o(e=>{let t=`Token validation failed:
|
|
44
|
+
|
|
45
|
+
`;for(const[n,s]of e){t+=`Error(s) in ${c.cyan(n)}:
|
|
46
|
+
`;for(const r of s)t+=` - ${r}
|
|
47
|
+
`;t+=`
|
|
48
|
+
`}return t+=`See ${c.cyan("https://sugarcube.sh/docs/design-tokens")} for valid token formats`,t},"TOKEN_VALIDATION_FAILED"),TOKEN_FILE_INVALID_JSON:o(e=>`File ${e}: Invalid JSON syntax`,"TOKEN_FILE_INVALID_JSON"),TOKEN_FILE_INCOMPLETE_JSON:o(e=>`File ${e}: Incomplete JSON file`,"TOKEN_FILE_INCOMPLETE_JSON"),TOKEN_FILE_GENERIC_ERROR:o((e,t)=>`File ${e}: ${t}`,"TOKEN_FILE_GENERIC_ERROR"),DEPENDENCY_INSTALL_FAILED:o(e=>`Failed to install dependencies using ${e}.
|
|
49
|
+
Please check your package manager configuration and try again.`,"DEPENDENCY_INSTALL_FAILED"),VALIDATE_NO_PATH_SPECIFIED:o(()=>`No path specified.
|
|
50
|
+
|
|
51
|
+
Run ${c.cyan("make-sugarcube validate --help")} for more information.`,"VALIDATE_NO_PATH_SPECIFIED"),VALIDATE_PATH_NOT_FOUND:o(e=>`Path not found: ${e}
|
|
52
|
+
|
|
53
|
+
Please check that the specified path exists`,"VALIDATE_PATH_NOT_FOUND"),VALIDATE_NO_TOKEN_FILES:o(()=>`No token files found.
|
|
54
|
+
|
|
55
|
+
Please ensure the path contains .json token files`,"VALIDATE_NO_TOKEN_FILES"),COMPONENTS_FRAMEWORK_REQUIRED:o(()=>`Framework is required when specifying components. Use --framework to specify a framework (react, css-only) or run without arguments for interactive mode.
|
|
56
|
+
|
|
57
|
+
See ${c.cyan("https://sugarcube.sh/docs/cli/components")} for more information.`,"COMPONENTS_FRAMEWORK_REQUIRED"),COMPONENTS_INVALID_FRAMEWORK:o(()=>"Invalid framework. Must be one of: react, css-only.","COMPONENTS_INVALID_FRAMEWORK"),COMPONENTS_DIRECTORY_NOT_CONFIGURED:o(()=>"Components directory must be configured in non-interactive mode. Please run the 'components' command without arguments first.","COMPONENTS_DIRECTORY_NOT_CONFIGURED"),PLUGIN_DETECTED:o(e=>`Plugin detected: ${e}
|
|
58
|
+
|
|
59
|
+
The 'generate' command is for manual generation without plugins. Since you have a plugin installed, use your development server instead:
|
|
60
|
+
|
|
61
|
+
npm run dev # or your framework's dev command
|
|
62
|
+
|
|
63
|
+
The plugin will automatically generate CSS with hot module replacement.`,"PLUGIN_DETECTED")};class g extends Error{static{o(this,"CLIError")}constructor(t,n){super(t),this.name="CLIError",this.cause=n}}const ue=m.enum(["react","web-components","css-only"]),De=m.object({path:m.string(),type:m.string()}),kt=De.extend({framework:ue});m.object({modes:m.record(m.string(),m.array(m.string())).optional(),themes:m.record(m.string(),m.array(m.string())).optional()}).strict();const Et=m.object({name:m.string(),type:m.string(),description:m.string().optional(),frameworks:m.array(m.string()).optional(),files:m.array(m.union([kt,De])),tokens:m.record(m.object({type:m.string(),mapping:m.string()})).optional(),dependencies:m.record(ue,m.array(m.string())).optional(),registryDependencies:m.record(ue,m.array(m.string())).optional(),tokenDependencies:m.array(m.string()).optional()}),bt=m.array(Et),Ct=m.object({content:m.string()}),Ae=process.env.REGISTRY_URL??"https://sugarcube.sh/r";async function ve(e){try{const t=await Qe(e);if(!t.ok){if(t.status===401)throw new g(w.REGISTRY_AUTH_REQUIRED(e));if(t.status===403)throw new g(w.REGISTRY_AUTH_INVALID(e));if(t.status===404)throw new g(w.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(w.REGISTRY_REQUEST_FAILED(s,e))}return t.json()}catch(t){throw t instanceof g?t:new g(w.REGISTRY_NETWORK_ERROR(e))}}o(ve,"fetchRegistry");async function j(){const e=`${Ae}/index.json`,t=await ve(e);try{return bt.parse(t)}catch{throw new g(w.REGISTRY_INVALID_DATA(e))}}o(j,"getRegistryIndex");async function fe({type:e,name:t,framework:n}){const s=await j(),r=s.find(a=>a.type===e&&a.name===t);if(!r){const a=s.filter(l=>l.type===e).map(l=>l.name);throw new g(w.REGISTRY_ITEM_NOT_FOUND(e,t,a))}let i=r.files;e==="component"&&n&&(i=r.files.filter(a=>"framework"in a&&a.framework===n));const u=await Promise.all(i.map(async a=>{const l=`${Ae}/${a.path}.json`,f=await ve(l);try{const p=Ct.parse(f);return{path:a.path,type:a.type,framework:"framework"in a?a.framework:void 0,content:p.content}}catch{throw new g(w.REGISTRY_FILE_INVALID(a.path))}}));return{item:r,files:u}}o(fe,"getRegistryFiles");async function $t(e){const t=await fe({type:"tokens",name:e});if(!t.files[0])throw new g(w.STARTER_KIT_UNAVAILABLE(e));return t}o($t,"fetchStarterKit");async function pe(e,t,n){const s=[],r=new Set;async function i(u){if(r.has(u))return;r.add(u);const a=e.find(f=>f.name===u);if(!a){const f=e.filter(p=>p.type==="component").map(p=>p.name).join(", ");throw new g(`Component '${u}' not found in registry
|
|
64
|
+
Available components: ${f}`)}const l=a.registryDependencies?.[n]||[];for(const f of l)await i(f);s.push(a)}o(i,"resolveComponent");for(const u of t)await i(u);return s}o(pe,"resolveTree");async function Rt({selectedComponents:e,componentType:t,componentsOutputDirectory:n}){const s={variableCSS:[],utilityCSS:[],componentFiles:[],componentCSS:[],cubeCSS:[],indexFiles:[]},r=await j(),u=(await pe(r,e,t)).map(p=>p.name),a=r.filter(p=>p.type==="component").filter(p=>u.includes(p.name)),l=a.flatMap(p=>p.files.filter(d=>(d.type==="tsx"||d.type==="astro"||d.type==="njk")&&"framework"in d&&d.framework===t).map(d=>$(process.cwd(),R(n,p.name,`${p.name}.${d.type}`))));s.componentFiles=l.filter(p=>F(R(process.cwd(),p)));const f=a.map(p=>{const d=p.name;return $(process.cwd(),R(n,p.name,`${d}.css`))});return s.componentCSS=f.filter(p=>F(R(process.cwd(),p))),s}o(Rt,"collectComponentOverwriteWarnings");async function _t({cubeDirectory:e}){const t={variableCSS:[],utilityCSS:[],componentFiles:[],componentCSS:[],cubeCSS:[],indexFiles:[]},s=(await j()).filter(r=>r.type==="cube").flatMap(r=>r.files).map(r=>{const i=r.path.replace(/^styles\//,"");return $(process.cwd(),R(e,i))});return t.cubeCSS=s.filter(r=>F(R(process.cwd(),r))),t}o(_t,"collectCubeOverwriteWarnings");function Ne(e){const t=[];if(e.variableCSS.length>0&&t.push(`CSS variables files:
|
|
65
|
+
${e.variableCSS.map(s=>` - ${s}`).join(`
|
|
66
|
+
`)}`),e.utilityCSS.length>0&&t.push(`CSS utility files:
|
|
67
|
+
${e.utilityCSS.map(s=>` - ${s}`).join(`
|
|
68
|
+
`)}`),e.cubeCSS.length>0&&t.push(`CUBE CSS files:
|
|
69
|
+
${e.cubeCSS.map(s=>` - ${s}`).join(`
|
|
70
|
+
`)}`),e.componentFiles.length>0||e.componentCSS.length>0){const s=[...e.componentFiles,...e.componentCSS];t.push(`Component files:
|
|
71
|
+
${s.map(r=>` - ${r}`).join(`
|
|
72
|
+
`)}`)}return e.indexFiles.length>0&&t.push(`Index files:
|
|
73
|
+
${e.indexFiles.map(s=>` - ${s}`).join(`
|
|
74
|
+
`)}`),t.length===0?void 0:`The following file(s) already exist and will be overwritten:
|
|
75
|
+
|
|
76
|
+
${t.join(`
|
|
77
|
+
|
|
78
|
+
`)}`}o(Ne,"formatOverwriteWarnings");async function de(e,t,n){if(e.length===0)return;const s=n==="npm"?"install":"add";try{await et(n,[s,...e],{cwd:t})}catch{throw new g(w.DEPENDENCY_INSTALL_FAILED(n))}}o(de,"installDependencies");async function Dt(e,t,n){const s=R(n,t.name);if(await B(s,{recursive:!0}),e.path.endsWith(".css")){const i=R(s,`${t.name}.css`);return await X(i,e.content),i}const r=R(s,G(e.path));return await X(r,e.content),r}o(Dt,"writeComponentFile");async function At({registryIndex:e,selectedComponents:t,componentType:n,componentsOutputDirectory:s,packageManager:r}){const i=[],u=new Set;await B(s,{recursive:!0});const a=await pe(e,t,n);for(const l of a){const f=await fe({type:"component",name:l.name,framework:n});for(const d of f.files)if(d)try{const h=await Dt(d,l,s);h&&i.push(h)}catch(h){const E=h instanceof Error?`: ${h.message}`:"";throw new g(`Failed to write component file for "${l.name}"${E}`)}const p=l.dependencies?.[n]||[];for(const d of p)u.add(d)}if(u.size>0)try{await de(Array.from(u),process.cwd(),r)}catch(l){const f=l instanceof Error?`: ${l.message}`:"";throw new g(`Failed to install component dependencies${f}`)}return{createdFiles:i,npmDependencies:u}}o(At,"installComponents");function vt(e,t){const n=L(e),s=L(t);return n.startsWith(`${s}/`)||n===s}o(vt,"isWithinDirectory");async function Nt(e){const t=[],n=L(process.cwd(),e);await B(n,{recursive:!0});const r=(await j()).filter(i=>i.type==="cube").map(i=>i.name);for(const i of r){const u=await fe({type:"cube",name:i});for(const a of u.files){if(!a)continue;const l=a.path.replace(/^styles\//,""),f=L(n,l);if(!vt(f,n))throw new g(`Invalid file path detected in CUBE module "${i}": path escapes target directory`);const p=ze(f);try{await B(p,{recursive:!0}),await X(f,a.content),t.push(f)}catch(d){const h=d instanceof Error?`: ${d.message}`:"";throw new g(`Failed to write CUBE module "${i}"${h}`)}}}return t}o(Nt,"installCUBE");async function Ft(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}o(Ft,"writeTokenFiles");async function K(e,t){const n={type:"files",config:e},{trees:s,resolved:r,errors:i}=await tt(n);if(i.load.length>0){const u=i.load.map(a=>{const l=a.file.split("/").pop()||"unknown file";let f=`File ${l}: `;return a.message.includes("Unexpected token")?f=w.TOKEN_FILE_INVALID_JSON(l):a.message.includes("Unexpected end")?f=w.TOKEN_FILE_INCOMPLETE_JSON(l):f=w.TOKEN_FILE_GENERIC_ERROR(l,a.message),f});throw new g(w.TOKEN_LOAD_FAILED(u))}if(i.validation.length>0||i.flatten.length>0||i.resolution.length>0){const u=[...i.flatten,...i.validation,...i.resolution],a=new Map;for(const l of u)if(l.source?.sourcePath){const f=a.get(l.source.sourcePath)||[];f.push(l.message),a.set(l.source.sourcePath,f)}throw new g(w.TOKEN_VALIDATION_FAILED(a))}return{trees:s,resolved:r}}o(K,"loadAndResolveTokensForCLI");function Ot(e,t){const n={...e},s=t.modes&&Object.keys(t.modes).length>0,r=t.themes&&Object.keys(t.themes).length>0;return(s||r)&&typeof n.tokens=="object"&&!Array.isArray(n.tokens)&&"source"in n.tokens&&(s&&(n.tokens.modes=t.modes),r&&(n.tokens.themes=t.themes)),nt(n)}o(Ot,"integrateVariantsIntoConfig");const{hidden:ms}=c,Pt=at(),k=o((e,t)=>Pt?e:t,"unicodeOr"),Lt=k("\u25C7","o"),Fe=k("\u250C","T"),O=k("\u2502","|"),ge=k("\u2514","\u2014"),Mt=k("\u2510","T"),jt=k("\u2518","\u2014"),te=k("\u2500","-"),Ut=k("\u256E","+"),xt=k("\u256F","+"),Wt=k("\u2570","+"),Gt=k("\u256D","+"),Bt=k("\u25CF","\u2022"),Vt=k("\u25C6","*"),Kt=k("\u25B2","!"),Yt=k("\u25A0","x"),Y=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"),J=o((e="",t)=>{process.stdout.write(`
|
|
79
|
+
|
|
80
|
+
${c.gray(Fe)}${c.gray(te)} ${e}
|
|
81
|
+
`)},"intro"),ne=o((e="",t)=>{process.stdout.write(`${c.gray(O)}
|
|
82
|
+
${c.gray(ge)}${c.gray(te)} ${e}
|
|
83
|
+
|
|
84
|
+
`)},"outro");function Ht(...e){process.env.DEBUG==="true"&&process.stderr.write(`[sugarcube:debug] ${e.map(String).join(" ")}
|
|
85
|
+
`)}o(Ht,"debugLog");function U(e){return new Promise(t=>setTimeout(t,e))}o(U,"sleep");function Jt(e,t){const n={},s={};if(e.modes)for(const[r,i]of Object.entries(e.modes))n[r]=i.map(u=>{const a=t[u];if(!a)throw new g(w.KIT_INCOMPLETE());return a});if(e.themes)for(const[r,i]of Object.entries(e.themes))s[r]=i.map(u=>{const a=t[u];if(!a)throw new g(w.KIT_INCOMPLETE());return a});return{modes:n,themes:s}}o(Jt,"processKitVariants");const qt=o(async(e,t,n)=>{const s=await $t(e),r=L(process.cwd(),t),i=s.files.find(d=>G(d.path)==="config.json");let u={};if(i)try{u=JSON.parse(i.content)}catch(d){Ht(`Could not parse config.json for starter kit '${e}':`,d)}const a=s.files.filter(d=>G(d.path)!=="config.json").map(d=>({path:R(r,G(d.path)),content:d.content})),l=Object.fromEntries(a.map(d=>[G(d.path),$(process.cwd(),d.path)])),f=Jt(u,l);return{config:Ot(n,f),tokenFiles:a,tokensDir:r,createdTokenPaths:a.map(d=>$(process.cwd(),d.path))}},"prepareStarterKitForInstall");async function zt(e){const t=await qt(e.starterKit??"",e.tokensDir,e.config),n=await Ft(t.tokenFiles,e.tokensDir),{trees:s,resolved:r}=await K(e.config);e.setupResult={config:t.config,createdTokenPaths:t.createdTokenPaths,trees:s,resolved:r,tokenFiles:t.tokenFiles,tokensDir:t.tokensDir},e.createdFiles.push(...n)}o(zt,"installFromStarterKit");async function Oe(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 lt({message:"Build with",options:t});return ae(n)&&process.exit(0),n==="web-components"?(ut.info(c.blue("Web components are coming soon! Please choose React or CSS Only for now.")),Oe(e)):n}o(Oe,"promptComponentFramework");async function Zt(e,t){const n=e.filter(r=>r.type==="component"&&r.frameworks?.includes(t)),s=await ft({message:"Select components to add",options:n.map(r=>({label:r.name,value:r.name,hint:r.description})),required:!0});return ae(s)&&process.exit(0),s}o(Zt,"promptComponentSelectionFiltered");async function Pe(e,t=!1){const n=await pt({message:e,initialValue:t});return(!n||ae(n))&&(Ee(),process.exit(0)),!0}o(Pe,"confirmOverwrite");const Qt=[Gt,Ut,Wt,xt],Xt=[Fe,Mt,ge,jt];function Le(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(Le,"getPaddingForLine");const en=o(e=>e,"defaultFormatBorder"),me=o((e="",t="",n)=>{const s=n?.output??process.stdout,r=dt(s),u=1*2,a=n?.titlePadding??1,l=n?.contentPadding??2,f=n?.width===void 0||n.width==="auto"?1:Math.min(1,n.width),p=n?.includePrefix?`${O} `:"",d=n?.formatBorder??en,h=(n?.rounded?Qt:Xt).map(d),E=d(te),b=d(O),T=r-p.length;let C=Math.floor(r*f)-p.length;if(n?.width==="auto"){const Z=e.split(`
|
|
86
|
+
`);let W=H(t).length+a*2;for(const Je of Z){const ye=H(Je).length+l*2;ye>W&&(W=ye)}const Q=W+u;Q<C&&(C=Q)}C%2!==0&&(C<T?C++:C--);const I=C-u,N=I-a*2,y=H(t).length>N?`${t.slice(0,N-3)}...`:t,[_,D]=Le(H(y).length,I,a,n?.titleAlign),P=gt(e,I-l*2,{hard:!0,trim:!1});s.write(`${p}${h[0]}${E.repeat(_)}${y}${E.repeat(D)}${h[1]}
|
|
87
|
+
`);const z=P.split(`
|
|
88
|
+
`);for(const Z of z){const[W,Q]=Le(H(Z).length,I,l,n?.contentAlign);s.write(`${p}${b}${" ".repeat(W)}${Z}${" ".repeat(Q)}${b}
|
|
89
|
+
`)}s.write(`${p}${h[2]}${E.repeat(I)}${h[3]}
|
|
90
|
+
`)},"box");function he(e,t={}){const n=`
|
|
91
|
+
${e}`;me(n,c.black(c.bgRed(" ERROR ")),{width:"auto",titlePadding:2,formatBorder:c.red,...t})}o(he,"errorBoxWithBadge");function Me(e,t={}){const n=`
|
|
92
|
+
${e}`;me(n,c.black(c.bgYellow(" WARNING ")),{width:"auto",titlePadding:2,formatBorder:c.yellow,...t})}o(Me,"warningBoxWithBadge");function tn(e,t={}){const n=`
|
|
93
|
+
${e}`;me(n,c.black(c.bgCyan(" INFO ")),{width:"auto",titlePadding:2,formatBorder:c.cyan,...t})}o(tn,"infoBoxWithBadge");const nn=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"),sn=o(async(e,t={})=>{const{sidebarSymbol:n=c.gray("\u2502"),clear:s=!1,stdin:r=process.stdin,stdout:i=process.stdout}=t,u=Ce.createInterface({input:r,escapeCodeTimeout:50}),a=$e(i,{showCursor:!1});Ce.emitKeypressEvents(r,u);let l=0,f=!1;const p=o(async()=>{r.off("keypress",d),r.isTTY&&r.setRawMode(!1),u.close(),f=!0,l<e.length-1||s?a.clear():a.done()},"done"),d=o((h,E)=>{r.isTTY&&r.setRawMode(!0);const b=nn(E);if(b==="abort")return p(),process.exit(0);["up","down","left","right"].includes(b)||p()},"handleKeyPress");r.isTTY&&r.setRawMode(!0),r.on("keypress",d);for(const h of e){const E=Array.isArray(h)?h:h.split(" "),b=[];for(const I of[""].concat(E)){I&&b.push(I);const N=b.join(" ").replace(/sugarcube/g,c.cyan("sugarcube")),y=`${n} ${N}`;a(y),f||await new Promise(_=>setTimeout(_,Math.floor(Math.random()*126)+75))}f||await new Promise(I=>setTimeout(I,100));const C=(await Promise.all(E).then(I=>I.join(" "))).replace(/sugarcube/g,c.cyan("sugarcube"));a(`${n} ${C}`),f||await new Promise(I=>setTimeout(I,Math.floor(Math.random()*201)+1200)),l++}r.off("keypress",d),await new Promise(h=>setTimeout(h,100)),p(),r.isTTY&&r.setRawMode(!1),r.removeAllListeners("keypress")},"sayAnimatedInSidebar");function on(){return Math.floor(Math.random()*551)+200}o(on,"getRandomTaskDuration");async function rn(e,{sidebarSymbol:t="\u2502",spacing:n=1,stdin:s=process.stdin,stdout:r=process.stdout,initialDelayMs:i=200,minDurationMs:u,successPauseMs:a=300,successMessage:l,successAsOutro:f=!1}={}){const p=o((y,_)=>{let D="";switch(_){case"start":D=`${c.cyan(`\u25B6 ${y.start}`)}`;break;case"pending":D=`${c.dim(`\u25A1 ${y.pending}`)}`;break;case"success":D=`${c.green(`\u2714 ${y.end}`)}`;break;case"end":D=`${c.dim(`\u25A0 ${y.end}`)}`;break}return`${t} ${D}`},"formatWithSidebar"),d=Array.from({length:e.length},()=>"");e.forEach((y,_)=>{d[_]=p(y,"pending")});const h=$e(r),E=be.createInterface({input:s,escapeCodeTimeout:50});be.emitKeypressEvents(s,E);const b=o(y=>{y===""&&(h.clear(),E.close(),s.isTTY&&s.setRawMode(!1),process.exit(0)),s.isTTY&&s.setRawMode(!0)},"keypress");s.isTTY&&s.setRawMode(!0),s.on("keypress",b);const T=Array.from({length:Math.max(n,0)},()=>`${t}`),C=o(()=>[...T,...d].join(`
|
|
94
|
+
`),"renderContent");h(C()),await U(i);let I=0;for(const y of e){d[I]=p(y,"start"),h(C());const _=Date.now(),D=y.while();try{await D;const P=Date.now()-_,z=typeof u=="number"?u:on();P<z&&await U(z-P),d[I]=p(y,"success"),h(C()),await U(a)}catch(P){throw d[I]=`${t} ${c.red(`\u2717 ${y.end} (failed)`)}`,h(C()),y.onError?.(P),s.removeListener("keypress",b),E.close(),s.isTTY&&s.setRawMode(!1),P}I++}const N=e.map(y=>p(y,"end"));if(l)if(f){const y=`${c.gray(ge)}${c.gray(te)} ${c.green(l)}`;h([...T,...N,`${t}`,y].join(`
|
|
95
|
+
`))}else{const y=`${t} ${c.green(l)}`;h([...T,...N,`${t}`,y].join(`
|
|
96
|
+
`))}else h([...T,...N].join(`
|
|
97
|
+
`));await U(1e3),s.removeListener("keypress",b),s.isTTY&&s.setRawMode(!1),E.close(),h.done()}o(rn,"executeTasksInSidebar");const an=o(e=>process.stdout.write(`${e}
|
|
98
|
+
`),"rawLog"),S={message:o((e=[],{symbol:t=c.gray(O),secondarySymbol:n=c.gray(O),output:s=process.stdout,spacing:r=1}={})=>{const i=[];for(let a=0;a<r;a++)i.push(`${n}`);const u=Array.isArray(e)?e:e.split(`
|
|
99
|
+
`);if(u.length>0){const[a,...l]=u;a&&a.length>0?i.push(`${t} ${a}`):i.push(t);for(const f of l)f.length>0?i.push(`${n} ${f}`):i.push(n)}s.write(`${i.join(`
|
|
100
|
+
`)}
|
|
101
|
+
`)},"message"),info:o((e,t)=>{S.message(e,{...t,symbol:c.blue(Bt)})},"info"),success:o((e,t)=>{S.message(e,{...t,symbol:c.green(Vt)})},"success"),step:o((e,t)=>{S.message(e,{...t,symbol:c.green(Lt)})},"step"),warn:o((e,t)=>{S.message(e,{...t,symbol:c.yellow(Kt)})},"warn"),error:o((e,t)=>{S.message(e,{...t,symbol:c.red(Yt)})},"error"),animated:o(async(e,{secondarySymbol:t=c.gray(O),output:n=process.stdout,clear:s=!1,...r}={})=>sn(e,{sidebarSymbol:t,stdout:n,clear:s,...r}),"animated"),tasks:o(async(e,{spacing:t=1,secondarySymbol:n=c.gray(O),output:s=process.stdout,...r}={})=>rn(e,{sidebarSymbol:n,spacing:t,stdout:s,...r}),"tasks"),space:o((e=1)=>{for(let t=0;t<e;t++)process.stdout.write(`${c.gray(O)}
|
|
102
|
+
`)},"space"),break:o((e=1)=>{for(let t=0;t<e;t++)process.stdout.write(`
|
|
103
|
+
`)},"break")};function q(e){if(e instanceof g)S.space(1),he(e.message,{});else{const t=`An unexpected error occurred: ${e instanceof Error?e.message:String(e)}
|
|
104
|
+
|
|
105
|
+
If this issue persists, please report it: ${c.cyan("https://github.com/sugarcube-org/sugarcube/issues")}`;S.space(1),he(t,{})}process.exit(0)}o(q,"handleError");function je(e){return{absolute:L(process.cwd(),e)}}o(je,"resolveDirectoryFromFlag");async function Ue(e){if(A())try{const{config:t}=await ee(),n=cn(t,e);return typeof n=="string"?L(process.cwd(),n):void 0}catch{return}}o(Ue,"resolveDirectoryFromConfig");function cn(e,t){const n=t.split(".");let s=e;for(const r of n){if(s==null||typeof s!="object")return;s=s[r]}return s}o(cn,"getNestedValue");async function ln(e){if(e){const{absolute:t}=je(e);return{directory:t,fromConfig:!1}}if(A())try{const t=await Ue("output.css");if(t)return{directory:t,fromConfig:!0}}catch{}throw new g(`A sugarcube config file was not found.
|
|
106
|
+
|
|
107
|
+
Either a config file or --styles-dir is required to run this command.
|
|
108
|
+
|
|
109
|
+
To use the cube command without a config file:
|
|
110
|
+
e.g. ${c.cyan(`${v.CUBE} --styles-dir src/styles`)}
|
|
111
|
+
|
|
112
|
+
To create a config file:
|
|
113
|
+
${c.cyan(v.INIT)}
|
|
114
|
+
|
|
115
|
+
Stuck? ${c.cyan("https://sugarcube.sh")}`)}o(ln,"getCssDir");async function un(e){if(e){const{absolute:t}=je(e);return{directory:t,fromConfig:!1}}if(A())try{const t=await Ue("output.components");if(t)return{directory:t,fromConfig:!0}}catch{}throw new g(`A sugarcube config file was not found.
|
|
116
|
+
|
|
117
|
+
Either a config file or --components-dir is required to run this command.
|
|
118
|
+
|
|
119
|
+
To use the components command without a config file:
|
|
120
|
+
e.g. ${c.cyan(`${v.COMPONENTS} --components-dir src/components/ui`)}
|
|
121
|
+
|
|
122
|
+
To create a config file:
|
|
123
|
+
${c.cyan(v.INIT)}
|
|
124
|
+
|
|
125
|
+
Stuck? ${c.cyan("https://sugarcube.sh")}`)}o(un,"getComponentsDir");function x(e,t=process.cwd()){try{const n=ct(t,"package.json");if(!F(n))return!1;const s=Te(n,"utf-8"),r=JSON.parse(s),i={...r.dependencies,...r.devDependencies,...r.peerDependencies};return e in i}catch{return!1}}o(x,"isPackageInstalled");async function xe(e,{withFallback:t=!1}={}){const n=await mt({programmatic:!0,cwd:e});if(n?.startsWith("yarn@"))return"yarn";if(n?.startsWith("pnpm@"))return"pnpm";if(n==="bun")return"bun";if(!t)return n?.split("@")[0]??"npm";const s=process.env.npm_config_user_agent||"";return s.startsWith("yarn")?"yarn":s.startsWith("pnpm")?"pnpm":s.startsWith("bun")?"bun":"npm"}o(xe,"getPackageManager");function fn(e=process.cwd()){return ht(e)!==null}o(fn,"isTypeScriptProject");async function We(e=process.cwd()){return fn(e)?"sugarcube.config.ts":"sugarcube.config.js"}o(We,"getConfigFileName");function pn(e){return/^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(e)}o(pn,"isValidIdentifier");function we(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?"[]":`[
|
|
126
|
+
${e.map(r=>`${n} ${we(r,t+1)}`).join(`,
|
|
127
|
+
`)}
|
|
128
|
+
${n}]`;if(typeof e=="object"){const s=Object.entries(e);return s.length===0?"{}":`{
|
|
129
|
+
${s.map(([i,u])=>{const a=pn(i)?i:JSON.stringify(i);return`${n} ${a}: ${we(u,t+1)}`}).join(`,
|
|
130
|
+
`)}
|
|
131
|
+
${n}}`}return JSON.stringify(e)}o(we,"formatValue");function dn(e,t,n){const s=we(e,0);let r;return n?r=t?`import type { UserConfig } from "@sugarcube-org/vite";
|
|
132
|
+
|
|
133
|
+
const config: UserConfig = `:`/**
|
|
134
|
+
* @type {import('@sugarcube-org/vite').UserConfig}
|
|
135
|
+
*/
|
|
136
|
+
const config = `:r=`// Configuration reference: ${_e.CONFIGURATION}
|
|
137
|
+
const config = `,`${r}${s};
|
|
138
|
+
|
|
139
|
+
export default config;
|
|
140
|
+
`}o(dn,"formatConfigAsCode");async function Ge(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 g(`Failed to write config file${s}`)}}o(Ge,"writeUserConfig");function gn(e,t){return{...e,...t,output:{...e.output??{},...t.output??{}},transforms:{...e.transforms??{},...t.transforms??{}}}}o(gn,"mergeUserConfig");async function Be(e){const{config:t}=await st(),n=gn(t,e),s=x(le);await Ge(n,s)}o(Be,"mergeConfigIntoFile");const mn=new M().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||J(Y(c.bgGreen(c.black("Components"))));const{directory:n,fromConfig:s}=await un(t.componentsDir);let r=[],i;if(e.length>0||t.framework){if(!t.framework)throw new g(w.COMPONENTS_FRAMEWORK_REQUIRED());if(!["react","css-only"].includes(t.framework))throw new g(w.COMPONENTS_INVALID_FRAMEWORK());i=t.framework,r=e}else{i=await Oe(!1);const T=await j();T||(Ee("Failed to fetch component list"),process.exit(1)),r=await Zt(T,i)}const u=await xe(process.cwd(),{withFallback:!0}),a=await j(),l=await pe(a,r,i),f=await Rt({selectedComponents:r,componentType:i,componentsOutputDirectory:n}),p=Ne(f);if(p&&!t.force&&!t.silent){const T=Me(p,{});S.space(1),await Pe("Continue?",!1)}const d=[],h=[],E=new Set;for(const T of l){const C=T.dependencies?.[i]||[];for(const I of C)E.add(I)}const b=Array.from(E).filter(T=>!x(T,process.cwd()));b.length>0&&d.push({pending:`Install ${b.length} dependencies`,start:`Installing ${b.join(", ")}...`,end:`Installed ${b.join(", ")}`,while:o(async()=>{await de(b,process.cwd(),u)},"while")});for(const T of l)d.push({pending:`Write component files for ${T.name}`,start:`Writing component files for ${T.name}...`,end:`Wrote component files for ${T.name}`,while:o(async()=>{const C=await At({registryIndex:a,selectedComponents:[T.name],componentType:i,componentsOutputDirectory:n,overwrite:t.overwrite||!1,packageManager:u});h.push(...C.createdFiles)},"while")});if(await S.tasks(d,{successMessage:"Components added successfully! \u{1F389} ",minDurationMs:0,successAsOutro:!0}),an(""),!s&&A()){const T=$(process.cwd(),n);await Be({output:{components:T}})}}catch(n){q(n)}}),hn=new M().name("cube").description("Add CUBE CSS to your project").option("-s, --silent","Suppress logs and prompts").option("-f, --force","Skip overwrite confirmation").option("--styles-dir <dir>","CSS output directory (e.g., 'src/styles')").action(async e=>{try{e.silent||J(Y("CUBE CSS"));const{directory:t,fromConfig:n}=await ln(e.stylesDir);try{await B(t,{recursive:!0})}catch(u){const a=u instanceof Error?`: ${u.message}`:"";throw new g(`Failed to create output directory${a}`)}const s=await _t({cubeDirectory:t}),r=Ne(s);if(r&&!e.force&&!e.silent){S.space(1);const u=Me(r,{});await Pe("Continue?",!1)}const i=await Nt(t);if(!e.silent){S.space(1);const u=i,f=[...new Set(u)].map(p=>$(process.cwd(),p)).map(p=>({pending:`Write ${p}`,start:`Writing ${p}`,end:`Wrote ${p}`,while:o(async()=>{},"while")}));await S.tasks(f,{spacing:0,minDurationMs:0,successPauseMs:100,successMessage:"\u{1F389} Files written!"}),ne(c.green("CUBE added successfully."))}if(!n&&A()){const u=$(process.cwd(),t);await Be({output:{css:u}})}}catch(t){q(t)}});function wn(){return["**/*.{html,htm,js,ts,jsx,tsx,vue,svelte,astro,php,njk,liquid,pug,hbs,handlebars,twig,erb,ejs}","!node_modules/**","!dist/**","!build/**","!.next/**","!.nuxt/**","!.astro/**","!.git/**","!coverage/**","!*.config.{js,ts,mjs}"]}o(wn,"getDefaultScanPatterns");function yn(){return wn()}o(yn,"getScanPatterns");async function Ve(e,t){const n={name:"sugarcube",rules:ot(t.utilities??{},e),preflights:[]},s=await wt({presets:[n]}),r=yn(),i=await V(r,{dot:!0});if(i.length===0)return[];const a=(await Promise.all(i.map(f=>Xe(f,"utf8")))).join(`
|
|
141
|
+
`),{css:l}=await s.generate(a,{preflights:!1});return l?.trim()?[{path:`${t.output?.css||rt}/utilities/utilities.gen.css`,css:l,collection:"default"}]:[]}o(Ve,"generateSugarcubeUtilities");async function Tn(e,t,n){const s=[],r=await oe(e,t,n),i=await Se(r,n);await Ie(i),s.push(...i);const u=await Ve(r,n);return await ke(u),s.push(...u),s}o(Tn,"generateAllCSS");const Sn=new M().name("generate").description("Generate CSS from your design tokens").option("--force","Skip overwrite confirmation").option("-s, --silent","Suppress logs and prompts").action(async e=>{try{if(e.silent||J(Y("Generate CSS")),x("@sugarcube-org/vite"))throw new g("Sugarcube vite plugin detected. When using the plugin, CSS is generated automatically during your build process. Remove the plugin to use CLI generation instead.");if(!A())throw new g(`A sugarcube config file was not found. This command requires one.
|
|
142
|
+
|
|
143
|
+
Please run ${c.cyan(v.INIT)} (or manually create a config file).
|
|
144
|
+
|
|
145
|
+
Stuck? ${c.cyan("https://sugarcube.sh")}`);const{config:t}=await ee(),{trees:n,resolved:s}=await K(t),r=await Tn(n,s,t);if(!e.silent){const i=r.map(f=>f.path),l=[...new Set(i)].map(f=>$(process.cwd(),f)).map(f=>({pending:`Write ${f}`,start:`Writing ${f}`,end:`Wrote ${f}`,while:o(async()=>{},"while")}));await S.tasks(l,{spacing:1,minDurationMs:0,successPauseMs:100,successMessage:"\u{1F389} Files written!"}),S.space(1),ne(c.green("CSS generated successfully."))}}catch(t){q(t)}});function In(e){return{source:[R($(process.cwd(),e.actualTokensDir),Re)]}}o(In,"createSingleTokenCollection");async function kn(e){return In(e)}o(kn,"buildTokensConfig");async function En(e){const t=await kn({actualTokensDir:e.actualTokensDir}),n=$(process.cwd(),e.actualStylesDir),s=e.isSrcDir?re.output.components:re.output.components.replace(/^src\//,"");return{tokens:t,output:{css:n,components:s,separate:re.output.separate}}}o(En,"buildUserConfig");function Ke(e,t=0){if(typeof e!="object"||e===null||t>It)return!1;for(const[n,s]of Object.entries(e))if(!n.startsWith("$")&&typeof s=="object"&&s!==null&&("$value"in s||Ke(s,t+1)))return!0;return!1}o(Ke,"hasAnyToken");async function bn(e){try{const t=await V(Re,{cwd:e,absolute:!0});for(const n of t)try{const s=await se.readFile(n,"utf-8"),r=JSON.parse(s);if(Ke(r))return!0}catch{}return!1}catch{return!1}}o(bn,"detectExistingTokens");const Ye=["**/node_modules/**",".next","public","dist","build",".astro",".nuxt",".output",".svelte-kit"];function Cn(e){try{const t=ie.resolve(e,"package.json");if(!F(t))return null;const n=Te(t,"utf-8");return JSON.parse(n)}catch{return null}}o(Cn,"getPackageJson");async function $n(e){const[t,n,s]=await Promise.all([V.glob("**/{next,vite,astro,nuxt,svelte,remix,eleventy}.config.*|.eleventy.js",{cwd:e,deep:3,ignore:Ye}),F(ie.resolve(e,"src")),Cn(e)]),r=n?"src/design-tokens":"design-tokens",i=n?"src/styles":"styles",u=n?"src/components":"components";let a="none";return t.find(l=>l.startsWith("next.config."))?.length?a=F(ie.resolve(e,`${n?"src/":""}app`))?"next-app":"next-pages":t.find(l=>l.startsWith("astro.config."))?.length?a="astro":t.find(l=>l.startsWith("nuxt.config."))?.length?a="nuxt":t.find(l=>l.startsWith("svelte.config."))?.length?a="sveltekit":Object.keys(s?.dependencies??{}).find(l=>l.startsWith("@remix-run/"))?a="remix":t.find(l=>l.startsWith("eleventy.config.")||l.startsWith(".eleventy."))?.length?a="eleventy":t.find(l=>l.startsWith("vite.config."))?.length&&(a="vite"),{framework:a,isSrcDir:n,tokensDir:r,stylesDir:i,componentDir:u}}o($n,"getProjectInfo");async function Rn(e,t){return!!((await V.glob("vite.config.*",{cwd:e,deep:1,ignore:Ye})).length>0||["vite","astro","nuxt","sveltekit","remix"].includes(t))}o(Rn,"shouldInstallVitePlugin");const _n=o(async e=>{S.space(2),await U(200);let t="Next steps";if(e.pluginToInstall===le)t+=`
|
|
146
|
+
|
|
147
|
+
`,t+=`1. Import the generated CSS
|
|
148
|
+
`,t+=` ${c.cyan("import 'virtual:sugarcube.css'")}`;else{const n=`${e.stylesDir}/global/tokens.variables.gen.css`;t+=`
|
|
149
|
+
|
|
150
|
+
`,t+=`1. Import the generated CSS
|
|
151
|
+
`,t+=` ${c.cyan(`import './${n}'`)}`}t+=`
|
|
152
|
+
|
|
153
|
+
`,t+=`2. (Optional) Add CUBE CSS
|
|
154
|
+
`,t+=` ${c.cyan(v.CUBE)}`,t+=`
|
|
155
|
+
|
|
156
|
+
`,t+=`3. (Optional) Add components
|
|
157
|
+
`,t+=` ${c.cyan(v.COMPONENTS)}`,t+=`
|
|
158
|
+
|
|
159
|
+
`,t+=`Docs: ${c.cyan("https://sugarcube.sh")}`,tn(t,{width:.75}),await U(200),S.break(1)},"nextSteps");async function Dn(e){await _n(e)}o(Dn,"next");const An=o(async()=>{const e=["Welcome to sugarcube \u2014 the toolkit for seriously sweet frontends!"];S.space(1),await S.animated(e,{clear:!1})},"welcome");function He(e,t){if(!e||e.trim()==="")throw new g(w.DIRECTORY_PATH_EMPTY(t));const s=Ze(e).split("/")[0];if(s&&St.includes(s))throw new g(w.DIRECTORY_PATH_RESERVED(t,e))}o(He,"validateDirectoryPath");function vn(e){e.tokensDir&&He(e.tokensDir,"tokens-dir"),e.stylesDir&&He(e.stylesDir,"styles-dir")}o(vn,"validateOptions");async function Nn(){A()&&(he(w.CONFIG_EXISTS(),{}),process.exit(0))}o(Nn,"preflightInit");async function Fn(e){const t=await $n(process.cwd()),n=e.tokensDir||t.tokensDir,s=e.stylesDir||t.stylesDir,r=await bn(n);return{tokensDir:n,stylesDir:s,isSrcDir:t.isSrcDir,hasExistingTokens:r,framework:t.framework}}o(Fn,"initializeProjectContext");async function On(e,t,n){const s=t?null:e.kit||ce;if((e.skip||[]).includes("plugin"))return{starterKit:s,pluginToInstall:null};const i=await Pn(n);return{starterKit:s,pluginToInstall:i}}o(On,"determineInstallationTargets");async function Pn(e){return await Rn(process.cwd(),e)?le:null}o(Pn,"determinePlugin");async function Ln(e,t,n,s,r){const i=await xe(process.cwd(),{withFallback:!0});return{options:e,...t,isSrcDir:t.isSrcDir,config:n,userConfig:s,...r,packageManager:i,createdFiles:[],createdDirectories:[],installedDependencies:[],tasks:[]}}o(Ln,"buildInitContext");async function Mn(e){const{trees:t,resolved:n}=await K(e.config);e.setupResult={config:e.config,createdTokenPaths:[],trees:t,resolved:n,tokenFiles:[],tokensDir:e.tokensDir}}o(Mn,"processExistingTokens");async function jn(e){!e.hasExistingTokens&&e.starterKit?await zt(e):await Mn(e)}o(jn,"setupDesignTokens");async function Un(e){if(!e.setupResult)throw new g(w.INITIALIZATION_INCOMPLETE());const{trees:t,resolved:n}=e.setupResult,s=await oe(t,n,e.config),r=await Se(s,e.config);await Ie(r)}o(Un,"writeCSSVariables");async function xn(e){if(!e.setupResult)throw new g(w.INITIALIZATION_INCOMPLETE());const{trees:t,resolved:n}=e.setupResult,s=await oe(t,n,e.config),r=await Ve(s,e.config);r.length&&await ke(r)}o(xn,"writeCSSUtilities");async function Wn(e){if(e.pluginToInstall&&!x(e.pluginToInstall))try{await de([e.pluginToInstall],process.cwd(),e.packageManager),e.installedDependencies.push(e.pluginToInstall)}catch{throw new g(w.PLUGIN_INSTALL_FAILED({pluginToInstall:e.pluginToInstall,packageManager:e.packageManager}))}}o(Wn,"installPlugins");async function Gn(e){try{const t=!!e.pluginToInstall;await Ge(e.userConfig,t);const n=await We();e.createdFiles.push(n)}catch{throw new g(w.CONFIG_WRITE_FAILED())}}o(Gn,"finalize");function Bn(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} ${k("\u2192","->")} using them`,while:o(async()=>{},"while")}):e.starterKit&&t.push({pending:"Looking for existing tokens",start:"Looking for existing tokens...",end:`No existing tokens detected ${k("\u2192","->")} adding starter kit`,while:o(async()=>{},"while")}),e.pluginToInstall){const n="Vite";x(e.pluginToInstall)?t.push({pending:`Checking for ${n} compatibility`,start:`Checking for ${n} compatibility...`,end:`${n} plugin already installed ${k("\u2192","->")} skipping plugin installation`,while:o(async()=>{},"while")}):t.push({pending:"Checking for Vite compatibility",start:"Checking for Vite compatibility...",end:`Vite detected ${k("\u2192","->")} plugin will be installed`,while:o(async()=>{},"while")})}else{const n=e.options.skip?.includes("plugin");t.push({pending:"Checking for Vite compatibility",start:"Checking for Vite compatibility...",end:n?`Plugin skipped ${k("\u2192","->")} CSS will be generated as file(s)`:`No Vite detected ${k("\u2192","->")} CSS will be generated as file(s)`,while:o(async()=>{},"while")})}return t}o(Bn,"buildDetectionTasks");async function Vn(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:o(async()=>{await jn(e)},"while")}),!e.pluginToInstall)e.tasks.push({pending:"Generate CSS variables",start:"Generating CSS variables...",end:"CSS variables generated",while:o(async()=>{await Un(e)},"while")}),e.tasks.push({pending:"Generate CSS utilities",start:"Generating CSS utilities...",end:"CSS utilities generated",while:o(async()=>{await xn(e)},"while")});else if(e.pluginToInstall&&!x(e.pluginToInstall)){const t="Vite";e.tasks.push({pending:`Install ${t} plugin`,start:`Installing ${t} plugin...`,end:`${t} plugin installed`,while:o(async()=>{await Wn(e)},"while")})}e.tasks.push({pending:"Write configuration file",start:"Writing configuration file...",end:"Configuration file written",while:o(async()=>{await Gn(e)},"while")})}o(Vn,"buildExecutionTasks");const Kn=new M().name("init").description("Initialize a new sugarcube project").option("--kit <kit>",`Starter kit to use (default: ${ce})`,ce).option("--tokens-dir <dir>","Design tokens directory (e.g., 'src/design-tokens')").option("--styles-dir <dir>","Styles output directory (e.g., 'src/styles')").option("--with <items...>","Install optional items").option("--skip <items...>","Skip installation of specific items (e.g., plugin)").action(async e=>{let t;try{vn(e),await Nn();const n=await Fn(e),s=await En({actualTokensDir:n.tokensDir,actualStylesDir:n.stylesDir,isSrcDir:n.isSrcDir}),r=it(s),i=await On(e,n.hasExistingTokens,n.framework);t=await Ln(e,n,r,s,i),J(Y("sugarcube")),await An();const u=Bn(t);u.length>0&&(S.message("Detecting project\u2026"),await S.tasks(u,{minDurationMs:1e3})),t.tasks=[],await Vn(t),t.tasks.length>0&&(S.message("Setting things up\u2026"),await S.tasks(t.tasks,{successMessage:"\u{1F389} Tasks completed successfully!"})),await Dn(t)}catch(n){q(n)}}),Yn=new M().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(J(Y("Validate")),A()&&!e.length){const{config:s}=await ee();await K(s),ne(c.greenBright("All tokens valid \u2728"));return}if(!e.length)throw new g(w.VALIDATE_NO_PATH_SPECIFIED());for(const s of e)if(!F(s))throw new g(w.VALIDATE_PATH_NOT_FOUND(s));const t=await V(e.map(s=>s.endsWith(".json")?s:R(s,"**/*.json")));if(t.length===0)throw new g(w.VALIDATE_NO_TOKEN_FILES());const n=A()?(await ee()).config:{tokens:{source:[]},output:{css:".",separate:!1,modeAttribute:"data-mode",themeAttribute:"data-theme"},transforms:{fluid:{min:320,max:1200},colorFallbackStrategy:"native"}};await K({...n,tokens:{source:t.map(s=>$(process.cwd(),s))}}),ne(c.greenBright("All tokens valid \u2728"))}catch(t){q(t)}});process.on("SIGINT",()=>process.exit(0)),process.on("SIGTERM",()=>process.exit(0));async function Hn(){const e=new M().name("sugarcube").description("CLI for scaffolding sugarcube projects").version(Tt.version,"-v, --version","display the version number");e.addCommand(Kn).addCommand(Sn).addCommand(Yn).addCommand(mn).addCommand(hn),e.parse()}o(Hn,"main"),Hn();
|
package/package.json
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sugarcube-org/cli",
|
|
3
|
-
"version": "0.0.0-alpha.
|
|
3
|
+
"version": "0.0.0-alpha.20",
|
|
4
4
|
"publishConfig": {
|
|
5
|
-
"access": "
|
|
5
|
+
"access": "public",
|
|
6
|
+
"provenance": false
|
|
6
7
|
},
|
|
7
8
|
"description": "A CLI for scaffolding sugarcube applications",
|
|
8
|
-
"license": "
|
|
9
|
+
"license": "SEE LICENSE IN LICENSE.md",
|
|
9
10
|
"author": "Mark Tomlinson",
|
|
10
11
|
"repository": {
|
|
11
12
|
"type": "git",
|
|
@@ -28,35 +29,45 @@
|
|
|
28
29
|
"LICENSE.md"
|
|
29
30
|
],
|
|
30
31
|
"type": "module",
|
|
32
|
+
"main": "./dist/index.mjs",
|
|
33
|
+
"exports": {
|
|
34
|
+
".": "./dist/index.mjs"
|
|
35
|
+
},
|
|
31
36
|
"bin": {
|
|
32
37
|
"sugarcube": "./dist/index.mjs"
|
|
33
38
|
},
|
|
34
39
|
"dependencies": {
|
|
35
|
-
"@antfu/ni": "
|
|
36
|
-
"@clack/
|
|
37
|
-
"
|
|
38
|
-
"
|
|
39
|
-
"
|
|
40
|
-
"
|
|
41
|
-
"
|
|
42
|
-
"
|
|
43
|
-
"
|
|
44
|
-
"
|
|
45
|
-
"
|
|
46
|
-
"
|
|
47
|
-
"
|
|
40
|
+
"@antfu/ni": "23.3.0",
|
|
41
|
+
"@clack/core": "1.0.0-alpha.3",
|
|
42
|
+
"@clack/prompts": "1.0.0-alpha.3",
|
|
43
|
+
"@sugarcube-org/core": "0.0.1-alpha.9",
|
|
44
|
+
"@unocss/core": "66.5.2",
|
|
45
|
+
"commander": "12.1.0",
|
|
46
|
+
"execa": "9.5.2",
|
|
47
|
+
"fast-glob": "3.3.2",
|
|
48
|
+
"fast-wrap-ansi": "0.1.3",
|
|
49
|
+
"get-tsconfig": "4.7.2",
|
|
50
|
+
"is-unicode-supported": "2.1.0",
|
|
51
|
+
"log-update": "6.1.0",
|
|
52
|
+
"node-fetch": "3.3.0",
|
|
53
|
+
"pathe": "2.0.3",
|
|
54
|
+
"picocolors": "1.1.1",
|
|
55
|
+
"zod": "3.21.4"
|
|
48
56
|
},
|
|
49
57
|
"devDependencies": {
|
|
50
|
-
"
|
|
51
|
-
"
|
|
52
|
-
"
|
|
53
|
-
|
|
58
|
+
"cross-env": "7.0.3",
|
|
59
|
+
"pkgroll": "2.5.1",
|
|
60
|
+
"tsx": "4.19.2"
|
|
61
|
+
},
|
|
62
|
+
"engines": {
|
|
63
|
+
"node": ">=18.0.0"
|
|
54
64
|
},
|
|
55
65
|
"scripts": {
|
|
56
|
-
"build": "pkgroll --minify",
|
|
57
|
-
"dev": "cross-env REGISTRY_URL=http://localhost:
|
|
58
|
-
"test": "vitest",
|
|
66
|
+
"build": "tsc --noEmit && pkgroll --minify",
|
|
67
|
+
"dev": "cross-env REGISTRY_URL=http://localhost:4321/r tsx src/index.ts",
|
|
68
|
+
"test": "vitest run",
|
|
69
|
+
"test:watch": "vitest",
|
|
59
70
|
"type-check": "tsc --noEmit",
|
|
60
|
-
"start": "cross-env REGISTRY_URL=https://sugarcube
|
|
71
|
+
"start": "cross-env REGISTRY_URL=https://sugarcube.sh/r tsx src/index.ts"
|
|
61
72
|
}
|
|
62
73
|
}
|