@seed-design/cli 1.1.0 → 1.2.1

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/bin/index.mjs CHANGED
@@ -1,13 +1,15 @@
1
1
  #!/usr/bin/env node
2
- import*as C from"@clack/prompts";import{cosmiconfig as xe}from"cosmiconfig";import{execa as be}from"execa";import{z as _}from"zod";import he from"picocolors";var a=e=>he.cyan(e);import{detect as we}from"@antfu/ni";async function z(e){let t=await we({programmatic:!0,cwd:e});return t==="yarn@berry"?"yarn":t==="pnpm@6"?"pnpm":t==="bun"?"bun":t==="deno"?"deno":t??"npm"}var te="seed-design",Ie=xe(te,{searchPlaces:[`${te}.json`]}),re=_.object({$schema:_.string().optional(),rsc:_.coerce.boolean().default(!1),tsx:_.coerce.boolean().default(!0),path:_.string(),telemetry:_.coerce.boolean().optional().default(!0)}).strict();async function D(e){let t=await $e(e);return t?re.parse(t):null}async function $e(e){try{let t=await Ie.search(e);return re.parse(t.config)}catch{C.log.error("\uD504\uB85C\uC81D\uD2B8 \uB8E8\uD2B8 \uACBD\uB85C\uC5D0 `seed-design.json` \uD30C\uC77C\uC774 \uC5C6\uC5B4\uC694."),await C.confirm({message:"seed-design.json \uD30C\uC77C\uC744 \uC0DD\uC131\uD558\uC2DC\uACA0\uC5B4\uC694?"})||(C.outro(a("\uC791\uC5C5\uC774 \uCDE8\uC18C\uB410\uC5B4\uC694.")),process.exit(1));let i=await z(e);await be(i,["seed-design","init","--default"],{cwd:e}),C.log.message("seed-design.json \uD30C\uC77C\uC774 \uC0DD\uC131\uB410\uC5B4\uC694.")}}function L({selectedItemKeys:e,publicRegistries:t}){let i=[],c=new Set;function p(r,n){let l=i.find(o=>o.registryId===r);if(!l?.items.some(o=>o.id===n.id)){if(l?l.items.push(n):i.push({registryId:r,items:[n]}),n.dependencies?.length)for(let o of n.dependencies)c.add(o);if(n.innerDependencies?.length)for(let o of n.innerDependencies)for(let u of o.itemIds){let w=t.find(R=>R.id===o.registryId)?.items.find(R=>R.id===u);if(!w)throw new Error(`Cannot find dependency item: ${o.registryId}:${u}`);p(o.registryId,w)}}}for(let r of e){let[n,...l]=r.split(":"),o=l.join(":");if(!n||!o)throw new Error(`Invalid snippet format: "${r}"`);let u=t.find(w=>w.id===n)?.items.find(w=>w.id===o);if(!u)throw new Error(`Cannot find snippet: "${r}"`);p(n,u)}return{registryItemsToAdd:i,npmDependenciesToAdd:c}}import*as Q from"@clack/prompts";import{z as f}from"zod";var q=f.object({id:f.string(),description:f.string().optional(),deprecated:f.boolean().optional(),hideFromCLICatalog:f.boolean().optional(),dependencies:f.array(f.string()).optional(),innerDependencies:f.array(f.object({registryId:f.string(),itemIds:f.array(f.string())})).optional(),snippets:f.array(f.object({path:f.string(),content:f.string()}))}),W=f.object({id:f.string(),hideFromCLICatalog:f.boolean().optional(),items:f.array(q.omit({snippets:!0}).extend({snippets:f.array(f.object({path:f.string()}))}))}),se=f.array(f.object({id:f.string()}));async function K({baseUrl:e}){let t=await fetch(`${e}/__registry__/index.json`);if(!t.ok)throw new Error(`Failed to fetch registries: ${t.status} ${t.statusText}`);let i=await t.json(),{success:c,data:p,error:r}=se.safeParse(i);if(!c)throw new Error(`Failed to parse registries: ${r?.message}`);return p}async function N({baseUrl:e,registryId:t}){let i=await fetch(`${e}/__registry__/${t}/index.json`);if(!i.ok)throw new Error(`Failed to fetch ${t} registry: ${i.status} ${i.statusText}`);let c=await i.json(),{success:p,data:r,error:n}=W.safeParse(c);if(!p)throw new Error(`Failed to parse ${t} registry: ${n?.message}`);return r}async function Pe({baseUrl:e,registryId:t,registryItemId:i}){let c=await fetch(`${e}/__registry__/${t}/${i}.json`);if(!c.ok)throw new Error(`Failed to fetch ${i}: ${c.status} ${c.statusText}`);let p=await c.json(),{success:r,data:n,error:l}=q.safeParse(p);if(!r)throw new Error(`Failed to parse ${i}: ${l?.message}`);return n}async function ie({baseUrl:e,registryId:t,registryItemIds:i}){return await Promise.all(i.map(async c=>{try{return await Pe({baseUrl:e,registryId:t,registryItemId:c})}catch(p){let r=await fetch(`${e}/__registry__/${t}/index.json`);if(!r.ok)throw new Error(`${t} \uB808\uC9C0\uC2A4\uD2B8\uB9AC\uB97C \uAC00\uC838\uC624\uC9C0 \uBABB\uD588\uC5B4\uC694: ${r.status} ${r.statusText}`);let n=await r.json(),{success:l,data:o}=W.safeParse(n);throw l?(Q.log.error(`${c} \uC2A4\uB2C8\uD3AB\uC774 ${t} \uB808\uC9C0\uC2A4\uD2B8\uB9AC\uC5D0 \uC5C6\uC5B4\uC694.`),Q.log.info(`${t} \uB808\uC9C0\uC2A4\uD2B8\uB9AC\uC5D0 \uC874\uC7AC\uD558\uB294 \uC2A4\uB2C8\uD3AB:
3
- ${o.items.map(u=>u.id).join(`
4
- `)}`),p):new Error(`Failed to parse registry index for ${t}`)}}))}import{promises as Ce}from"fs";import{tmpdir as Ae}from"os";import ae from"path";import{transformFromAstSync as Se}from"@babel/core";import Re from"@babel/plugin-transform-typescript";import*as B from"recast";import{parse as Te}from"@babel/parser";var je={sourceType:"module",allowImportExportEverywhere:!0,allowReturnOutsideFunction:!0,startLine:1,tokens:!0,plugins:["asyncGenerators","bigInt","classPrivateMethods","classPrivateProperties","classProperties","classStaticBlock","decimal","decorators-legacy","doExpressions","dynamicImport","exportDefaultFrom","exportNamespaceFrom","functionBind","functionSent","importAssertions","importMeta","nullishCoalescingOperator","numericSeparator","objectRestSpread","optionalCatchBinding","optionalChaining",["pipelineOperator",{proposal:"minimal"}],["recordAndTuple",{syntaxType:"hash"}],"throwExpressions","topLevelAwait","v8intrinsic","typescript","jsx"]},oe=async({sourceFile:e,config:t})=>{let i=e.getFullText();if(t.tsx)return i;let c=B.parse(i,{parser:{parse:r=>Te(r,je)}}),p=Se(c,i,{cloneInputAst:!1,code:!1,ast:!0,plugins:[Re],configFile:!1});if(!p||!p.ast)throw new Error("Failed to transform JSX");return B.print(p.ast).code};import{SyntaxKind as Ee}from"ts-morph";var ne=async({sourceFile:e,config:t})=>{if(t.rsc)return e;let i=e.getFirstChildByKind(Ee.ExpressionStatement);if(!i)return e;let c=i.getExpression();if(!c)return e;let p=c.getText().trim();if(p!=='"use client"'&&p!=="'use client'")return e;let r=i.getText(),n=i.getFullText();if(r.trim()===n.trim())return e;let o=n.replace(r,"").replace(/^\s*\n/,"").replace(/\n\s*$/,"");return i.replaceWithText(o),e};import{Project as ve,ScriptKind as _e}from"ts-morph";var De=[ne],Oe=new ve({compilerOptions:{}});async function ke(e){let t=await Ce.mkdtemp(ae.join(Ae(),"seed-design-"));return ae.join(t,e)}async function ce(e){let t=await ke(e.filename),i=Oe.createSourceFile(t,e.raw,{scriptKind:_e.TSX});for(let c of De)c({sourceFile:i,...e});return await oe({sourceFile:i,...e})}import*as pe from"@clack/prompts";import Z from"fs-extra";import J from"path";async function H({registryItemsToAdd:e,rootPath:t,cwd:i,baseUrl:c,config:p}){let r=[];for(let{registryId:n,items:l}of e){let o=J.join(t,n);Z.ensureDirSync(o);let u=await ie({baseUrl:c,registryId:n,registryItemIds:l.map(w=>w.id)});for(let{id:w,snippets:R}of u){let E=await Promise.all(R.map(async x=>{let $=await ce({filename:x.path,config:p,raw:x.content}),I=J.join(o,x.path);return p.tsx||(I=I.replace(/\.tsx$/,".jsx"),I=I.replace(/\.ts$/,".js")),{filePath:I,content:$,relativePath:J.relative(i,I),name:`${n}:${w}`}}));await Promise.all(E.map(async({filePath:x,content:$})=>{await Z.ensureDir(J.dirname(x)),await Z.writeFile(x,$)}));let b=E.map(({name:x,relativePath:$})=>({name:x,path:$}));r.push(...b),pe.log.success(`${a(`${n}:${w}`)} \uAD00\uB828 \uC2A4\uB2C8\uD3AB \uB2E4\uC6B4\uB85C\uB4DC \uC644\uB8CC: ${a(b.map(x=>x.path).join(", "))}`)}}}import*as d from"@clack/prompts";import Ge from"path";import{z as k}from"zod";var V="https://seed-design.io";import*as le from"@clack/prompts";import{execa as Le}from"execa";import Fe from"findup-sync";import Me from"fs-extra";var Ue="package.json";function ze(){let e=Fe(Ue);if(!e)throw new Error("No package.json file found in the project.");return e}function G(){let e=ze();return Me.readJSONSync(e)}async function Y({cwd:e,deps:t,dev:i=!1}){let{start:c,stop:p}=le.spinner(),r=await z(e),l={...G().dependencies},o=new Set(t.filter(b=>!l[b])),u=new Set(t.filter(b=>l[b]));if(!o.size)return{installed:new Set,filtered:o};c("\uC758\uC874\uC131 \uC124\uCE58\uC911...");let E=[r==="npm"?"install":"add",i?"-D":null,...o].filter(Boolean);try{await Le(r,E,{cwd:e})}catch(b){console.error(`\uC758\uC874\uC131 \uC124\uCE58 \uC2E4\uD328: ${b}`),process.exit(1)}return p("\uC758\uC874\uC131 \uC124\uCE58\uAC00 \uC644\uB8CC\uB410\uC5B4\uC694."),{installed:o,filtered:u}}import{randomUUID as Ke}from"node:crypto";import*as me from"@clack/prompts";var Ne="seed_cli";async function Be(e){if(process.env.DISABLE_TELEMETRY==="true"||process.env.SEED_DISABLE_TELEMETRY==="true")return!1;try{if((await D(e))?.telemetry===!1)return!1}catch{}return!0}function Je(){return Ke()}var He=Je(),de=!1;async function Ve(e,{event:t,properties:i={}}){if(!await Be(e))return;let p=`${Ne}.${t}`;de||(me.log.info("\u{1F4CA} \uC0AC\uC6A9 \uB370\uC774\uD130 \uC218\uC9D1 \uC911 (\uBE44\uD65C\uC131\uD654: seed-design.json \uB610\uB294 DISABLE_TELEMETRY \uD658\uACBD \uBCC0\uC218)"),de=!0);try{let r="https://us.i.posthog.com/capture",n={"Content-Type":"application/json"},l={api_key:"phc_seod8HhifElOP1R92KmvsQybrtUmkOTgZBsq0mfCelR",event:p,distinct_id:He,properties:{...i,$process_person_profile:!1},timestamp:new Date().toISOString()},o=new AbortController,u=setTimeout(()=>o.abort(),5e3);try{await fetch(r,{method:"POST",headers:n,body:JSON.stringify(l),signal:o.signal})}finally{clearTimeout(u)}}catch{}}var O={track:Ve};var Ye=k.object({itemIds:k.array(k.string()).optional(),all:k.boolean(),cwd:k.string(),baseUrl:k.string().optional()}),fe=e=>{e.command("add [...item-ids]","add items").option("-a, --all","[Deprecated] Add all items",{default:!1}).option("-c, --cwd <cwd>","the working directory. defaults to the current directory.",{default:process.cwd()}).option("-u, --baseUrl <baseUrl>","the base url of the registry. defaults to the current directory.",{default:V}).example("seed-design add ui:action-button").example("seed-design add ui:alert-dialog").action(async(t,i)=>{let c=Date.now();d.intro("seed-design add");let{success:p,data:{all:r,...n},error:l}=Ye.safeParse({itemIds:t,...i});p||(d.log.error(`\uC798\uBABB\uB41C \uC635\uC158\uC774\uC5D0\uC694: ${l?.message}`),process.exit(1)),r&&(d.log.error("`--all` \uC635\uC158\uC740 \uB354 \uC774\uC0C1 \uC9C0\uC6D0\uB418\uC9C0 \uC54A\uC544\uC694. \uB300\uC2E0 `seed-design add-all` \uBA85\uB839\uC5B4\uB97C \uC0AC\uC6A9\uD574\uC8FC\uC138\uC694."),process.exit(1));let o=n.cwd,u=n.baseUrl,w=await D(o),R=Ge.resolve(o,w.path),{start:E,stop:b}=d.spinner();E("Registry\uB97C \uAC00\uC838\uC624\uACE0 \uC788\uC5B4\uC694...");let x=await Promise.all((await K({baseUrl:u})).map(async({id:s})=>N({baseUrl:u,registryId:s})));b("Registry\uB97C \uAC00\uC838\uC654\uC5B4\uC694.");let $=await(async()=>{if(n.itemIds.length>0)return n.itemIds;let s=await d.multiselect({message:"\uCD94\uAC00\uD560 \uD56D\uBAA9\uC744 \uC120\uD0DD\uD574\uC8FC\uC138\uC694 (\uC2A4\uD398\uC774\uC2A4 \uBC14\uB85C \uC5EC\uB7EC \uAC1C \uC120\uD0DD \uAC00\uB2A5)",options:x.filter(({hideFromCLICatalog:m})=>!m).flatMap(({id:m,items:T})=>T.filter(({hideFromCLICatalog:S})=>!S).sort((S,P)=>S.id.localeCompare(P.id)).map(({id:S,description:P,deprecated:j})=>({label:`${j?"(deprecated) ":""}${a(m)}:${S}`,value:`${m}:${S}`,hint:P,deprecated:j,registryItemCount:T.length}))).sort((m,T)=>m.deprecated!==T.deprecated?m.deprecated?1:-1:T.registryItemCount-m.registryItemCount)});return d.isCancel(s)&&(d.log.error("\uCDE8\uC18C\uB418\uC5C8\uC5B4\uC694."),process.exit(0)),s})();$?.length||(d.log.error("\uD56D\uBAA9\uC744 \uCC3E\uC744 \uC218 \uC5C6\uC5B4\uC694."),process.exit(0)),d.log.message(`\uC120\uD0DD\uB41C \uD56D\uBAA9: ${a($.join(", "))}`);let I=[];for(let s of $){let[m,...T]=s.split(":"),S=T.join(":");(!m||!S)&&(d.log.error(`${a(s)}: \uD56D\uBAA9 \uC774\uB984\uC774 \uC798\uBABB\uB418\uC5C8\uC5B4\uC694. ${a("ui:action-button")}\uACFC \uAC19\uC740 \uD615\uC2DD\uC73C\uB85C \uC785\uB825\uD574\uBCF4\uC138\uC694.`),process.exit(1));let P=x.find(j=>j.id===m)?.items.find(j=>j.id===S);if(P||(d.log.error(`${a(s)}: \uD56D\uBAA9\uC744 \uCC3E\uC744 \uC218 \uC5C6\uC5B4\uC694.`),process.exit(1)),P.deprecated){let j=await d.confirm({message:`${a(P.id)}: deprecated \uB418\uC5C8\uC5B4\uC694. \uCD94\uAC00\uD560\uAE4C\uC694?`,initialValue:!1});if(j===!1||d.isCancel(j)){d.log.info(`${a(P.id)}: \uCD94\uAC00\uD558\uC9C0 \uC54A\uC744\uAC8C\uC694.`);continue}}I.push(s)}let{registryItemsToAdd:v,npmDependenciesToAdd:M}=L({selectedItemKeys:I,publicRegistries:x});d.log.info(`\uCD94\uAC00\uD560 \uD56D\uBAA9: ${a(v.map(s=>s.items.map(m=>`${s.registryId}:${m.id}`).join(", ")).join(", ")||"\uC5C6\uC74C")}
2
+ import*as k from"@clack/prompts";import{cosmiconfig as be}from"cosmiconfig";import{execa as xe}from"execa";import{z as M}from"zod";import he from"picocolors";var i=e=>he.cyan(e);import{detect as we}from"@antfu/ni";async function B(e){let t=await we({programmatic:!0,cwd:e});return t==="yarn@berry"?"yarn":t==="pnpm@6"?"pnpm":t==="bun"?"bun":t==="deno"?"deno":t??"npm"}var re="seed-design",$e=be(re,{searchPlaces:[`${re}.json`]}),se=M.object({$schema:M.string().optional(),rsc:M.coerce.boolean().default(!1),tsx:M.coerce.boolean().default(!0),path:M.string(),telemetry:M.coerce.boolean().optional().default(!0)}).strict();async function U(e){let t=await Ie(e);return t?se.parse(t):null}async function Ie(e){try{let t=await $e.search(e);return se.parse(t.config)}catch{k.log.error("\uD504\uB85C\uC81D\uD2B8 \uB8E8\uD2B8 \uACBD\uB85C\uC5D0 `seed-design.json` \uD30C\uC77C\uC774 \uC5C6\uC5B4\uC694."),await k.confirm({message:"seed-design.json \uD30C\uC77C\uC744 \uC0DD\uC131\uD558\uC2DC\uACA0\uC5B4\uC694?"})||(k.outro(i("\uC791\uC5C5\uC774 \uCDE8\uC18C\uB410\uC5B4\uC694.")),process.exit(1));let o=await B(e);await xe(o,["seed-design","init","--default"],{cwd:e}),k.log.message("seed-design.json \uD30C\uC77C\uC774 \uC0DD\uC131\uB410\uC5B4\uC694.")}}function J({selectedItemKeys:e,publicRegistries:t}){let o=[],c=new Set;function l(r,a){let p=o.find(n=>n.registryId===r);if(!p?.items.some(n=>n.id===a.id)){if(p?p.items.push(a):o.push({registryId:r,items:[a]}),a.dependencies?.length)for(let n of a.dependencies)c.add(n);if(a.innerDependencies?.length)for(let n of a.innerDependencies)for(let u of n.itemIds){let $=t.find(T=>T.id===n.registryId)?.items.find(T=>T.id===u);if(!$)throw new Error(`Cannot find dependency item: ${n.registryId}:${u}`);l(n.registryId,$)}}}for(let r of e){let[a,...p]=r.split(":"),n=p.join(":");if(!a||!n)throw new Error(`Invalid snippet format: "${r}"`);let u=t.find($=>$.id===a)?.items.find($=>$.id===n);if(!u)throw new Error(`Cannot find snippet: "${r}"`);l(a,u)}return{registryItemsToAdd:o,npmDependenciesToAdd:c}}import*as ee from"@clack/prompts";import{z as f}from"zod";var Q=f.object({id:f.string(),description:f.string().optional(),deprecated:f.boolean().optional(),hideFromCLICatalog:f.boolean().optional(),dependencies:f.array(f.string()).optional(),innerDependencies:f.array(f.object({registryId:f.string(),itemIds:f.array(f.string())})).optional(),snippets:f.array(f.object({path:f.string(),content:f.string()}))}),Z=f.object({id:f.string(),hideFromCLICatalog:f.boolean().optional(),items:f.array(Q.omit({snippets:!0}).extend({snippets:f.array(f.object({path:f.string()}))}))}),oe=f.array(f.object({id:f.string()}));async function H({baseUrl:e}){let t=await fetch(`${e}/__registry__/index.json`);if(!t.ok)throw new Error(`Failed to fetch registries: ${t.status} ${t.statusText}`);let o=await t.json(),{success:c,data:l,error:r}=oe.safeParse(o);if(!c)throw new Error(`Failed to parse registries: ${r?.message}`);return l}async function V({baseUrl:e,registryId:t}){let o=await fetch(`${e}/__registry__/${t}/index.json`);if(!o.ok)throw new Error(`Failed to fetch ${t} registry: ${o.status} ${o.statusText}`);let c=await o.json(),{success:l,data:r,error:a}=Z.safeParse(c);if(!l)throw new Error(`Failed to parse ${t} registry: ${a?.message}`);return r}async function Pe({baseUrl:e,registryId:t,registryItemId:o}){let c=await fetch(`${e}/__registry__/${t}/${o}.json`);if(!c.ok)throw new Error(`Failed to fetch ${o}: ${c.status} ${c.statusText}`);let l=await c.json(),{success:r,data:a,error:p}=Q.safeParse(l);if(!r)throw new Error(`Failed to parse ${o}: ${p?.message}`);return a}async function ie({baseUrl:e,registryId:t,registryItemIds:o}){return await Promise.all(o.map(async c=>{try{return await Pe({baseUrl:e,registryId:t,registryItemId:c})}catch(l){let r=await fetch(`${e}/__registry__/${t}/index.json`);if(!r.ok)throw new Error(`${t} \uB808\uC9C0\uC2A4\uD2B8\uB9AC\uB97C \uAC00\uC838\uC624\uC9C0 \uBABB\uD588\uC5B4\uC694: ${r.status} ${r.statusText}`);let a=await r.json(),{success:p,data:n}=Z.safeParse(a);throw p?(ee.log.error(`${c} \uC2A4\uB2C8\uD3AB\uC774 ${t} \uB808\uC9C0\uC2A4\uD2B8\uB9AC\uC5D0 \uC5C6\uC5B4\uC694.`),ee.log.info(`${t} \uB808\uC9C0\uC2A4\uD2B8\uB9AC\uC5D0 \uC874\uC7AC\uD558\uB294 \uC2A4\uB2C8\uD3AB:
3
+ ${n.items.map(u=>u.id).join(`
4
+ `)}`),l):new Error(`Failed to parse registry index for ${t}`)}}))}import{promises as Ce}from"fs";import{tmpdir as Ae}from"os";import ce from"path";import{transformFromAstSync as Se}from"@babel/core";import Re from"@babel/plugin-transform-typescript";import*as G from"recast";import{parse as Te}from"@babel/parser";var ve={sourceType:"module",allowImportExportEverywhere:!0,allowReturnOutsideFunction:!0,startLine:1,tokens:!0,plugins:["asyncGenerators","bigInt","classPrivateMethods","classPrivateProperties","classProperties","classStaticBlock","decimal","decorators-legacy","doExpressions","dynamicImport","exportDefaultFrom","exportNamespaceFrom","functionBind","functionSent","importAssertions","importMeta","nullishCoalescingOperator","numericSeparator","objectRestSpread","optionalCatchBinding","optionalChaining",["pipelineOperator",{proposal:"minimal"}],["recordAndTuple",{syntaxType:"hash"}],"throwExpressions","topLevelAwait","v8intrinsic","typescript","jsx"]},ne=async({sourceFile:e,config:t})=>{let o=e.getFullText();if(t.tsx)return o;let c=G.parse(o,{parser:{parse:r=>Te(r,ve)}}),l=Se(c,o,{cloneInputAst:!1,code:!1,ast:!0,plugins:[Re],configFile:!1});if(!l||!l.ast)throw new Error("Failed to transform JSX");return G.print(l.ast).code};import{SyntaxKind as je}from"ts-morph";var ae=async({sourceFile:e,config:t})=>{if(t.rsc)return e;let o=e.getFirstChildByKind(je.ExpressionStatement);if(!o)return e;let c=o.getExpression();if(!c)return e;let l=c.getText().trim();if(l!=='"use client"'&&l!=="'use client'")return e;let r=o.getText(),a=o.getFullText();if(r.trim()===a.trim())return e;let n=a.replace(r,"").replace(/^\s*\n/,"").replace(/\n\s*$/,"");return o.replaceWithText(n),e};import{Project as Ee,ScriptKind as De}from"ts-morph";var _e=[ae],Oe=new Ee({compilerOptions:{}});async function ke(e){let t=await Ce.mkdtemp(ce.join(Ae(),"seed-design-"));return ce.join(t,e)}async function pe(e){let t=await ke(e.filename),o=Oe.createSourceFile(t,e.raw,{scriptKind:De.TSX});for(let c of _e)c({sourceFile:o,...e});return await ne({sourceFile:o,...e})}import*as A from"@clack/prompts";import L from"fs-extra";import E from"path";import{createPatch as Fe}from"diff";import ze from"@npmcli/disparity-colors";async function Y({registryItemsToAdd:e,rootPath:t,cwd:o,baseUrl:c,config:l,onDiff:r}){let a=[];for(let{registryId:p,items:n}of e){let u=E.join(t,p);L.ensureDirSync(u);let $=await ie({baseUrl:c,registryId:p,registryItemIds:n.map(T=>T.id)});for(let{id:T,snippets:_}of $){let P=await Promise.all(_.map(async x=>{let y=await pe({filename:x.path,config:l,raw:x.content}),b=E.join(u,x.path);return l.tsx||(b=b.replace(/\.tsx$/,".jsx"),b=b.replace(/\.ts$/,".js")),{filePath:b,content:y,relativePath:E.relative(o,b),name:`${p}:${T}`}})),j=[];for(let x of P){let{filePath:y,content:b,relativePath:C}=x;if(await L.ensureDir(E.dirname(y)),L.existsSync(y)){let O=await L.readFile(y,"utf-8");if(O===b){A.log.info(`${i(C)}: \uC774\uBBF8 \uCD5C\uC2E0 \uC0C1\uD0DC\uC608\uC694.`);continue}let z=E.basename(y),h=E.extname(y),s=E.basename(y,h),m=Date.now(),v=`legacy-${s}-${m}${h}`,S=await(async()=>{if(r)return r;let I=Fe(C,O,b),R=ze(I);return A.log.message(`
5
+ ${i(C)}: \uD604\uC7AC \uD30C\uC77C\uACFC \uBC1B\uC73C\uB824\uB294 \uD30C\uC77C\uC758 \uB0B4\uC6A9\uC774 \uB2EC\uB77C\uC694.
6
+ `),A.log.message(R),A.select({message:"\uD604\uC7AC \uD30C\uC77C\uC5D0 \uC2A4\uD0C0\uC77C \uBCC0\uACBD, \uB85C\uAE45 \uB4F1 \uCEE4\uC2A4\uD130\uB9C8\uC774\uC9D5\uC774 \uC801\uC6A9\uB418\uC5B4 \uC788\uB294 \uACBD\uC6B0 \uC2E0\uADDC \uD30C\uC77C\uC5D0 \uB3D9\uC77C\uD55C \uCEE4\uC2A4\uD130\uB9C8\uC774\uC9D5\uC744 \uC801\uC6A9\uD558\uB294 \uAC83\uC744 \uAC80\uD1A0\uD574\uBCF4\uC138\uC694.",options:[{value:"overwrite",label:`${z} \uB36E\uC5B4\uC4F0\uAE30`},{value:"backup",label:`\uAE30\uC874 \uD30C\uC77C \uB0B4\uC6A9\uC744 ${v}\uC73C\uB85C \uC62E\uAE30\uACE0 ${z} \uBC1B\uAE30`},{value:"skip",label:"\uC0C8 \uD30C\uC77C \uBC1B\uC9C0 \uC54A\uACE0 \uADF8\uB300\uB85C \uB450\uAE30"}]})})();if(A.isCancel(S)||S==="skip"){A.log.info(`${i(C)}: \uD30C\uC77C\uC744 \uBC1B\uC9C0 \uC54A\uACE0 \uAC74\uB108\uB6F0\uC5C8\uC5B4\uC694.`);continue}if(S==="backup"){let I=E.dirname(y),R=E.join(I,v);await L.rename(y,R),A.log.info(`${i(C)}: \uAE30\uC874 \uD30C\uC77C\uC744 ${i(E.relative(o,R))}\uB85C \uC62E\uACBC\uC5B4\uC694.`)}}await L.writeFile(y,b),j.push(x)}if(j.length>0){let x=j.map(({name:y,relativePath:b})=>({name:y,path:b}));a.push(...x),A.log.success(`${i(`${p}:${T}`)} \uAD00\uB828 \uC2A4\uB2C8\uD3AB \uB2E4\uC6B4\uB85C\uB4DC \uC644\uB8CC: ${i(x.map(y=>y.path).join(", "))}`)}}}}import*as d from"@clack/prompts";import Xe from"path";import{z as F}from"zod";var X="https://seed-design.io";import*as le from"@clack/prompts";import{execa as Ne}from"execa";import Me from"findup-sync";import Ue from"fs-extra";var Le="package.json";function Ke(){let e=Me(Le);if(!e)throw new Error("No package.json file found in the project.");return e}function q(){let e=Ke();return Ue.readJSONSync(e)}async function W({cwd:e,deps:t,dev:o=!1}){let{start:c,stop:l}=le.spinner(),r=await B(e),p={...q().dependencies},n=new Set(t.filter(P=>!p[P])),u=new Set(t.filter(P=>p[P]));if(!n.size)return{installed:new Set,filtered:n};c("\uC758\uC874\uC131 \uC124\uCE58\uC911...");let _=[r==="npm"?"install":"add",o?"-D":null,...n].filter(Boolean);try{await Ne(r,_,{cwd:e})}catch(P){console.error(`\uC758\uC874\uC131 \uC124\uCE58 \uC2E4\uD328: ${P}`),process.exit(1)}return l("\uC758\uC874\uC131 \uC124\uCE58\uAC00 \uC644\uB8CC\uB410\uC5B4\uC694."),{installed:n,filtered:u}}import{randomUUID as Be}from"node:crypto";import*as de from"@clack/prompts";var Je="seed_cli";async function He(e){if(process.env.DISABLE_TELEMETRY==="true"||process.env.SEED_DISABLE_TELEMETRY==="true")return!1;try{if((await U(e))?.telemetry===!1)return!1}catch{}return!0}function Ve(){return Be()}var Ge=Ve(),me=!1;async function Ye(e,{event:t,properties:o={}}){if(!await He(e))return;let l=`${Je}.${t}`;me||(de.log.info("\u{1F4CA} \uC0AC\uC6A9 \uB370\uC774\uD130 \uC218\uC9D1 \uC911 (\uBE44\uD65C\uC131\uD654: seed-design.json \uB610\uB294 DISABLE_TELEMETRY \uD658\uACBD \uBCC0\uC218)"),me=!0);try{let r="https://us.i.posthog.com/capture",a={"Content-Type":"application/json"},p={api_key:"phc_seod8HhifElOP1R92KmvsQybrtUmkOTgZBsq0mfCelR",event:l,distinct_id:Ge,properties:{...o,$process_person_profile:!1},timestamp:new Date().toISOString()},n=new AbortController,u=setTimeout(()=>n.abort(),5e3);try{await fetch(r,{method:"POST",headers:a,body:JSON.stringify(p),signal:n.signal})}finally{clearTimeout(u)}}catch{}}var K={track:Ye};var qe=F.object({itemIds:F.array(F.string()).optional(),all:F.boolean(),cwd:F.string(),baseUrl:F.string().optional(),onDiff:F.enum(["overwrite","backup"]).optional()}),fe=e=>{e.command("add [...item-ids]","add items").option("-a, --all","[Deprecated] Add all items",{default:!1}).option("-c, --cwd <cwd>","the working directory. defaults to the current directory.",{default:process.cwd()}).option("-u, --baseUrl <baseUrl>","the base url of the registry. defaults to the current directory.",{default:X}).option("--on-diff <mode>","Action when file differs: overwrite or backup").example("seed-design add ui:action-button").example("seed-design add ui:alert-dialog").action(async(t,o)=>{let c=Date.now();d.intro("seed-design add");let{success:l,data:{all:r,...a},error:p}=qe.safeParse({itemIds:t,...o});l||(d.log.error(`\uC798\uBABB\uB41C \uC635\uC158\uC774\uC5D0\uC694: ${p?.message}`),process.exit(1)),r&&(d.log.error("`--all` \uC635\uC158\uC740 \uB354 \uC774\uC0C1 \uC9C0\uC6D0\uB418\uC9C0 \uC54A\uC544\uC694. \uB300\uC2E0 `seed-design add-all` \uBA85\uB839\uC5B4\uB97C \uC0AC\uC6A9\uD574\uC8FC\uC138\uC694."),process.exit(1));let n=a.cwd,u=a.baseUrl,$=await U(n),T=Xe.resolve(n,$.path),{start:_,stop:P}=d.spinner();_("Registry\uB97C \uAC00\uC838\uC624\uACE0 \uC788\uC5B4\uC694...");let j=await Promise.all((await H({baseUrl:u})).map(async({id:s})=>V({baseUrl:u,registryId:s})));P("Registry\uB97C \uAC00\uC838\uC654\uC5B4\uC694.");let x=await(async()=>{if(a.itemIds.length>0)return a.itemIds;let s=await d.multiselect({message:"\uCD94\uAC00\uD560 \uD56D\uBAA9\uC744 \uC120\uD0DD\uD574\uC8FC\uC138\uC694 (\uC2A4\uD398\uC774\uC2A4 \uBC14\uB85C \uC5EC\uB7EC \uAC1C \uC120\uD0DD \uAC00\uB2A5)",options:j.filter(({hideFromCLICatalog:m})=>!m).flatMap(({id:m,items:v})=>v.filter(({hideFromCLICatalog:S})=>!S).sort((S,I)=>S.id.localeCompare(I.id)).map(({id:S,description:I,deprecated:R})=>({label:`${R?"(deprecated) ":""}${i(m)}:${S}`,value:`${m}:${S}`,hint:I,deprecated:R,registryItemCount:v.length}))).sort((m,v)=>m.deprecated!==v.deprecated?m.deprecated?1:-1:v.registryItemCount-m.registryItemCount)});return d.isCancel(s)&&(d.log.error("\uCDE8\uC18C\uB418\uC5C8\uC5B4\uC694."),process.exit(0)),s})();x?.length||(d.log.error("\uD56D\uBAA9\uC744 \uCC3E\uC744 \uC218 \uC5C6\uC5B4\uC694."),process.exit(0)),d.log.message(`\uC120\uD0DD\uB41C \uD56D\uBAA9: ${i(x.join(", "))}`);let y=[];for(let s of x){let[m,...v]=s.split(":"),S=v.join(":");(!m||!S)&&(d.log.error(`${i(s)}: \uD56D\uBAA9 \uC774\uB984\uC774 \uC798\uBABB\uB418\uC5C8\uC5B4\uC694. ${i("ui:action-button")}\uACFC \uAC19\uC740 \uD615\uC2DD\uC73C\uB85C \uC785\uB825\uD574\uBCF4\uC138\uC694.`),process.exit(1));let I=j.find(R=>R.id===m)?.items.find(R=>R.id===S);if(I||(d.log.error(`${i(s)}: \uD56D\uBAA9\uC744 \uCC3E\uC744 \uC218 \uC5C6\uC5B4\uC694.`),process.exit(1)),I.deprecated){let R=await d.confirm({message:`${i(I.id)}: deprecated \uB418\uC5C8\uC5B4\uC694. \uCD94\uAC00\uD560\uAE4C\uC694?`,initialValue:!1});if(R===!1||d.isCancel(R)){d.log.info(`${i(I.id)}: \uCD94\uAC00\uD558\uC9C0 \uC54A\uC744\uAC8C\uC694.`);continue}}y.push(s)}let{registryItemsToAdd:b,npmDependenciesToAdd:C}=J({selectedItemKeys:y,publicRegistries:j});d.log.info(`\uCD94\uAC00\uD560 \uD56D\uBAA9: ${i(b.map(s=>s.items.map(m=>`${s.registryId}:${m.id}`).join(", ")).join(", ")||"\uC5C6\uC74C")}
5
7
 
6
- \uC124\uCE58\uD560 \uC758\uC874\uC131: ${a(Array.from(M).join(", ")||"\uC5C6\uC74C")}`),await H({registryItemsToAdd:v,rootPath:R,cwd:o,baseUrl:u,config:w});try{let{installed:s,filtered:m}=await Y({cwd:o,deps:Array.from(M)});s.size===0&&d.log.message("\uBAA8\uB4E0 \uC758\uC874\uC131\uC774 \uC774\uBBF8 \uC124\uCE58\uB418\uC5B4 \uC788\uC5B4\uC694."),s.size&&(d.log.message(`\uC758\uC874\uC131 \uC124\uCE58 \uC644\uB8CC: ${a(Array.from(s).join(", "))}`),m.size&&d.log.message(`\uC124\uCE58\uD558\uC9C0 \uC54A\uC740 \uC758\uC874\uC131 (\uC774\uBBF8 \uC124\uCE58\uB428): ${a(Array.from(m).join(", "))}`)),d.outro("\uC644\uB8CC\uD588\uC5B4\uC694.")}catch(s){d.log.error(`\uCD94\uAC00\uC5D0 \uC2E4\uD328\uD588\uC5B4\uC694. ${s}`),d.outro(a("\uC791\uC5C5\uC774 \uCDE8\uC18C\uB410\uC5B4\uC694.")),process.exit(1)}let U=Date.now()-c,X=new Set(v.map(s=>s.registryId)),h=$.some(s=>{let[m,...T]=s.split(":"),S=T.join(":");return x.find(P=>P.id===m)?.items.find(P=>P.id===S)?.deprecated});await O.track(n.cwd,{event:"add",properties:{items_count:I.length,registries:Array.from(X),has_deprecated:h,dependencies_count:M.size,duration_ms:U}})})};import*as g from"@clack/prompts";import Xe from"path";import{z as A}from"zod";var qe=A.object({registryIds:A.array(A.string()).optional(),all:A.boolean(),includeDeprecated:A.boolean().optional(),cwd:A.string(),baseUrl:A.string().optional()}),ge=e=>{e.command("add-all [...registry-ids]","add all items from registries").option("-a, --all","Add all items from all registries",{default:!1}).option("--include-deprecated","Include deprecated items when used with `--all`",{default:!1}).option("-c, --cwd <cwd>","the working directory. defaults to the current directory.",{default:process.cwd()}).option("-u, --baseUrl <baseUrl>","the base url of the registry. defaults to the current directory.",{default:V}).example("seed-design add-all ui --include-deprecated").example("seed-design add-all ui lib breeze").action(async(t,i)=>{let c=Date.now();g.intro("seed-design add-all");let{success:p,data:r,error:n}=qe.safeParse({registryIds:t,...i});p||(g.log.error(`\uC798\uBABB\uB41C \uC635\uC158\uC774\uC5D0\uC694: ${n?.message}`),process.exit(1));let l=r.cwd,o=r.baseUrl,u=await D(l),w=Xe.resolve(l,u.path),{start:R,stop:E}=g.spinner();R("Registry\uB97C \uAC00\uC838\uC624\uACE0 \uC788\uC5B4\uC694...");let b=await Promise.all((await K({baseUrl:o})).map(async({id:h})=>N({baseUrl:o,registryId:h})));E("Registry\uB97C \uAC00\uC838\uC654\uC5B4\uC694.");let x=await(async()=>{if(r.all){let s=b.map(m=>m.id);return g.log.message(`\uBAA8\uB4E0 \uB808\uC9C0\uC2A4\uD2B8\uB9AC\uC758 \uBAA8\uB4E0 \uD56D\uBAA9\uC744 \uCD94\uAC00\uD569\uB2C8\uB2E4: ${a(s.join(", "))}`),s}if(r.registryIds?.length){let s=b.map(m=>m.id);for(let m of r.registryIds)s.includes(m)||(g.log.error(`\uB808\uC9C0\uC2A4\uD2B8\uB9AC '${m}'\uB97C \uCC3E\uC744 \uC218 \uC5C6\uC5B4\uC694.`),g.log.info(`\uC0AC\uC6A9 \uAC00\uB2A5\uD55C \uB808\uC9C0\uC2A4\uD2B8\uB9AC: ${s.join(", ")}`),process.exit(1));return g.log.message(`\uC120\uD0DD\uB41C \uB808\uC9C0\uC2A4\uD2B8\uB9AC\uC758 \uBAA8\uB4E0 \uD56D\uBAA9\uC744 \uCD94\uAC00\uD569\uB2C8\uB2E4: ${a(r.registryIds.join(", "))}`),r.registryIds}let h=await g.multiselect({message:"\uCD94\uAC00\uD560 \uB808\uC9C0\uC2A4\uD2B8\uB9AC\uB97C \uC120\uD0DD\uD574\uC8FC\uC138\uC694 (\uC2A4\uD398\uC774\uC2A4 \uBC14\uB85C \uC5EC\uB7EC \uAC1C \uC120\uD0DD \uAC00\uB2A5)",options:b.filter(({hideFromCLICatalog:s})=>!s).sort((s,m)=>m.items.length-s.items.length).map(s=>({label:s.id,value:s.id,hint:`${s.items.length}\uAC1C \uD56D\uBAA9 (${s.items[0].id} \uB4F1)`}))});return g.isCancel(h)&&(g.log.error("\uCDE8\uC18C\uB418\uC5C8\uC5B4\uC694."),process.exit(0)),g.log.message(`\uC120\uD0DD\uB41C \uB808\uC9C0\uC2A4\uD2B8\uB9AC\uC758 \uD56D\uBAA9\uC744 \uCD94\uAC00\uD569\uB2C8\uB2E4: ${a(h.join(", "))}`),h})(),$=b.filter(h=>x.includes(h.id)),I=$.flatMap(h=>h.items.filter(s=>s.deprecated?r.includeDeprecated:!0).map(s=>`${h.id}:${s.id}`)),v=$.flatMap(h=>h.items.filter(s=>s.deprecated).map(()=>1)).length;!r.includeDeprecated&&v>0&&g.log.info(`${v}\uAC1C\uC758 deprecated \uD56D\uBAA9\uC740 \uC81C\uC678\uB418\uC5C8\uC5B4\uC694. --include-deprecated \uC635\uC158\uC744 \uC0AC\uC6A9\uD558\uBA74 \uCD94\uAC00\uD560 \uC218 \uC788\uC5B4\uC694.`),I.length||(g.log.error("\uCD94\uAC00\uD560 \uD56D\uBAA9\uC774 \uC5C6\uC5B4\uC694."),process.exit(0)),g.log.message(`\uCD1D ${a(I.length.toString())}\uAC1C\uC758 \uD56D\uBAA9\uC744 \uCD94\uAC00\uD569\uB2C8\uB2E4.`);let{registryItemsToAdd:M,npmDependenciesToAdd:U}=L({selectedItemKeys:I,publicRegistries:b});await H({registryItemsToAdd:M,rootPath:w,cwd:l,baseUrl:o,config:u});try{let{installed:h,filtered:s}=await Y({cwd:l,deps:Array.from(U)});h.size===0&&g.log.message("\uBAA8\uB4E0 \uC758\uC874\uC131\uC774 \uC774\uBBF8 \uC124\uCE58\uB418\uC5B4 \uC788\uC5B4\uC694."),h.size&&(g.log.message(`\uC758\uC874\uC131 \uC124\uCE58 \uC644\uB8CC: ${a(Array.from(h).join(", "))}`),s.size&&g.log.message(`\uC124\uCE58\uD558\uC9C0 \uC54A\uC740 \uC758\uC874\uC131 (\uC774\uBBF8 \uC124\uCE58\uB428): ${a(Array.from(s).join(", "))}`)),g.outro("\uC644\uB8CC\uD588\uC5B4\uC694.")}catch(h){g.log.error(`\uCD94\uAC00\uC5D0 \uC2E4\uD328\uD588\uC5B4\uC694. ${h}`),g.outro(a("\uC791\uC5C5\uC774 \uCDE8\uC18C\uB410\uC5B4\uC694.")),process.exit(1)}let X=Date.now()-c;await O.track(r.cwd,{event:"add-all",properties:{registries:x,items_count:I.length,include_deprecated:r.includeDeprecated||!1,dependencies_count:U.size,duration_ms:X}})})};import*as y from"@clack/prompts";import We from"fs-extra";import ue from"path";import{z as ee}from"zod";import Qe from"dedent";var Ze=ee.object({cwd:ee.string(),yes:ee.boolean().optional()}),ye=e=>{e.command("init","seed-design.json \uD30C\uC77C \uC0DD\uC131").option("-c, --cwd <cwd>","\uC791\uC5C5 \uB514\uB809\uD1A0\uB9AC. \uAE30\uBCF8\uAC12\uC740 \uD604\uC7AC \uB514\uB809\uD1A0\uB9AC.",{default:process.cwd()}).option("-y, --yes","\uBAA8\uB4E0 \uC9C8\uBB38\uC5D0 \uB300\uD574 \uAE30\uBCF8\uAC12\uC73C\uB85C \uB2F5\uBCC0\uD569\uB2C8\uB2E4.").action(async t=>{let i=Date.now();y.intro("seed-design.json \uD30C\uC77C \uC0DD\uC131");let c=Ze.parse(t),p=c.yes,r={rsc:!1,tsx:!0,path:"./seed-design",telemetry:!0};p||(r={...await y.group({tsx:()=>y.confirm({message:`${a("TypeScript")}\uB97C \uC0AC\uC6A9\uC911\uC774\uC2E0\uAC00\uC694?`,initialValue:!0}),rsc:()=>y.confirm({message:`${a("React Server Components")}\uB97C \uC0AC\uC6A9\uC911\uC774\uC2E0\uAC00\uC694?`,initialValue:!1}),path:()=>y.text({message:`${a("seed-design \uD3F4\uB354")} \uACBD\uB85C\uB97C \uC785\uB825\uD574\uC8FC\uC138\uC694. (\uAE30\uBCF8\uAC12\uC740 \uD504\uB85C\uC81D\uD2B8 \uB8E8\uD2B8\uC5D0 \uC0DD\uC131\uB429\uB2C8\uB2E4.)`,initialValue:"./seed-design",defaultValue:"./seed-design",placeholder:"./seed-design"}),telemetry:()=>y.confirm({message:`\uAC1C\uC120\uC744 \uC704\uD574 ${a("\uC775\uBA85 \uC0AC\uC6A9 \uB370\uC774\uD130")}\uB97C \uC218\uC9D1\uD560\uAE4C\uC694?`,initialValue:!0})},{onCancel:()=>{y.cancel("\uC791\uC5C5\uC774 \uCDE8\uC18C\uB410\uC5B4\uC694."),process.exit(0)}})});try{let{start:l,stop:o}=y.spinner();l("seed-design.json \uD30C\uC77C \uC0DD\uC131\uC911...");let u=ue.resolve(c.cwd,"seed-design.json");await We.writeFile(u,`${JSON.stringify(r,null,2)}
7
- `,"utf-8");let w=ue.relative(process.cwd(),u);o(`seed-design.json \uD30C\uC77C\uC774 ${a(w)}\uC5D0 \uC0DD\uC131\uB410\uC5B4\uC694.`),y.log.info(a("seed-design add {component} \uBA85\uB839\uC5B4\uB85C \uCEF4\uD3EC\uB10C\uD2B8\uB97C \uCD94\uAC00\uD574\uBCF4\uC138\uC694!")),y.log.info(a("seed-design add \uBA85\uB839\uC5B4\uB85C \uCD94\uAC00\uD560 \uC218 \uC788\uB294 \uBAA8\uB4E0 \uCEF4\uD3EC\uB10C\uD2B8\uB97C \uD655\uC778\uD574\uBCF4\uC138\uC694.")),y.note(Qe(`SEED Design CLI\uB294 \uAC1C\uC120\uC744 \uC704\uD574 \uC775\uBA85 \uC0AC\uC6A9 \uB370\uC774\uD130\uB97C \uC218\uC9D1\uD574\uC694.
8
+ \uC124\uCE58\uD560 \uC758\uC874\uC131: ${i(Array.from(C).join(", ")||"\uC5C6\uC74C")}`),await Y({registryItemsToAdd:b,rootPath:T,cwd:n,baseUrl:u,config:$,onDiff:a.onDiff});try{let{installed:s,filtered:m}=await W({cwd:n,deps:Array.from(C)});s.size===0&&d.log.message("\uBAA8\uB4E0 \uC758\uC874\uC131\uC774 \uC774\uBBF8 \uC124\uCE58\uB418\uC5B4 \uC788\uC5B4\uC694."),s.size&&(d.log.message(`\uC758\uC874\uC131 \uC124\uCE58 \uC644\uB8CC: ${i(Array.from(s).join(", "))}`),m.size&&d.log.message(`\uC124\uCE58\uD558\uC9C0 \uC54A\uC740 \uC758\uC874\uC131 (\uC774\uBBF8 \uC124\uCE58\uB428): ${i(Array.from(m).join(", "))}`)),d.outro("\uC644\uB8CC\uD588\uC5B4\uC694.")}catch(s){d.log.error(`\uCD94\uAC00\uC5D0 \uC2E4\uD328\uD588\uC5B4\uC694. ${s}`),d.outro(i("\uC791\uC5C5\uC774 \uCDE8\uC18C\uB410\uC5B4\uC694.")),process.exit(1)}let O=Date.now()-c,z=new Set(b.map(s=>s.registryId)),h=x.some(s=>{let[m,...v]=s.split(":"),S=v.join(":");return j.find(I=>I.id===m)?.items.find(I=>I.id===S)?.deprecated});await K.track(a.cwd,{event:"add",properties:{items_count:y.length,registries:Array.from(z),has_deprecated:h,dependencies_count:C.size,duration_ms:O}})})};import*as g from"@clack/prompts";import We from"path";import{z as D}from"zod";var Qe=D.object({registryIds:D.array(D.string()).optional(),all:D.boolean(),includeDeprecated:D.boolean().optional(),cwd:D.string(),baseUrl:D.string().optional(),onDiff:D.enum(["overwrite","backup"]).optional()}),ge=e=>{e.command("add-all [...registry-ids]","add all items from registries").option("-a, --all","Add all items from all registries",{default:!1}).option("--include-deprecated","Include deprecated items when used with `--all`",{default:!1}).option("-c, --cwd <cwd>","the working directory. defaults to the current directory.",{default:process.cwd()}).option("-u, --baseUrl <baseUrl>","the base url of the registry. defaults to the current directory.",{default:X}).option("--on-diff <mode>","Action when file differs: overwrite or backup").example("seed-design add-all ui --include-deprecated").example("seed-design add-all ui lib breeze").action(async(t,o)=>{let c=Date.now();g.intro("seed-design add-all");let{success:l,data:r,error:a}=Qe.safeParse({registryIds:t,...o});l||(g.log.error(`\uC798\uBABB\uB41C \uC635\uC158\uC774\uC5D0\uC694: ${a?.message}`),process.exit(1));let p=r.cwd,n=r.baseUrl,u=await U(p),$=We.resolve(p,u.path),{start:T,stop:_}=g.spinner();T("Registry\uB97C \uAC00\uC838\uC624\uACE0 \uC788\uC5B4\uC694...");let P=await Promise.all((await H({baseUrl:n})).map(async({id:h})=>V({baseUrl:n,registryId:h})));_("Registry\uB97C \uAC00\uC838\uC654\uC5B4\uC694.");let j=await(async()=>{if(r.all){let s=P.map(m=>m.id);return g.log.message(`\uBAA8\uB4E0 \uB808\uC9C0\uC2A4\uD2B8\uB9AC\uC758 \uBAA8\uB4E0 \uD56D\uBAA9\uC744 \uCD94\uAC00\uD569\uB2C8\uB2E4: ${i(s.join(", "))}`),s}if(r.registryIds?.length){let s=P.map(m=>m.id);for(let m of r.registryIds)s.includes(m)||(g.log.error(`\uB808\uC9C0\uC2A4\uD2B8\uB9AC '${m}'\uB97C \uCC3E\uC744 \uC218 \uC5C6\uC5B4\uC694.`),g.log.info(`\uC0AC\uC6A9 \uAC00\uB2A5\uD55C \uB808\uC9C0\uC2A4\uD2B8\uB9AC: ${s.join(", ")}`),process.exit(1));return g.log.message(`\uC120\uD0DD\uB41C \uB808\uC9C0\uC2A4\uD2B8\uB9AC\uC758 \uBAA8\uB4E0 \uD56D\uBAA9\uC744 \uCD94\uAC00\uD569\uB2C8\uB2E4: ${i(r.registryIds.join(", "))}`),r.registryIds}let h=await g.multiselect({message:"\uCD94\uAC00\uD560 \uB808\uC9C0\uC2A4\uD2B8\uB9AC\uB97C \uC120\uD0DD\uD574\uC8FC\uC138\uC694 (\uC2A4\uD398\uC774\uC2A4 \uBC14\uB85C \uC5EC\uB7EC \uAC1C \uC120\uD0DD \uAC00\uB2A5)",options:P.filter(({hideFromCLICatalog:s})=>!s).sort((s,m)=>m.items.length-s.items.length).map(s=>({label:s.id,value:s.id,hint:`${s.items.length}\uAC1C \uD56D\uBAA9 (${s.items[0].id} \uB4F1)`}))});return g.isCancel(h)&&(g.log.error("\uCDE8\uC18C\uB418\uC5C8\uC5B4\uC694."),process.exit(0)),g.log.message(`\uC120\uD0DD\uB41C \uB808\uC9C0\uC2A4\uD2B8\uB9AC\uC758 \uD56D\uBAA9\uC744 \uCD94\uAC00\uD569\uB2C8\uB2E4: ${i(h.join(", "))}`),h})(),x=P.filter(h=>j.includes(h.id)),y=x.flatMap(h=>h.items.filter(s=>s.deprecated?r.includeDeprecated:!0).map(s=>`${h.id}:${s.id}`)),b=x.flatMap(h=>h.items.filter(s=>s.deprecated).map(()=>1)).length;!r.includeDeprecated&&b>0&&g.log.info(`${b}\uAC1C\uC758 deprecated \uD56D\uBAA9\uC740 \uC81C\uC678\uB418\uC5C8\uC5B4\uC694. --include-deprecated \uC635\uC158\uC744 \uC0AC\uC6A9\uD558\uBA74 \uCD94\uAC00\uD560 \uC218 \uC788\uC5B4\uC694.`),y.length||(g.log.error("\uCD94\uAC00\uD560 \uD56D\uBAA9\uC774 \uC5C6\uC5B4\uC694."),process.exit(0)),g.log.message(`\uCD1D ${i(y.length.toString())}\uAC1C\uC758 \uD56D\uBAA9\uC744 \uCD94\uAC00\uD569\uB2C8\uB2E4.`);let{registryItemsToAdd:C,npmDependenciesToAdd:O}=J({selectedItemKeys:y,publicRegistries:P});await Y({registryItemsToAdd:C,rootPath:$,cwd:p,baseUrl:n,config:u,onDiff:r.onDiff});try{let{installed:h,filtered:s}=await W({cwd:p,deps:Array.from(O)});h.size===0&&g.log.message("\uBAA8\uB4E0 \uC758\uC874\uC131\uC774 \uC774\uBBF8 \uC124\uCE58\uB418\uC5B4 \uC788\uC5B4\uC694."),h.size&&(g.log.message(`\uC758\uC874\uC131 \uC124\uCE58 \uC644\uB8CC: ${i(Array.from(h).join(", "))}`),s.size&&g.log.message(`\uC124\uCE58\uD558\uC9C0 \uC54A\uC740 \uC758\uC874\uC131 (\uC774\uBBF8 \uC124\uCE58\uB428): ${i(Array.from(s).join(", "))}`)),g.outro("\uC644\uB8CC\uD588\uC5B4\uC694.")}catch(h){g.log.error(`\uCD94\uAC00\uC5D0 \uC2E4\uD328\uD588\uC5B4\uC694. ${h}`),g.outro(i("\uC791\uC5C5\uC774 \uCDE8\uC18C\uB410\uC5B4\uC694.")),process.exit(1)}let z=Date.now()-c;await K.track(r.cwd,{event:"add-all",properties:{registries:j,items_count:y.length,include_deprecated:r.includeDeprecated||!1,dependencies_count:O.size,duration_ms:z}})})};import*as w from"@clack/prompts";import Ze from"fs-extra";import ue from"path";import{z as te}from"zod";import et from"dedent";var tt=te.object({cwd:te.string(),yes:te.boolean().optional()}),ye=e=>{e.command("init","seed-design.json \uD30C\uC77C \uC0DD\uC131").option("-c, --cwd <cwd>","\uC791\uC5C5 \uB514\uB809\uD1A0\uB9AC. \uAE30\uBCF8\uAC12\uC740 \uD604\uC7AC \uB514\uB809\uD1A0\uB9AC.",{default:process.cwd()}).option("-y, --yes","\uBAA8\uB4E0 \uC9C8\uBB38\uC5D0 \uB300\uD574 \uAE30\uBCF8\uAC12\uC73C\uB85C \uB2F5\uBCC0\uD569\uB2C8\uB2E4.").action(async t=>{let o=Date.now();w.intro("seed-design.json \uD30C\uC77C \uC0DD\uC131");let c=tt.parse(t),l=c.yes,r={rsc:!1,tsx:!0,path:"./seed-design",telemetry:!0};l||(r={...await w.group({tsx:()=>w.confirm({message:`${i("TypeScript")}\uB97C \uC0AC\uC6A9\uC911\uC774\uC2E0\uAC00\uC694?`,initialValue:!0}),rsc:()=>w.confirm({message:`${i("React Server Components")}\uB97C \uC0AC\uC6A9\uC911\uC774\uC2E0\uAC00\uC694?`,initialValue:!1}),path:()=>w.text({message:`${i("seed-design \uD3F4\uB354")} \uACBD\uB85C\uB97C \uC785\uB825\uD574\uC8FC\uC138\uC694. (\uAE30\uBCF8\uAC12\uC740 \uD504\uB85C\uC81D\uD2B8 \uB8E8\uD2B8\uC5D0 \uC0DD\uC131\uB429\uB2C8\uB2E4.)`,initialValue:"./seed-design",defaultValue:"./seed-design",placeholder:"./seed-design"}),telemetry:()=>w.confirm({message:`\uAC1C\uC120\uC744 \uC704\uD574 ${i("\uC775\uBA85 \uC0AC\uC6A9 \uB370\uC774\uD130")}\uB97C \uC218\uC9D1\uD560\uAE4C\uC694?`,initialValue:!0})},{onCancel:()=>{w.cancel("\uC791\uC5C5\uC774 \uCDE8\uC18C\uB410\uC5B4\uC694."),process.exit(0)}})});try{let{start:p,stop:n}=w.spinner();p("seed-design.json \uD30C\uC77C \uC0DD\uC131\uC911...");let u=ue.resolve(c.cwd,"seed-design.json");await Ze.writeFile(u,`${JSON.stringify(r,null,2)}
9
+ `,"utf-8");let $=ue.relative(process.cwd(),u);n(`seed-design.json \uD30C\uC77C\uC774 ${i($)}\uC5D0 \uC0DD\uC131\uB410\uC5B4\uC694.`),w.log.info(i("seed-design add {component} \uBA85\uB839\uC5B4\uB85C \uCEF4\uD3EC\uB10C\uD2B8\uB97C \uCD94\uAC00\uD574\uBCF4\uC138\uC694!")),w.log.info(i("seed-design add \uBA85\uB839\uC5B4\uB85C \uCD94\uAC00\uD560 \uC218 \uC788\uB294 \uBAA8\uB4E0 \uCEF4\uD3EC\uB10C\uD2B8\uB97C \uD655\uC778\uD574\uBCF4\uC138\uC694.")),w.note(et(`SEED Design CLI\uB294 \uAC1C\uC120\uC744 \uC704\uD574 \uC775\uBA85 \uC0AC\uC6A9 \uB370\uC774\uD130\uB97C \uC218\uC9D1\uD574\uC694.
8
10
 
9
11
  \uBE44\uD65C\uC131\uD654\uD558\uB824\uBA74:
10
- \u2022 seed-design.json\uC5D0\uC11C ${a('"telemetry": false')}\uB85C \uC124\uC815
11
- \u2022 ${a("DISABLE_TELEMETRY=true")} \uD658\uACBD \uBCC0\uC218 \uC124\uC815
12
+ \u2022 seed-design.json\uC5D0\uC11C ${i('"telemetry": false')}\uB85C \uC124\uC815
13
+ \u2022 ${i("DISABLE_TELEMETRY=true")} \uD658\uACBD \uBCC0\uC218 \uC124\uC815
12
14
 
13
- \uC790\uC138\uD55C \uB0B4\uC6A9: https://seed-design.com/react/getting-started/cli/configuration#telemetry`),"Telemetry \uC548\uB0B4"),y.outro("\uC791\uC5C5\uC774 \uC644\uB8CC\uB410\uC5B4\uC694.")}catch(l){y.log.error(`seed-design.json \uD30C\uC77C \uC0DD\uC131\uC5D0 \uC2E4\uD328\uD588\uC5B4\uC694. ${l}`),y.outro(a("\uC791\uC5C5\uC774 \uCDE8\uC18C\uB410\uC5B4\uC694.")),process.exit(1)}let n=Date.now()-i;await O.track(c.cwd,{event:"init",properties:{tsx:r.tsx,rsc:r.rsc,telemetry:r.telemetry,yes_option:p,duration_ms:n}})})};import{cac as et}from"cac";var tt="seed-design",F=et(tt);async function rt(){let e=G();fe(F),ge(F),ye(F),F.version(e.version||"1.0.0","-v, --version"),F.help(),F.parse()}rt();
15
+ \uC790\uC138\uD55C \uB0B4\uC6A9: https://seed-design.com/react/getting-started/cli/configuration#telemetry`),"Telemetry \uC548\uB0B4"),w.outro("\uC791\uC5C5\uC774 \uC644\uB8CC\uB410\uC5B4\uC694.")}catch(p){w.log.error(`seed-design.json \uD30C\uC77C \uC0DD\uC131\uC5D0 \uC2E4\uD328\uD588\uC5B4\uC694. ${p}`),w.outro(i("\uC791\uC5C5\uC774 \uCDE8\uC18C\uB410\uC5B4\uC694.")),process.exit(1)}let a=Date.now()-o;await K.track(c.cwd,{event:"init",properties:{tsx:r.tsx,rsc:r.rsc,telemetry:r.telemetry,yes_option:l,duration_ms:a}})})};import{cac as rt}from"cac";var st="seed-design",N=rt(st);async function ot(){let e=q();fe(N),ge(N),ye(N),N.version(e.version||"1.0.0","-v, --version"),N.help(),N.parse()}ot();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@seed-design/cli",
3
- "version": "1.1.0",
3
+ "version": "1.2.1",
4
4
  "type": "module",
5
5
  "repository": {
6
6
  "type": "git",
@@ -25,14 +25,16 @@
25
25
  "lint:publish": "bun publint"
26
26
  },
27
27
  "dependencies": {
28
- "@antfu/ni": "^27.0.0",
28
+ "@antfu/ni": "^28.0.0",
29
29
  "@babel/core": "^7.26.10",
30
30
  "@babel/parser": "^7.27.0",
31
31
  "@babel/plugin-transform-typescript": "^7.27.0",
32
32
  "@clack/prompts": "^0.11.0",
33
+ "@npmcli/disparity-colors": "^3.0.1",
33
34
  "cac": "^6.7.14",
34
35
  "cosmiconfig": "^9.0.0",
35
36
  "dedent": "^1.7.0",
37
+ "diff": "^8.0.3",
36
38
  "execa": "^9.5.2",
37
39
  "findup-sync": "^5.0.0",
38
40
  "fs-extra": "^11.3.0",
@@ -18,6 +18,7 @@ const addAllOptionsSchema = z.object({
18
18
  includeDeprecated: z.boolean().optional(),
19
19
  cwd: z.string(),
20
20
  baseUrl: z.string().optional(),
21
+ onDiff: z.enum(["overwrite", "backup"]).optional(),
21
22
  });
22
23
 
23
24
  export const addAllCommand = (cli: CAC) => {
@@ -37,6 +38,7 @@ export const addAllCommand = (cli: CAC) => {
37
38
  "the base url of the registry. defaults to the current directory.",
38
39
  { default: BASE_URL },
39
40
  )
41
+ .option("--on-diff <mode>", "Action when file differs: overwrite or backup")
40
42
  .example("seed-design add-all ui --include-deprecated")
41
43
  .example("seed-design add-all ui lib breeze")
42
44
  .action(async (registryIds, opts) => {
@@ -156,7 +158,14 @@ export const addAllCommand = (cli: CAC) => {
156
158
  publicRegistries,
157
159
  });
158
160
 
159
- await writeRegistryItemSnippets({ registryItemsToAdd, rootPath, cwd, baseUrl, config });
161
+ await writeRegistryItemSnippets({
162
+ registryItemsToAdd,
163
+ rootPath,
164
+ cwd,
165
+ baseUrl,
166
+ config,
167
+ onDiff: options.onDiff,
168
+ });
160
169
 
161
170
  try {
162
171
  const { installed, filtered } = await installDependencies({
@@ -20,6 +20,7 @@ const addOptionsSchema = z.object({
20
20
  all: z.boolean(),
21
21
  cwd: z.string(),
22
22
  baseUrl: z.string().optional(),
23
+ onDiff: z.enum(["overwrite", "backup"]).optional(),
23
24
  });
24
25
 
25
26
  export const addCommand = (cli: CAC) => {
@@ -36,6 +37,7 @@ export const addCommand = (cli: CAC) => {
36
37
  "the base url of the registry. defaults to the current directory.",
37
38
  { default: BASE_URL },
38
39
  )
40
+ .option("--on-diff <mode>", "Action when file differs: overwrite or backup")
39
41
  .example("seed-design add ui:action-button")
40
42
  .example("seed-design add ui:alert-dialog")
41
43
  .action(async (itemIds, opts) => {
@@ -180,6 +182,7 @@ export const addCommand = (cli: CAC) => {
180
182
  cwd,
181
183
  baseUrl,
182
184
  config,
185
+ onDiff: options.onDiff,
183
186
  });
184
187
 
185
188
  try {
@@ -3,6 +3,8 @@ import { transform } from "@/src/utils/transformers";
3
3
  import * as p from "@clack/prompts";
4
4
  import fs from "fs-extra";
5
5
  import path from "path";
6
+ import { createPatch } from "diff";
7
+ import colorize from "@npmcli/disparity-colors";
6
8
  import { highlight } from "./color";
7
9
  import type { Config } from "@/src/utils/get-config";
8
10
  import type { PublicRegistry } from "@/src/schema";
@@ -13,12 +15,14 @@ export async function writeRegistryItemSnippets({
13
15
  cwd,
14
16
  baseUrl,
15
17
  config,
18
+ onDiff,
16
19
  }: {
17
20
  registryItemsToAdd: { registryId: string; items: PublicRegistry["items"] }[];
18
21
  rootPath: string;
19
22
  cwd: string;
20
23
  baseUrl: string;
21
24
  config: Config;
25
+ onDiff?: "overwrite" | "backup";
22
26
  }) {
23
27
  const registryResult: { name: string; path: string }[] = [];
24
28
 
@@ -53,23 +57,87 @@ export async function writeRegistryItemSnippets({
53
57
  }),
54
58
  );
55
59
 
56
- await Promise.all(
57
- transformedSnippets.map(async ({ filePath, content }) => {
58
- await fs.ensureDir(path.dirname(filePath));
59
- await fs.writeFile(filePath, content);
60
- }),
61
- );
60
+ const writtenSnippets: typeof transformedSnippets = [];
62
61
 
63
- const snippetResults = transformedSnippets.map(({ name, relativePath }) => ({
64
- name,
65
- path: relativePath,
66
- }));
62
+ for (const snippet of transformedSnippets) {
63
+ const { filePath, content, relativePath } = snippet;
67
64
 
68
- registryResult.push(...snippetResults);
65
+ await fs.ensureDir(path.dirname(filePath));
69
66
 
70
- p.log.success(
71
- `${highlight(`${registryId}:${id}`)} 관련 스니펫 다운로드 완료: ${highlight(snippetResults.map((r) => r.path).join(", "))}`,
72
- );
67
+ // 파일 존재 여부 확인
68
+ if (fs.existsSync(filePath)) {
69
+ const existingContent = await fs.readFile(filePath, "utf-8");
70
+
71
+ // 내용이 동일하면 스킵
72
+ if (existingContent === content) {
73
+ p.log.info(`${highlight(relativePath)}: 이미 최신 상태예요.`);
74
+ continue;
75
+ }
76
+
77
+ const filename = path.basename(filePath);
78
+ const ext = path.extname(filePath);
79
+ const base = path.basename(filePath, ext);
80
+ const timestamp = Date.now();
81
+ const legacyFilename = `legacy-${base}-${timestamp}${ext}`;
82
+
83
+ // diff가 있는 경우
84
+ const action = await (async () => {
85
+ if (onDiff) return onDiff;
86
+
87
+ // interactive mode
88
+ const patch = createPatch(relativePath, existingContent, content);
89
+ const coloredDiff = colorize(patch);
90
+
91
+ p.log.message(
92
+ `\n${highlight(relativePath)}: 현재 파일과 받으려는 파일의 내용이 달라요.\n`,
93
+ );
94
+ p.log.message(coloredDiff);
95
+
96
+ return p.select({
97
+ message:
98
+ "현재 파일에 스타일 변경, 로깅 등 커스터마이징이 적용되어 있는 경우 신규 파일에 동일한 커스터마이징을 적용하는 것을 검토해보세요.",
99
+ options: [
100
+ { value: "overwrite", label: `${filename} 덮어쓰기` },
101
+ {
102
+ value: "backup",
103
+ label: `기존 파일 내용을 ${legacyFilename}으로 옮기고 ${filename} 받기`,
104
+ },
105
+ { value: "skip", label: "새 파일 받지 않고 그대로 두기" },
106
+ ],
107
+ });
108
+ })();
109
+
110
+ if (p.isCancel(action) || action === "skip") {
111
+ p.log.info(`${highlight(relativePath)}: 파일을 받지 않고 건너뛰었어요.`);
112
+ continue;
113
+ }
114
+
115
+ if (action === "backup") {
116
+ const dir = path.dirname(filePath);
117
+ const legacyPath = path.join(dir, legacyFilename);
118
+ await fs.rename(filePath, legacyPath);
119
+ p.log.info(
120
+ `${highlight(relativePath)}: 기존 파일을 ${highlight(path.relative(cwd, legacyPath))}로 옮겼어요.`,
121
+ );
122
+ }
123
+ }
124
+
125
+ await fs.writeFile(filePath, content);
126
+ writtenSnippets.push(snippet);
127
+ }
128
+
129
+ if (writtenSnippets.length > 0) {
130
+ const snippetResults = writtenSnippets.map(({ name, relativePath }) => ({
131
+ name,
132
+ path: relativePath,
133
+ }));
134
+
135
+ registryResult.push(...snippetResults);
136
+
137
+ p.log.success(
138
+ `${highlight(`${registryId}:${id}`)} 관련 스니펫 다운로드 완료: ${highlight(snippetResults.map((r) => r.path).join(", "))}`,
139
+ );
140
+ }
73
141
  }
74
142
  }
75
143
  }