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