@seed-design/cli 1.2.1 → 1.3.0
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 +12 -10
- package/package.json +3 -3
- package/src/AGENTS.md +17 -0
- package/src/commands/add-all.ts +160 -111
- package/src/commands/add.ts +181 -136
- package/src/commands/compat.ts +281 -0
- package/src/commands/docs.ts +312 -0
- package/src/commands/init.ts +56 -67
- package/src/index.ts +6 -0
- package/src/schema.ts +53 -4
- package/src/tests/compatibility.test.ts +148 -0
- package/src/tests/resolve-dependencies.test.ts +14 -14
- package/src/utils/analytics.ts +3 -4
- package/src/utils/compatibility.ts +291 -0
- package/src/utils/error.ts +160 -0
- package/src/utils/fetch.ts +22 -0
- package/src/utils/get-config.ts +35 -22
- package/src/utils/get-package-info.ts +4 -4
- package/src/utils/init-config.ts +67 -0
- package/src/utils/install.ts +10 -3
package/bin/index.mjs
CHANGED
|
@@ -1,15 +1,17 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import*as
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
${
|
|
6
|
-
`),
|
|
2
|
+
import*as X from"@clack/prompts";import{cosmiconfig as rt}from"cosmiconfig";import{z as te}from"zod";import*as H from"@clack/prompts";import{ZodError as Ze}from"zod";import Qe from"picocolors";var a=e=>Qe.cyan(e);var $=class extends Error{hint;details;constructor({message:t,hint:s,details:o=[],cause:n}){super(t,{cause:n}),this.name="CliError",this.hint=s,this.details=o}},k=class extends Error{constructor(t="\uC791\uC5C5\uC774 \uCDE8\uC18C\uB410\uC5B4\uC694."){super(t),this.name="CliCancelError"}};function z(e){return e instanceof k}function F(e){return!e||typeof e!="object"||!("verbose"in e)?!1:e.verbose===!0}function et(e,t){if(e instanceof $)return{reason:e.message,hint:e.hint??t,details:e.details,stack:tt(e.cause??e)};if(e instanceof Ze){let s=e.issues.map(o=>`${o.path.join(".")||"(root)"}: ${o.message}`);return{reason:"\uC785\uB825\uAC12 \uB610\uB294 \uC124\uC815 \uD30C\uC77C \uD615\uC2DD\uC774 \uC62C\uBC14\uB974\uC9C0 \uC54A\uC544\uC694.",hint:t,details:s,stack:e.stack}}if(e instanceof Error){let s=e,o=[];return(s.escapedCommand||s.command)&&o.push(`\uC2E4\uD589 \uBA85\uB839\uC5B4: ${s.escapedCommand??s.command}`),typeof s.exitCode=="number"&&o.push(`\uC885\uB8CC \uCF54\uB4DC: ${s.exitCode}`),s.stderr?.trim()?o.push(`stderr: ${s.stderr.trim()}`):s.stdout?.trim()&&o.push(`stdout: ${s.stdout.trim()}`),{reason:s.shortMessage??e.message,hint:t,details:o,stack:e.stack}}return typeof e=="string"?{reason:e,hint:t,details:[]}:{reason:"\uC54C \uC218 \uC5C6\uB294 \uC624\uB958\uAC00 \uBC1C\uC0DD\uD588\uC5B4\uC694.",hint:t,details:[]}}function tt(e){if(e instanceof Error)return e.stack}function V(e,{defaultMessage:t,defaultHint:s,verbose:o=!1}){let n=et(e,s);H.log.error(t),H.log.error(`\uC6D0\uC778: ${n.reason}`);for(let r of n.details)H.log.info(r);n.hint&&H.log.info(`\uD574\uACB0 \uD78C\uD2B8: ${n.hint}`),o&&n.stack&&(H.log.message(a(`
|
|
3
|
+
[verbose] stack trace`)),H.log.message(n.stack)),H.outro(a("\uC791\uC5C5\uC5D0 \uC2E4\uD328\uD588\uC5B4\uC694."))}import*as W from"@clack/prompts";import st from"fs-extra";import Pe from"path";var K={rsc:!1,tsx:!0,path:"./seed-design",telemetry:!0};async function Se(){return await W.group({tsx:()=>W.confirm({message:`${a("TypeScript")}\uB97C \uC0AC\uC6A9\uC911\uC774\uC2E0\uAC00\uC694?`,initialValue:K.tsx}),rsc:()=>W.confirm({message:`${a("React Server Components")}\uB97C \uC0AC\uC6A9\uC911\uC774\uC2E0\uAC00\uC694?`,initialValue:K.rsc}),path:()=>W.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:K.path,defaultValue:K.path,placeholder:K.path}),telemetry:()=>W.confirm({message:`\uAC1C\uC120\uC744 \uC704\uD574 ${a("\uC775\uBA85 \uC0AC\uC6A9 \uB370\uC774\uD130")}\uB97C \uC218\uC9D1\uD560\uAE4C\uC694?`,initialValue:K.telemetry})},{onCancel:()=>{throw new k}})}async function fe({cwd:e,config:t}){let s=Pe.resolve(e,"seed-design.json");return await st.writeFile(s,`${JSON.stringify(t,null,2)}
|
|
4
|
+
`,"utf-8"),{relativePath:Pe.relative(process.cwd(),s),targetPath:s}}var Re="seed-design",it=rt(Re,{searchPlaces:[`${Re}.json`]}),Ee=te.object({$schema:te.string().optional(),rsc:te.coerce.boolean().default(!1),tsx:te.coerce.boolean().default(!0),path:te.string(),telemetry:te.coerce.boolean().optional().default(!0)}).strict();async function ge(e){let t=await le(e);if(t)return t;X.log.error("\uD504\uB85C\uC81D\uD2B8 \uB8E8\uD2B8 \uACBD\uB85C\uC5D0 `seed-design.json` \uD30C\uC77C\uC774 \uC5C6\uC5B4\uC694.");let s=await X.confirm({message:"seed-design.json \uD30C\uC77C\uC744 \uC0DD\uC131\uD558\uC2DC\uACA0\uC5B4\uC694?"});if(X.isCancel(s)||!s)throw new k;try{return await fe({cwd:e,config:K}),X.log.message("seed-design.json \uD30C\uC77C\uC774 \uC0DD\uC131\uB410\uC5B4\uC694."),Ee.parse(K)}catch(o){throw new $({message:"seed-design.json \uD30C\uC77C \uC0DD\uC131\uC5D0 \uC2E4\uD328\uD588\uC5B4\uC694.",hint:"\uB514\uB809\uD1A0\uB9AC \uC4F0\uAE30 \uAD8C\uD55C\uACFC \uACBD\uB85C\uB97C \uD655\uC778\uD55C \uB4A4 \uB2E4\uC2DC \uC2DC\uB3C4\uD574\uBCF4\uC138\uC694.",cause:o})}}async function le(e){let t=await it.search(e);if(!t||t.isEmpty)return null;try{return Ee.parse(t.config)}catch(s){throw new $({message:"seed-design.json \uD615\uC2DD\uC774 \uC62C\uBC14\uB974\uC9C0 \uC54A\uC544\uC694.",hint:"https://seed-design.com/react/getting-started/cli/configuration \uBB38\uC11C\uB97C \uCC38\uACE0\uD574 \uC8FC\uC138\uC694.",cause:s})}}function ue({selectedItemKeys:e,publicRegistries:t}){let s=[],o=new Set;function n(r,i){let c=s.find(m=>m.registryId===r);if(!c?.items.some(m=>m.id===i.id)){if(c?c.items.push(i):s.push({registryId:r,items:[i]}),i.dependencies?.length)for(let m of i.dependencies)o.add(m);if(i.innerDependencies?.length)for(let m of i.innerDependencies)for(let y of m.itemIds){let C=t.find(b=>b.id===m.registryId)?.items.find(b=>b.id===y);if(!C)throw new Error(`Cannot find dependency item: ${m.registryId}:${y}`);n(m.registryId,C)}}}for(let r of e){let[i,...c]=r.split(":"),m=c.join(":");if(!i||!m)throw new Error(`Invalid snippet format: "${r}"`);let y=t.find(C=>C.id===i)?.items.find(C=>C.id===m);if(!y)throw new Error(`Cannot find snippet: "${r}"`);n(i,y)}return{registryItemsToAdd:s,npmDependenciesToAdd:o}}import*as $e from"@clack/prompts";import{z as p}from"zod";var Ce=p.object({id:p.string(),description:p.string().optional(),deprecated:p.boolean().optional(),hideFromCLICatalog:p.boolean().optional(),dependencies:p.array(p.string()).optional(),innerDependencies:p.array(p.object({registryId:p.string(),itemIds:p.array(p.string())})).optional(),snippets:p.array(p.object({path:p.string(),dependencies:p.record(p.string(),p.string()).optional(),content:p.string()}))}),Ie=p.object({id:p.string(),hideFromCLICatalog:p.boolean().optional(),items:p.array(Ce.omit({snippets:!0}).extend({snippets:p.array(p.object({path:p.string(),dependencies:p.record(p.string(),p.string()).optional()}))}))}),ke=p.array(p.object({id:p.string()})),ot=p.object({label:p.string(),path:p.string()}),nt=p.object({id:p.string(),title:p.string(),description:p.string().optional(),docUrl:p.string(),deprecated:p.boolean().optional(),snippetKey:p.string().optional(),snippets:p.array(ot).optional()}),at=p.object({id:p.string(),label:p.string(),items:p.array(nt)}),ct=p.object({id:p.string(),label:p.string(),sections:p.array(at)}),ve=p.object({categories:p.array(ct)});async function je({baseUrl:e}){let t=await fetch(`${e}/__docs__/index.json`);if(!t.ok)throw new $({message:`\uBB38\uC11C \uBAA9\uB85D\uC744 \uAC00\uC838\uC624\uC9C0 \uBABB\uD588\uC5B4\uC694: ${t.status} ${t.statusText}`});let s=await t.json(),{success:o,data:n,error:r}=ve.safeParse(s);if(!o)throw new $({message:`\uBB38\uC11C \uBAA9\uB85D \uD30C\uC2F1\uC5D0 \uC2E4\uD328\uD588\uC5B4\uC694: ${r?.message}`});return n}async function se({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 s=await t.json(),{success:o,data:n,error:r}=ke.safeParse(s);if(!o)throw new Error(`Failed to parse registries: ${r?.message}`);return n}async function re({baseUrl:e,registryId:t}){let s=await fetch(`${e}/__registry__/${t}/index.json`);if(!s.ok)throw new Error(`Failed to fetch ${t} registry: ${s.status} ${s.statusText}`);let o=await s.json(),{success:n,data:r,error:i}=Ie.safeParse(o);if(!n)throw new Error(`Failed to parse ${t} registry: ${i?.message}`);return r}async function pt({baseUrl:e,registryId:t,registryItemId:s}){let o=await fetch(`${e}/__registry__/${t}/${s}.json`);if(!o.ok)throw new Error(`Failed to fetch ${s}: ${o.status} ${o.statusText}`);let n=await o.json(),{success:r,data:i,error:c}=Ce.safeParse(n);if(!r)throw new Error(`Failed to parse ${s}: ${c?.message}`);return i}async function Ae({baseUrl:e,registryId:t,registryItemIds:s}){return await Promise.all(s.map(async o=>{try{return await pt({baseUrl:e,registryId:t,registryItemId:o})}catch(n){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 i=await r.json(),{success:c,data:m}=Ie.safeParse(i);throw c?($e.log.error(`${o} \uC2A4\uB2C8\uD3AB\uC774 ${t} \uB808\uC9C0\uC2A4\uD2B8\uB9AC\uC5D0 \uC5C6\uC5B4\uC694.`),$e.log.info(`${t} \uB808\uC9C0\uC2A4\uD2B8\uB9AC\uC5D0 \uC874\uC7AC\uD558\uB294 \uC2A4\uB2C8\uD3AB:
|
|
5
|
+
${m.items.map(y=>y.id).join(`
|
|
6
|
+
`)}`),n):new Error(`Failed to parse registry index for ${t}`)}}))}import{promises as ut}from"fs";import{tmpdir as yt}from"os";import _e from"path";import{transformFromAstSync as lt}from"@babel/core";import mt from"@babel/plugin-transform-typescript";import*as ye from"recast";import{parse as dt}from"@babel/parser";var ft={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"]},De=async({sourceFile:e,config:t})=>{let s=e.getFullText();if(t.tsx)return s;let o=ye.parse(s,{parser:{parse:r=>dt(r,ft)}}),n=lt(o,s,{cloneInputAst:!1,code:!1,ast:!0,plugins:[mt],configFile:!1});if(!n||!n.ast)throw new Error("Failed to transform JSX");return ye.print(n.ast).code};import{SyntaxKind as gt}from"ts-morph";var Te=async({sourceFile:e,config:t})=>{if(t.rsc)return e;let s=e.getFirstChildByKind(gt.ExpressionStatement);if(!s)return e;let o=s.getExpression();if(!o)return e;let n=o.getText().trim();if(n!=='"use client"'&&n!=="'use client'")return e;let r=s.getText(),i=s.getFullText();if(r.trim()===i.trim())return e;let m=i.replace(r,"").replace(/^\s*\n/,"").replace(/\n\s*$/,"");return s.replaceWithText(m),e};import{Project as ht,ScriptKind as wt}from"ts-morph";var bt=[Te],Ct=new ht({compilerOptions:{}});async function It(e){let t=await ut.mkdtemp(_e.join(yt(),"seed-design-"));return _e.join(t,e)}async function Oe(e){let t=await It(e.filename),s=Ct.createSourceFile(t,e.raw,{scriptKind:wt.TSX});for(let o of bt)o({sourceFile:s,...e});return await De({sourceFile:s,...e})}import*as L from"@clack/prompts";import ie from"fs-extra";import q from"path";import{createPatch as $t}from"diff";import xt from"@npmcli/disparity-colors";async function he({registryItemsToAdd:e,rootPath:t,cwd:s,baseUrl:o,config:n,onDiff:r}){let i=[];for(let{registryId:c,items:m}of e){let y=q.join(t,c);ie.ensureDirSync(y);let C=await Ae({baseUrl:o,registryId:c,registryItemIds:m.map(b=>b.id)});for(let{id:b,snippets:h}of C){let j=await Promise.all(h.map(async g=>{let d=await Oe({filename:g.path,config:n,raw:g.content}),w=q.join(y,g.path);return n.tsx||(w=w.replace(/\.tsx$/,".jsx"),w=w.replace(/\.ts$/,".js")),{filePath:w,content:d,relativePath:q.relative(s,w),name:`${c}:${b}`}})),f=[];for(let g of j){let{filePath:d,content:w,relativePath:I}=g;if(await ie.ensureDir(q.dirname(d)),ie.existsSync(d)){let E=await ie.readFile(d,"utf-8");if(E===w){L.log.info(`${a(I)}: \uC774\uBBF8 \uCD5C\uC2E0 \uC0C1\uD0DC\uC608\uC694.`);continue}let P=q.basename(d),O=q.extname(d),ee=q.basename(d,O),pe=Date.now(),x=`legacy-${ee}-${pe}${O}`,l=await(async()=>{if(r)return r;let u=$t(I,E,w),A=xt(u);return L.log.message(`
|
|
7
|
+
${a(I)}: \uD604\uC7AC \uD30C\uC77C\uACFC \uBC1B\uC73C\uB824\uB294 \uD30C\uC77C\uC758 \uB0B4\uC6A9\uC774 \uB2EC\uB77C\uC694.
|
|
8
|
+
`),L.log.message(A),L.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:`${P} \uB36E\uC5B4\uC4F0\uAE30`},{value:"backup",label:`\uAE30\uC874 \uD30C\uC77C \uB0B4\uC6A9\uC744 ${x}\uC73C\uB85C \uC62E\uAE30\uACE0 ${P} \uBC1B\uAE30`},{value:"skip",label:"\uC0C8 \uD30C\uC77C \uBC1B\uC9C0 \uC54A\uACE0 \uADF8\uB300\uB85C \uB450\uAE30"}]})})();if(L.isCancel(l)||l==="skip"){L.log.info(`${a(I)}: \uD30C\uC77C\uC744 \uBC1B\uC9C0 \uC54A\uACE0 \uAC74\uB108\uB6F0\uC5C8\uC5B4\uC694.`);continue}if(l==="backup"){let u=q.dirname(d),A=q.join(u,x);await ie.rename(d,A),L.log.info(`${a(I)}: \uAE30\uC874 \uD30C\uC77C\uC744 ${a(q.relative(s,A))}\uB85C \uC62E\uACBC\uC5B4\uC694.`)}}await ie.writeFile(d,w),f.push(g)}if(f.length>0){let g=f.map(({name:d,relativePath:w})=>({name:d,path:w}));i.push(...g),L.log.success(`${a(`${c}:${b}`)} \uAD00\uB828 \uC2A4\uB2C8\uD3AB \uB2E4\uC6B4\uB85C\uB4DC \uC644\uB8CC: ${a(g.map(d=>d.path).join(", "))}`)}}}}import*as S from"@clack/prompts";import Gt from"path";import{z as Z}from"zod";var B="https://seed-design.io";import*as Ke from"@clack/prompts";import{execa as vt}from"execa";import{detect as Pt}from"@antfu/ni";async function Me(e){let t=await Pt({programmatic:!0,cwd:e});return t==="yarn@berry"?"yarn":t==="pnpm@6"?"pnpm":t==="bun"?"bun":t==="deno"?"deno":t??"npm"}import St from"findup-sync";import Rt from"fs-extra";var Et="package.json";function kt(e=process.cwd()){let t=St(Et,{cwd:e});if(!t)throw new Error("No package.json file found in the project.");return t}function oe(e=process.cwd()){let t=kt(e);return Rt.readJSONSync(t)}async function we({cwd:e,deps:t,dev:s=!1}){let{start:o,stop:n}=Ke.spinner(),r=await Me(e),c={...oe(e).dependencies},m=new Set(t.filter(f=>!c[f])),y=new Set(t.filter(f=>c[f]));if(!m.size)return{installed:new Set,filtered:m};o("\uC758\uC874\uC131 \uC124\uCE58\uC911...");let h=[r==="npm"?"install":"add",s?"-D":null,...m].filter(Boolean),j=`${r} ${h.join(" ")}`;try{await vt(r,h,{cwd:e})}catch(f){throw n("\uC758\uC874\uC131 \uC124\uCE58\uC5D0 \uC2E4\uD328\uD588\uC5B4\uC694."),new $({message:"\uC758\uC874\uC131 \uC124\uCE58\uC5D0 \uC2E4\uD328\uD588\uC5B4\uC694.",hint:"\uB124\uD2B8\uC6CC\uD06C \uC0C1\uD0DC\uB97C \uD655\uC778\uD558\uACE0, \uC124\uCE58 \uBA85\uB839\uC5B4\uB97C \uC9C1\uC811 \uC2E4\uD589\uD574 \uC0C1\uC138 \uC624\uB958\uB97C \uD655\uC778\uD574\uBCF4\uC138\uC694.",details:[`\uC2E4\uD589 \uBA85\uB839\uC5B4: ${j}`],cause:f})}return n("\uC758\uC874\uC131 \uC124\uCE58\uAC00 \uC644\uB8CC\uB410\uC5B4\uC694."),{installed:m,filtered:y}}import{randomUUID as jt}from"node:crypto";import*as Ue from"@clack/prompts";var At="seed_cli";async function Dt(e){if(process.env.DISABLE_TELEMETRY==="true"||process.env.SEED_DISABLE_TELEMETRY==="true")return!1;try{if((await le(e))?.telemetry===!1)return!1}catch{}return!0}function Tt(){return jt()}var _t=Tt(),Le=!1;async function Ot(e,{event:t,properties:s={}}){if(!await Dt(e))return;let n=`${At}.${t}`;Le||(Ue.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)"),Le=!0);try{let r="https://us.i.posthog.com/capture",i={"Content-Type":"application/json"},c={api_key:"phc_seod8HhifElOP1R92KmvsQybrtUmkOTgZBsq0mfCelR",event:n,distinct_id:_t,properties:{...s,$process_person_profile:!1},timestamp:new Date().toISOString()},m=new AbortController,y=setTimeout(()=>m.abort(),5e3);try{await fetch(r,{method:"POST",headers:i,body:JSON.stringify(c),signal:m.signal})}finally{clearTimeout(y)}}catch{}}var U={track:Ot};import*as Q from"@clack/prompts";import Mt from"fs-extra";import Kt from"path";import{intersects as Lt,satisfies as Ut,valid as ze,validRange as Fe}from"semver";var me=["@seed-design/react","@seed-design/css"],Ne="workspace:",Nt="npm:";function ne(e){try{let t=oe(e),s={...t.dependencies,...t.devDependencies,...t.peerDependencies,...t.optionalDependencies},o={};for(let n of me){let r=s[n];typeof r=="string"&&(o[n]=r)}return o}catch{return{}}}function ae({publicRegistries:e,itemKeys:t,projectPackageVersions:s}){let o=Array.from(new Set(t)),n=new Map(e.flatMap(i=>i.items.map(c=>[`${i.id}:${c.id}`,c]))),r=[];for(let i of o){let c=n.get(i);if(!c)continue;let m=zt(c);for(let y of me){let C=Array.from(m[y]??[]);if(!C.length)continue;let b=s[y];if(!b){r.push({itemKey:i,packageName:y,requiredRanges:C,type:"missing-package"});continue}let h=Ft(b);if(!h){r.push({itemKey:i,packageName:y,requiredRanges:C,installedVersionSpec:b,type:"invalid-version-spec"});continue}C.every(f=>Vt({currentVersionSpec:h,requiredRange:f}))||r.push({itemKey:i,packageName:y,requiredRanges:C,installedVersionSpec:b,type:"incompatible-version"})}}return{checkedItemKeys:o,projectPackageVersions:s,issues:r}}function ce({report:e,title:t}){if(!e.issues.length)return;Q.log.warn(t),Q.log.info(`\uD604\uC7AC \uD504\uB85C\uC81D\uD2B8 \uBC84\uC804: ${me.map(o=>`${o}@${a(e.projectPackageVersions[o]??"\uBBF8\uC124\uCE58")}`).join(", ")}`);let s=new Map;for(let o of e.issues){let n=s.get(o.itemKey)??[];n.push(o),s.set(o.itemKey,n)}for(let[o,n]of s.entries()){Q.log.warn(a(o));for(let r of n){let i=r.requiredRanges.join(" | ");if(r.type==="missing-package"){Q.log.info(` - ${r.packageName}: \uD328\uD0A4\uC9C0\uAC00 \uC124\uCE58\uB418\uC5B4 \uC788\uC9C0 \uC54A\uC544\uC694. \uD544\uC694 \uBC94\uC704: ${i}`);continue}if(r.type==="invalid-version-spec"){Q.log.info(` - ${r.packageName}: \uD604\uC7AC \uBC84\uC804 \uD615\uC2DD\uC744 \uD574\uC11D\uD558\uC9C0 \uBABB\uD588\uC5B4\uC694 (${r.installedVersionSpec}). \uD544\uC694 \uBC94\uC704: ${i}`);continue}Q.log.info(` - ${r.packageName}: \uD604\uC7AC ${r.installedVersionSpec}, \uD544\uC694 \uBC94\uC704 ${i}`)}}}function Ve({publicRegistries:e,rootPath:t}){let s=[];for(let o of e)for(let n of o.items)n.snippets.some(i=>qt(i.path).some(c=>Mt.existsSync(Kt.join(t,o.id,c))))&&s.push(`${o.id}:${n.id}`);return s}function zt(e){let t=Object.fromEntries(me.map(s=>[s,new Set]));for(let s of e.snippets)for(let[o,n]of Object.entries(s.dependencies??{}))Bt(o)&&t[o].add(n);return t}function Ft(e){let t=e.trim();if(t.startsWith(Ne)&&(t=t.slice(Ne.length).trim()),t.startsWith(Nt)){let s=t.split("@").at(-1);if(!s)return null;t=s}return!t||t==="*"?null:ze(t)||Fe(t)?t:null}function Vt({currentVersionSpec:e,requiredRange:t}){let s=Fe(t);return s?ze(e)?Ut(e,s,{includePrerelease:!0}):Lt(e,s,{includePrerelease:!0}):!1}function qt(e){let t=new Set([e]);return e.endsWith(".tsx")&&t.add(`${e.slice(0,-4)}.jsx`),e.endsWith(".ts")&&t.add(`${e.slice(0,-3)}.js`),e.endsWith(".jsx")&&t.add(`${e.slice(0,-4)}.tsx`),e.endsWith(".js")&&t.add(`${e.slice(0,-3)}.ts`),Array.from(t)}function Bt(e){return me.includes(e)}var Ht=Z.object({itemIds:Z.array(Z.string()).optional(),all:Z.boolean(),cwd:Z.string(),baseUrl:Z.string().optional(),onDiff:Z.enum(["overwrite","backup"]).optional()}),qe=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:B}).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,s)=>{let o=Date.now(),n=F(s);S.intro("seed-design add");try{let r=Ht.safeParse({itemIds:t,...s});if(!r.success)throw r.error;let{data:{all:i,...c}}=r;if(i)throw new $({message:"`--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."});let m=c.cwd,y=c.baseUrl,C=await ge(m),b=Gt.resolve(m,C.path),{start:h,stop:j}=S.spinner();h("Registry\uB97C \uAC00\uC838\uC624\uACE0 \uC788\uC5B4\uC694...");let f=await(async()=>{try{let l=await Promise.all((await se({baseUrl:y})).map(async({id:u})=>re({baseUrl:y,registryId:u})));return j("Registry\uB97C \uAC00\uC838\uC654\uC5B4\uC694."),l}catch(l){throw j("Registry\uB97C \uAC00\uC838\uC624\uC9C0 \uBABB\uD588\uC5B4\uC694."),l}})(),g=await(async()=>{if(c.itemIds?.length)return c.itemIds;let l=await S.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:f.filter(({hideFromCLICatalog:u})=>!u).flatMap(({id:u,items:A})=>A.filter(({hideFromCLICatalog:M})=>!M).sort((M,T)=>M.id.localeCompare(T.id)).map(({id:M,description:T,deprecated:G})=>({label:`${G?"(deprecated) ":""}${a(u)}:${M}`,value:`${u}:${M}`,hint:T,deprecated:G,registryItemCount:A.length}))).sort((u,A)=>u.deprecated!==A.deprecated?u.deprecated?1:-1:A.registryItemCount-u.registryItemCount)});if(S.isCancel(l))throw new k;return l})();if(!g?.length)throw new k("\uCD94\uAC00\uD560 \uD56D\uBAA9\uC774 \uC120\uD0DD\uB418\uC9C0 \uC54A\uC558\uC5B4\uC694.");S.log.message(`\uC120\uD0DD\uB41C \uD56D\uBAA9: ${a(g.join(", "))}`);let d=[];for(let l of g){let[u,...A]=l.split(":"),M=A.join(":");if(!u||!M)throw new $({message:`${a(l)}: \uD56D\uBAA9 \uC774\uB984\uC774 \uC798\uBABB\uB418\uC5C8\uC5B4\uC694.`,hint:`${a("ui:action-button")}\uACFC \uAC19\uC740 \uD615\uC2DD\uC73C\uB85C \uC785\uB825\uD574\uBCF4\uC138\uC694.`});let T=f.find(G=>G.id===u)?.items.find(G=>G.id===M);if(!T)throw new $({message:`${a(l)}: \uD56D\uBAA9\uC744 \uCC3E\uC744 \uC218 \uC5C6\uC5B4\uC694.`});if(T.deprecated){let G=await S.confirm({message:`${a(T.id)}: deprecated \uB418\uC5C8\uC5B4\uC694. \uCD94\uAC00\uD560\uAE4C\uC694?`,initialValue:!1});if(S.isCancel(G))throw new k;if(G===!1){S.log.info(`${a(T.id)}: \uCD94\uAC00\uD558\uC9C0 \uC54A\uC744\uAC8C\uC694.`);continue}}d.push(l)}let{registryItemsToAdd:w,npmDependenciesToAdd:I}=ue({selectedItemKeys:d,publicRegistries:f}),E=ae({publicRegistries:f,itemKeys:w.flatMap(({registryId:l,items:u})=>u.map(A=>`${l}:${A.id}`)),projectPackageVersions:ne(c.cwd)});ce({report:E,title:"\uD604\uC7AC \uD504\uB85C\uC81D\uD2B8 \uBC84\uC804\uACFC \uD638\uD658\uB418\uC9C0 \uC54A\uC744 \uC218 \uC788\uB294 \uC2A4\uB2C8\uD3AB\uC774 \uC788\uC5B4\uC694."}),S.log.info(`\uCD94\uAC00\uD560 \uD56D\uBAA9: ${a(w.map(l=>l.items.map(u=>`${l.registryId}:${u.id}`).join(", ")).join(", ")||"\uC5C6\uC74C")}
|
|
7
9
|
|
|
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
|
-
`,"
|
|
10
|
+
\uC124\uCE58\uD560 \uC758\uC874\uC131: ${a(Array.from(I).join(", ")||"\uC5C6\uC74C")}`),await he({registryItemsToAdd:w,rootPath:b,cwd:m,baseUrl:y,config:C,onDiff:c.onDiff});let{installed:P,filtered:O}=await we({cwd:m,deps:Array.from(I)});P.size===0&&S.log.message("\uBAA8\uB4E0 \uC758\uC874\uC131\uC774 \uC774\uBBF8 \uC124\uCE58\uB418\uC5B4 \uC788\uC5B4\uC694."),P.size&&(S.log.message(`\uC758\uC874\uC131 \uC124\uCE58 \uC644\uB8CC: ${a(Array.from(P).join(", "))}`),O.size&&S.log.message(`\uC124\uCE58\uD558\uC9C0 \uC54A\uC740 \uC758\uC874\uC131 (\uC774\uBBF8 \uC124\uCE58\uB428): ${a(Array.from(O).join(", "))}`)),S.outro("\uC644\uB8CC\uD588\uC5B4\uC694.");let ee=Date.now()-o,pe=new Set(w.map(l=>l.registryId)),x=g.some(l=>{let[u,...A]=l.split(":"),M=A.join(":");return f.find(T=>T.id===u)?.items.find(T=>T.id===M)?.deprecated});try{await U.track(c.cwd,{event:"add",properties:{items_count:d.length,registries:Array.from(pe),has_deprecated:x,dependencies_count:I.size,duration_ms:ee}})}catch(l){n&&console.error("[Telemetry] add tracking failed:",l)}}catch(r){z(r)&&(S.outro(a(r.message)),process.exit(0)),V(r,{defaultMessage:"\uCD94\uAC00\uC5D0 \uC2E4\uD328\uD588\uC5B4\uC694.",defaultHint:"`--verbose` \uC635\uC158\uC73C\uB85C \uC0C1\uC138 \uC624\uB958\uB97C \uD655\uC778\uD574\uBCF4\uC138\uC694.",verbose:n}),process.exit(1)}})};import*as v from"@clack/prompts";import Jt from"path";import{z as Y}from"zod";var Wt=Y.object({registryIds:Y.array(Y.string()).optional(),all:Y.boolean(),includeDeprecated:Y.boolean().optional(),cwd:Y.string(),baseUrl:Y.string().optional(),onDiff:Y.enum(["overwrite","backup"]).optional()}),Be=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:B}).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,s)=>{let o=Date.now(),n=F(s);v.intro("seed-design add-all");try{let r=Wt.safeParse({registryIds:t,...s});if(!r.success)throw r.error;let{data:i}=r,c=i.cwd,m=i.baseUrl,y=await ge(c),C=Jt.resolve(c,y.path),{start:b,stop:h}=v.spinner();b("Registry\uB97C \uAC00\uC838\uC624\uACE0 \uC788\uC5B4\uC694...");let j=await(async()=>{try{let x=await Promise.all((await se({baseUrl:m})).map(async({id:l})=>re({baseUrl:m,registryId:l})));return h("Registry\uB97C \uAC00\uC838\uC654\uC5B4\uC694."),x}catch(x){throw h("Registry\uB97C \uAC00\uC838\uC624\uC9C0 \uBABB\uD588\uC5B4\uC694."),x}})(),f=await(async()=>{if(i.all){let l=j.map(u=>u.id);return v.log.message(`\uBAA8\uB4E0 \uB808\uC9C0\uC2A4\uD2B8\uB9AC\uC758 \uBAA8\uB4E0 \uD56D\uBAA9\uC744 \uCD94\uAC00\uD569\uB2C8\uB2E4: ${a(l.join(", "))}`),l}if(i.registryIds?.length){let l=j.map(u=>u.id);for(let u of i.registryIds)if(!l.includes(u))throw new $({message:`\uB808\uC9C0\uC2A4\uD2B8\uB9AC '${u}'\uB97C \uCC3E\uC744 \uC218 \uC5C6\uC5B4\uC694.`,details:[`\uC0AC\uC6A9 \uAC00\uB2A5\uD55C \uB808\uC9C0\uC2A4\uD2B8\uB9AC: ${l.join(", ")}`]});return v.log.message(`\uC120\uD0DD\uB41C \uB808\uC9C0\uC2A4\uD2B8\uB9AC\uC758 \uBAA8\uB4E0 \uD56D\uBAA9\uC744 \uCD94\uAC00\uD569\uB2C8\uB2E4: ${a(i.registryIds.join(", "))}`),i.registryIds}let x=await v.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:j.filter(({hideFromCLICatalog:l})=>!l).sort((l,u)=>u.items.length-l.items.length).map(l=>{let u=l.items[0]?.id,A=u?`${l.items.length}\uAC1C \uD56D\uBAA9 (${u} \uB4F1)`:`${l.items.length}\uAC1C \uD56D\uBAA9 (\uD56D\uBAA9 \uC5C6\uC74C)`;return{label:l.id,value:l.id,hint:A}})});if(v.isCancel(x))throw new k;return v.log.message(`\uC120\uD0DD\uB41C \uB808\uC9C0\uC2A4\uD2B8\uB9AC\uC758 \uD56D\uBAA9\uC744 \uCD94\uAC00\uD569\uB2C8\uB2E4: ${a(x.join(", "))}`),x})(),g=j.filter(x=>f.includes(x.id)),d=g.flatMap(x=>x.items.filter(l=>l.deprecated?i.includeDeprecated:!0).map(l=>`${x.id}:${l.id}`)),w=g.reduce((x,l)=>x+l.items.filter(u=>u.deprecated).length,0);if(!i.includeDeprecated&&w>0&&v.log.info(`${w}\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.`),!d.length)throw new k("\uCD94\uAC00\uD560 \uD56D\uBAA9\uC774 \uC5C6\uC5B4\uC694.");v.log.message(`\uCD1D ${a(d.length.toString())}\uAC1C\uC758 \uD56D\uBAA9\uC744 \uCD94\uAC00\uD569\uB2C8\uB2E4.`);let{registryItemsToAdd:I,npmDependenciesToAdd:E}=ue({selectedItemKeys:d,publicRegistries:j}),P=ae({publicRegistries:j,itemKeys:I.flatMap(({registryId:x,items:l})=>l.map(u=>`${x}:${u.id}`)),projectPackageVersions:ne(i.cwd)});ce({report:P,title:"\uD604\uC7AC \uD504\uB85C\uC81D\uD2B8 \uBC84\uC804\uACFC \uD638\uD658\uB418\uC9C0 \uC54A\uC744 \uC218 \uC788\uB294 \uC2A4\uB2C8\uD3AB\uC774 \uC788\uC5B4\uC694."}),await he({registryItemsToAdd:I,rootPath:C,cwd:c,baseUrl:m,config:y,onDiff:i.onDiff});let{installed:O,filtered:ee}=await we({cwd:c,deps:Array.from(E)});O.size===0&&v.log.message("\uBAA8\uB4E0 \uC758\uC874\uC131\uC774 \uC774\uBBF8 \uC124\uCE58\uB418\uC5B4 \uC788\uC5B4\uC694."),O.size&&(v.log.message(`\uC758\uC874\uC131 \uC124\uCE58 \uC644\uB8CC: ${a(Array.from(O).join(", "))}`),ee.size&&v.log.message(`\uC124\uCE58\uD558\uC9C0 \uC54A\uC740 \uC758\uC874\uC131 (\uC774\uBBF8 \uC124\uCE58\uB428): ${a(Array.from(ee).join(", "))}`)),v.outro("\uC644\uB8CC\uD588\uC5B4\uC694.");let pe=Date.now()-o;try{await U.track(i.cwd,{event:"add-all",properties:{registries:f,items_count:d.length,include_deprecated:i.includeDeprecated||!1,dependencies_count:E.size,duration_ms:pe}})}catch(x){n&&console.error("[Telemetry] add-all tracking failed:",x)}}catch(r){z(r)&&(v.outro(a(r.message)),process.exit(0)),V(r,{defaultMessage:"\uCD94\uAC00\uC5D0 \uC2E4\uD328\uD588\uC5B4\uC694.",defaultHint:"`--verbose` \uC635\uC158\uC73C\uB85C \uC0C1\uC138 \uC624\uB958\uB97C \uD655\uC778\uD574\uBCF4\uC138\uC694.",verbose:n}),process.exit(1)}})};import*as D from"@clack/prompts";import Ge from"path";import{z as N}from"zod";var Yt=N.object({itemIds:N.array(N.string()).optional(),component:N.union([N.string(),N.array(N.string())]).optional(),all:N.boolean(),registry:N.string().optional(),cwd:N.string(),baseUrl:N.string().optional()});function Xt({itemIds:e,component:t}){let s=r=>r.trim().replace(/\s+/g,"-"),o=(e??[]).map(s).filter(Boolean),n=(Array.isArray(t)?t:[t]).filter(r=>!!r).flatMap(r=>r.split(",")).map(s).filter(Boolean);return Array.from(new Set([...o,...n]))}function Qt({publicRegistries:e,targetInputs:t,defaultRegistry:s}){let o=e.filter(r=>typeof r.id=="string"&&Array.isArray(r.items)).flatMap(r=>r.items.filter(i=>typeof i.id=="string").map(i=>`${r.id}:${i.id}`)),n=new Set;for(let r of t){let i=r.includes(":")?r:s?`${s}:${r}`:(()=>{let c=o.filter(m=>m.endsWith(`:${r}`));if(!c.length)throw new $({message:`${a(r)}: \uD56D\uBAA9\uC744 \uCC3E\uC744 \uC218 \uC5C6\uC5B4\uC694.`,hint:`${a("ui:action-button")}\uCC98\uB7FC registry\uB97C \uD3EC\uD568\uD574\uC11C \uC785\uB825\uD574\uBCF4\uC138\uC694.`});if(c.length>1)throw new $({message:`${a(r)}: \uAC19\uC740 \uC774\uB984\uC758 \uD56D\uBAA9\uC774 \uC5EC\uB7EC \uB808\uC9C0\uC2A4\uD2B8\uB9AC\uC5D0 \uC788\uC5B4\uC694.`,details:c.map(m=>`- ${m}`),hint:`${a("ui:action-button")}\uCC98\uB7FC registry\uB97C \uD3EC\uD568\uD574\uC11C \uC785\uB825\uD574\uBCF4\uC138\uC694.`});return c[0]})();if(!o.includes(i))throw new $({message:`${a(i)}: \uD56D\uBAA9\uC744 \uCC3E\uC744 \uC218 \uC5C6\uC5B4\uC694.`});n.add(i)}return Array.from(n)}var He=e=>{e.command("compat [...item-ids]","check snippet compatibility").option("-c, --component <component>","\uAC80\uC0AC\uD560 \uCEF4\uD3EC\uB10C\uD2B8. \uC5EC\uB7EC \uBC88 \uB610\uB294 \uC27C\uD45C\uB85C \uC9C0\uC815 \uAC00\uB2A5").option("-a, --all","\uBAA8\uB4E0 registry \uD56D\uBAA9\uC744 \uAC80\uC0AC",{default:!1}).option("-r, --registry <registryId>","\uCEF4\uD3EC\uB10C\uD2B8 shorthand \uC785\uB825 \uC2DC \uAE30\uBCF8 registry").option("--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:B}).example("seed-design compat").example("seed-design compat -c action-button").example("seed-design compat ui:action-button ui:alert-dialog").example("seed-design compat --all").action(async(t,s)=>{let o=Date.now(),n=F(s);D.intro("seed-design compat");try{let r=Yt.safeParse({itemIds:t,...s});if(!r.success)throw r.error;let{data:i}=r,{start:c,stop:m}=D.spinner();c("Registry\uB97C \uAC00\uC838\uC624\uACE0 \uC788\uC5B4\uC694...");let y=await(async()=>{try{let g=await Promise.all((await se({baseUrl:i.baseUrl})).map(async({id:d})=>re({baseUrl:i.baseUrl,registryId:d})));return m("Registry\uB97C \uAC00\uC838\uC654\uC5B4\uC694."),g}catch(g){throw m("Registry\uB97C \uAC00\uC838\uC624\uC9C0 \uBABB\uD588\uC5B4\uC694."),g}})(),C=Xt({itemIds:i.itemIds,component:i.component}),b=i.all?y.flatMap(d=>d.items.map(w=>`${d.id}:${w.id}`)):C.length>0?Qt({publicRegistries:y,targetInputs:C,defaultRegistry:i.registry}):le(i.cwd),h=Array.isArray(b)?b:await(async()=>{let g=await b;if(!g)throw new $({message:"seed-design.json \uD30C\uC77C\uC774 \uC5C6\uC5B4 \uC124\uCE58\uB41C \uC2A4\uB2C8\uD3AB \uACBD\uB85C\uB97C \uC54C \uC218 \uC5C6\uC5B4\uC694.",hint:"`seed-design init`\uC73C\uB85C \uC124\uC815\uC744 \uB9CC\uB4E0 \uB4A4 \uC2E4\uD589\uD558\uAC70\uB098, `--all`/`-c`\uB85C \uAC80\uC0AC \uB300\uC0C1\uC744 \uC9C1\uC811 \uC9C0\uC815\uD574\uC8FC\uC138\uC694."});let d=Ge.resolve(i.cwd,g.path),w=Ve({publicRegistries:y,rootPath:d});return w.length?w:(D.log.info(`${a(Ge.relative(i.cwd,d)||g.path)}\uC5D0\uC11C \uC124\uCE58\uB41C \uC2A4\uB2C8\uD3AB\uC744 \uCC3E\uC9C0 \uBABB\uD588\uC5B4\uC694.`),[])})();h.length||(D.outro("\uAC80\uC0AC\uD560 \uC2A4\uB2C8\uD3AB\uC774 \uC5C6\uC5B4\uC694."),process.exit(0));let j=ne(i.cwd),f=ae({publicRegistries:y,itemKeys:h,projectPackageVersions:j});if(D.log.info(`\uAC80\uC0AC \uB300\uC0C1: ${a(f.checkedItemKeys.join(", "))}`),!f.issues.length){D.outro("\uBAA8\uB4E0 \uC2A4\uB2C8\uD3AB\uC774 \uD604\uC7AC @seed-design/react, @seed-design/css\uC640 \uD638\uD658\uB3FC\uC694.");try{await U.track(i.cwd,{event:"compat",properties:{checked_items_count:f.checkedItemKeys.length,incompatible_items_count:0,duration_ms:Date.now()-o}})}catch(g){n&&console.error("[Telemetry] compat tracking failed:",g)}process.exit(0)}ce({report:f,title:"\uD604\uC7AC \uD504\uB85C\uC81D\uD2B8 \uBC84\uC804\uACFC \uD638\uD658\uB418\uC9C0 \uC54A\uB294 \uC2A4\uB2C8\uD3AB\uC744 \uCC3E\uC558\uC5B4\uC694."}),D.log.info("\uD544\uC694\uD55C \uBC84\uC804\uC73C\uB85C @seed-design/react \uB610\uB294 @seed-design/css\uB97C \uB9DE\uCD98 \uB4A4 \uB2E4\uC2DC \uC2E4\uD589\uD574\uBCF4\uC138\uC694."),D.outro("\uD638\uD658\uC131 \uC774\uC288\uAC00 \uC788\uC5B4\uC694.");try{await U.track(i.cwd,{event:"compat",properties:{checked_items_count:f.checkedItemKeys.length,incompatible_items_count:new Set(f.issues.map(g=>g.itemKey)).size,issue_count:f.issues.length,duration_ms:Date.now()-o}})}catch(g){n&&console.error("[Telemetry] compat tracking failed:",g)}process.exit(1)}catch(r){z(r)&&(D.outro(a(r.message)),process.exit(0)),V(r,{defaultMessage:"\uD638\uD658\uC131 \uAC80\uC0AC\uC5D0 \uC2E4\uD328\uD588\uC5B4\uC694.",defaultHint:"`--verbose` \uC635\uC158\uC73C\uB85C \uC0C1\uC138 \uC624\uB958\uB97C \uD655\uC778\uD574\uBCF4\uC138\uC694.",verbose:n}),process.exit(1)}})};import*as R from"@clack/prompts";import{z as xe}from"zod";var Zt="https://raw.githubusercontent.com/daangn/seed-design/refs/heads/dev/docs/registry",es=xe.object({query:xe.string().optional(),baseUrl:xe.string().optional()});function Je(e,t){return`${Zt}/${e}/${t}`}function ts(e,t){let s=`${t}${e.docUrl}`,o=`${t}/llms${e.docUrl}.txt`,n=[e.id,`- docs: ${s}`,`- llms.txt: ${o}`];if(e.snippetKey&&e.snippets&&e.snippets.length>0){let[r]=e.snippetKey.split(":");if(r==="ui"||r==="breeze")if(e.snippets.length===1)n.push(`- snippet: ${Je(r,e.snippets[0].path)}`);else{n.push("- snippet:");for(let i of e.snippets)n.push(` - ${i.label}: ${Je(r,i.path)}`)}}R.log.message(n.join(`
|
|
11
|
+
`))}function ss(e){return e.split("/").map(t=>t.trim()).filter(Boolean)}function rs(e,t){let s=t.toLowerCase();return e.flatMap(o=>o.sections.flatMap(n=>n.items.filter(r=>r.id.toLowerCase().includes(s)||r.title.toLowerCase().includes(s)).map(r=>({item:r,categoryLabel:o.label,sectionLabel:n.label}))))}async function de(e){let t=await R.select({message:"\uD56D\uBAA9\uC744 \uC120\uD0DD\uD574\uC8FC\uC138\uC694",options:e.map(s=>({label:`${s.deprecated?"(deprecated) ":""}${s.title}`,value:s,hint:s.description}))});if(R.isCancel(t))throw new k;return t}async function We(e){let t=await R.select({message:"\uC139\uC158\uC744 \uC120\uD0DD\uD574\uC8FC\uC138\uC694",options:e.map(s=>({label:s.label,value:s,hint:`${s.items.length}\uAC1C \uD56D\uBAA9`}))});if(R.isCancel(t))throw new k;return t}async function is(e){let t=await R.select({message:"\uCE74\uD14C\uACE0\uB9AC\uB97C \uC120\uD0DD\uD574\uC8FC\uC138\uC694",options:e.map(s=>({label:s.label,value:s,hint:`${s.sections.reduce((o,n)=>o+n.items.length,0)}\uAC1C \uD56D\uBAA9`}))});if(R.isCancel(t))throw new k;return t}var Ye=e=>{e.command("docs [query]","\uBB38\uC11C \uB9C1\uD06C, llms.txt \uB9C1\uD06C, \uC2A4\uB2C8\uD3AB \uB9C1\uD06C\uB97C \uC870\uD68C\uD569\uB2C8\uB2E4").option("-u, --baseUrl <baseUrl>",`\uB808\uC9C0\uC2A4\uD2B8\uB9AC\uC758 \uAE30\uBCF8 URL (\uAE30\uBCF8\uAC12: ${B})`,{default:B}).example("seed-design docs").example("seed-design docs action-button").example("seed-design docs react").example("seed-design docs react/components").example("seed-design docs react/components/action-button").action(async(t,s)=>{let o=Date.now(),n=F(s);R.intro("seed-design docs");try{let r=es.safeParse({query:t,...s});if(!r.success)throw r.error;let{data:i}=r,c=i.baseUrl??B,{start:m,stop:y}=R.spinner();m("\uBB38\uC11C \uBAA9\uB85D\uC744 \uAC00\uC838\uC624\uACE0 \uC788\uC5B4\uC694...");let C=await(async()=>{try{let f=await je({baseUrl:c});return y("\uBB38\uC11C \uBAA9\uB85D\uC744 \uAC00\uC838\uC654\uC5B4\uC694."),f}catch(f){throw y("\uBB38\uC11C \uBAA9\uB85D\uC744 \uAC00\uC838\uC624\uC9C0 \uBABB\uD588\uC5B4\uC694."),f}})(),{categories:b}=C,h;if(i.query){let f=ss(i.query),g=b.find(d=>d.id===f[0]);if(g&&f.length>=2){let d=g.sections.find(w=>w.id===f[1]);if(d&&f.length>=3){let w=d.items.find(I=>I.id===f[2]);if(w)h=w;else{let I=f[2].toLowerCase(),E=d.items.filter(P=>P.id.toLowerCase().includes(I)||P.title.toLowerCase().includes(I));if(E.length===0)throw new $({message:`${a(i.query)}: \uBB38\uC11C\uB97C \uCC3E\uC744 \uC218 \uC5C6\uC5B4\uC694.`,hint:`\`seed-design docs ${g.id}/${d.id}\`\uB85C \uBAA9\uB85D\uC744 \uD655\uC778\uD574\uBCF4\uC138\uC694.`});E.length===1?h=E[0]:h=await de(E)}}else if(d)h=await de(d.items);else{let w=f[1].toLowerCase(),I=g.sections.flatMap(E=>E.items.filter(P=>P.id.toLowerCase().includes(w)||P.title.toLowerCase().includes(w)).map(P=>({item:P,sectionLabel:E.label})));if(I.length===0)throw new $({message:`${a(i.query)}: \uBB38\uC11C\uB97C \uCC3E\uC744 \uC218 \uC5C6\uC5B4\uC694.`,hint:`\`seed-design docs ${g.id}\`\uB85C \uBAA9\uB85D\uC744 \uD655\uC778\uD574\uBCF4\uC138\uC694.`});if(I.length===1)h=I[0].item;else{let E=await R.select({message:`${a(f[1])}\uC5D0 \uD574\uB2F9\uD558\uB294 \uD56D\uBAA9\uC744 \uC120\uD0DD\uD574\uC8FC\uC138\uC694`,options:I.map(({item:P,sectionLabel:O})=>({label:`[${O}] ${P.title}`,value:P,hint:P.description}))});if(R.isCancel(E))throw new k;h=E}}}else if(g)if(g.sections.length===1)h=await de(g.sections[0].items);else{let d=await We(g.sections);h=await de(d.items)}else{let d=rs(b,i.query);if(d.length===0)throw new $({message:`${a(i.query)}: \uBB38\uC11C\uB97C \uCC3E\uC744 \uC218 \uC5C6\uC5B4\uC694.`,hint:"`seed-design docs`\uB85C \uC804\uCCB4 \uBAA9\uB85D\uC744 \uD655\uC778\uD574\uBCF4\uC138\uC694."});if(d.length===1)h=d[0].item;else{let w=await R.select({message:`${a(i.query)}\uC5D0 \uD574\uB2F9\uD558\uB294 \uD56D\uBAA9\uC744 \uC120\uD0DD\uD574\uC8FC\uC138\uC694`,options:d.map(({item:I,categoryLabel:E,sectionLabel:P})=>({label:`[${E} > ${P}] ${I.title}`,value:I,hint:I.description}))});if(R.isCancel(w))throw new k;h=w}}}else{let f=await is(b),g;f.sections.length===1?g=f.sections[0]:g=await We(f.sections),h=await de(g.items)}ts(h,c),R.outro("\uC644\uB8CC\uD588\uC5B4\uC694.");let j=Date.now()-o;try{await U.track(process.cwd(),{event:"docs",properties:{query:i.query??null,item_id:h.id,has_snippet:!!(h.snippets&&h.snippets.length>0),duration_ms:j}})}catch(f){n&&console.error("[Telemetry] docs tracking failed:",f)}}catch(r){z(r)&&(R.outro(a(r.message)),process.exit(0)),V(r,{defaultMessage:"\uBB38\uC11C \uC870\uD68C\uC5D0 \uC2E4\uD328\uD588\uC5B4\uC694.",defaultHint:"`--verbose` \uC635\uC158\uC73C\uB85C \uC0C1\uC138 \uC624\uB958\uB97C \uD655\uC778\uD574\uBCF4\uC138\uC694.",verbose:n}),process.exit(1)}})};import*as _ from"@clack/prompts";import{z as be}from"zod";import os from"dedent";var ns=be.object({cwd:be.string(),yes:be.boolean().optional(),default:be.boolean().optional()}),Xe=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.").option("--default","Deprecated. --yes\uC640 \uB3D9\uC77C\uD558\uAC8C \uAE30\uBCF8\uAC12\uC73C\uB85C \uC0DD\uC131\uD569\uB2C8\uB2E4.").action(async t=>{let s=Date.now(),o=F(t);_.intro("seed-design.json \uD30C\uC77C \uC0DD\uC131");try{let n=ns.safeParse(t);if(!n.success)throw n.error;let r=n.data,i=r.yes||r.default,c=i?K:await Se(),{start:m,stop:y}=_.spinner();m("seed-design.json \uD30C\uC77C \uC0DD\uC131\uC911...");let C=await(async()=>{try{return(await fe({cwd:r.cwd,config:c})).relativePath}catch(h){throw y("seed-design.json \uD30C\uC77C \uC0DD\uC131\uC774 \uC911\uB2E8\uB410\uC5B4\uC694."),h}})();y(`seed-design.json \uD30C\uC77C\uC774 ${a(C)}\uC5D0 \uC0DD\uC131\uB410\uC5B4\uC694.`),_.log.info(a("seed-design add {component} \uBA85\uB839\uC5B4\uB85C \uCEF4\uD3EC\uB10C\uD2B8\uB97C \uCD94\uAC00\uD574\uBCF4\uC138\uC694!")),_.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.")),_.note(os(`SEED Design CLI\uB294 \uAC1C\uC120\uC744 \uC704\uD574 \uC775\uBA85 \uC0AC\uC6A9 \uB370\uC774\uD130\uB97C \uC218\uC9D1\uD574\uC694.
|
|
10
12
|
|
|
11
13
|
\uBE44\uD65C\uC131\uD654\uD558\uB824\uBA74:
|
|
12
|
-
\u2022 seed-design.json\uC5D0\uC11C ${
|
|
13
|
-
\u2022 ${
|
|
14
|
+
\u2022 seed-design.json\uC5D0\uC11C ${a('"telemetry": false')}\uB85C \uC124\uC815
|
|
15
|
+
\u2022 ${a("DISABLE_TELEMETRY=true")} \uD658\uACBD \uBCC0\uC218 \uC124\uC815
|
|
14
16
|
|
|
15
|
-
\uC790\uC138\uD55C \uB0B4\uC6A9: https://seed-design.com/react/getting-started/cli/configuration#telemetry`),"Telemetry \uC548\uB0B4"),
|
|
17
|
+
\uC790\uC138\uD55C \uB0B4\uC6A9: https://seed-design.com/react/getting-started/cli/configuration#telemetry`),"Telemetry \uC548\uB0B4"),_.outro("\uC791\uC5C5\uC774 \uC644\uB8CC\uB410\uC5B4\uC694.");let b=Date.now()-s;try{await U.track(r.cwd,{event:"init",properties:{tsx:c.tsx,rsc:c.rsc,telemetry:c.telemetry,yes_option:i,duration_ms:b}})}catch(h){o&&console.error("[Telemetry] init tracking failed:",h)}}catch(n){z(n)&&(_.outro(a(n.message)),process.exit(0)),V(n,{defaultMessage:"seed-design.json \uD30C\uC77C \uC0DD\uC131\uC5D0 \uC2E4\uD328\uD588\uC5B4\uC694.",defaultHint:"`--verbose` \uC635\uC158\uC73C\uB85C \uC0C1\uC138 \uC624\uB958\uB97C \uD655\uC778\uD574\uBCF4\uC138\uC694.",verbose:o}),process.exit(1)}})};import{cac as as}from"cac";var cs="seed-design",J=as(cs);async function ps(){let e=oe();J.option("--verbose","\uC624\uB958 \uC0C1\uC138 \uC815\uBCF4\uB97C \uCD9C\uB825\uD569\uB2C8\uB2E4."),qe(J),Be(J),He(J),Ye(J),Xe(J),J.version(e.version||"1.0.0","-v, --version"),J.help(),J.parse()}ps();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@seed-design/cli",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.3.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -21,7 +21,6 @@
|
|
|
21
21
|
"scripts": {
|
|
22
22
|
"build": "ENV=prod bun ./build.mjs",
|
|
23
23
|
"dev": "ENV=dev bun ./dev.mjs",
|
|
24
|
-
"test": "bun vitest",
|
|
25
24
|
"lint:publish": "bun publint"
|
|
26
25
|
},
|
|
27
26
|
"dependencies": {
|
|
@@ -29,7 +28,7 @@
|
|
|
29
28
|
"@babel/core": "^7.26.10",
|
|
30
29
|
"@babel/parser": "^7.27.0",
|
|
31
30
|
"@babel/plugin-transform-typescript": "^7.27.0",
|
|
32
|
-
"@clack/prompts": "^0.
|
|
31
|
+
"@clack/prompts": "^1.0.0",
|
|
33
32
|
"@npmcli/disparity-colors": "^3.0.1",
|
|
34
33
|
"cac": "^6.7.14",
|
|
35
34
|
"cosmiconfig": "^9.0.0",
|
|
@@ -40,6 +39,7 @@
|
|
|
40
39
|
"fs-extra": "^11.3.0",
|
|
41
40
|
"picocolors": "^1.1.1",
|
|
42
41
|
"recast": "^0.23.11",
|
|
42
|
+
"semver": "^7.7.2",
|
|
43
43
|
"ts-morph": "^27.0.0",
|
|
44
44
|
"zod": "^3.24.3"
|
|
45
45
|
},
|
package/src/AGENTS.md
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
## 디렉토리 개요
|
|
2
|
+
|
|
3
|
+
`packages/cli/src`는 CLI 실행 엔트리, 명령어 구현, 공통 유틸, 테스트를 포함한다. 상위 규칙은 `packages/cli/AGENTS.md`를 따르고, 이 문서는 `src` 내부 구조 전용 컨벤션만 정의한다.
|
|
4
|
+
|
|
5
|
+
## 파일 작성 컨벤션
|
|
6
|
+
|
|
7
|
+
- `commands/`: 사용자가 직접 호출하는 커맨드 액션(`init`, `add`, `add-all`, `compat`)
|
|
8
|
+
- `utils/`: 명령 간 공유 로직(설정, fetch, write, install, analytics, error)
|
|
9
|
+
- `tests/`: 독립 단위 테스트
|
|
10
|
+
- 파일명은 역할 중심 소문자 kebab-case를 유지하고, barrel file은 만들지 않는다.
|
|
11
|
+
|
|
12
|
+
## 코드 작성 컨벤션
|
|
13
|
+
|
|
14
|
+
- 명령어 파일에서 사용자 입출력(`@clack/prompts`)과 종료 코드(`process.exit`)를 최종 처리한다.
|
|
15
|
+
- 유틸 파일은 사이드이펙트 종료 대신 예외를 throw하고, 명령어 계층에서 공통 핸들러로 변환한다.
|
|
16
|
+
- 사용자 취소는 `CliCancelError`, 오류는 `CliError`로 구분한다.
|
|
17
|
+
- 옵션 검증은 zod schema를 명령어 파일 상단에 정의하고 `safeParse/parse`로 검증한다.
|
package/src/commands/add-all.ts
CHANGED
|
@@ -10,6 +10,18 @@ import type { CAC } from "cac";
|
|
|
10
10
|
import { BASE_URL } from "../constants";
|
|
11
11
|
import { analytics } from "../utils/analytics";
|
|
12
12
|
import { highlight } from "../utils/color";
|
|
13
|
+
import {
|
|
14
|
+
analyzeRegistryItemCompatibility,
|
|
15
|
+
getProjectSeedPackageVersionSpecs,
|
|
16
|
+
logCompatibilityReport,
|
|
17
|
+
} from "../utils/compatibility";
|
|
18
|
+
import {
|
|
19
|
+
CliCancelError,
|
|
20
|
+
CliError,
|
|
21
|
+
handleCliError,
|
|
22
|
+
isCliCancelError,
|
|
23
|
+
isVerboseMode,
|
|
24
|
+
} from "../utils/error";
|
|
13
25
|
import { installDependencies } from "../utils/install";
|
|
14
26
|
|
|
15
27
|
const addAllOptionsSchema = z.object({
|
|
@@ -43,131 +55,154 @@ export const addAllCommand = (cli: CAC) => {
|
|
|
43
55
|
.example("seed-design add-all ui lib breeze")
|
|
44
56
|
.action(async (registryIds, opts) => {
|
|
45
57
|
const startTime = Date.now();
|
|
58
|
+
const verbose = isVerboseMode(opts);
|
|
46
59
|
p.intro("seed-design add-all");
|
|
47
60
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
if (!success) {
|
|
55
|
-
p.log.error(`잘못된 옵션이에요: ${error?.message}`);
|
|
56
|
-
|
|
57
|
-
process.exit(1);
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
const cwd = options.cwd;
|
|
61
|
-
const baseUrl = options.baseUrl;
|
|
62
|
-
const config = await getConfig(cwd);
|
|
63
|
-
const rootPath = path.resolve(cwd, config.path);
|
|
61
|
+
try {
|
|
62
|
+
const parsed = addAllOptionsSchema.safeParse({ registryIds, ...opts });
|
|
63
|
+
if (!parsed.success) {
|
|
64
|
+
throw parsed.error;
|
|
65
|
+
}
|
|
64
66
|
|
|
65
|
-
|
|
67
|
+
const { data: options } = parsed;
|
|
66
68
|
|
|
67
|
-
|
|
69
|
+
const cwd = options.cwd;
|
|
70
|
+
const baseUrl = options.baseUrl;
|
|
71
|
+
const config = await getConfig(cwd);
|
|
72
|
+
const rootPath = path.resolve(cwd, config.path);
|
|
68
73
|
|
|
69
|
-
|
|
70
|
-
(
|
|
71
|
-
fetchRegistry({ baseUrl, registryId: id }),
|
|
72
|
-
),
|
|
73
|
-
);
|
|
74
|
+
const { start, stop } = p.spinner();
|
|
75
|
+
start("Registry를 가져오고 있어요...");
|
|
74
76
|
|
|
75
|
-
|
|
77
|
+
const publicRegistries = await (async () => {
|
|
78
|
+
try {
|
|
79
|
+
const registries = await Promise.all(
|
|
80
|
+
(await fetchAvailableRegistries({ baseUrl })).map(async ({ id }) =>
|
|
81
|
+
fetchRegistry({ baseUrl, registryId: id }),
|
|
82
|
+
),
|
|
83
|
+
);
|
|
84
|
+
stop("Registry를 가져왔어요.");
|
|
76
85
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
86
|
+
return registries;
|
|
87
|
+
} catch (error) {
|
|
88
|
+
stop("Registry를 가져오지 못했어요.");
|
|
89
|
+
throw error;
|
|
90
|
+
}
|
|
91
|
+
})();
|
|
81
92
|
|
|
82
|
-
|
|
83
|
-
|
|
93
|
+
const selectedRegistryIds: string[] = await (async () => {
|
|
94
|
+
if (options.all) {
|
|
95
|
+
const ids = publicRegistries.map((r) => r.id);
|
|
96
|
+
p.log.message(`모든 레지스트리의 모든 항목을 추가합니다: ${highlight(ids.join(", "))}`);
|
|
84
97
|
|
|
85
|
-
|
|
86
|
-
|
|
98
|
+
return ids;
|
|
99
|
+
}
|
|
87
100
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
p.log.error(`레지스트리 '${registryId}'를 찾을 수 없어요.`);
|
|
91
|
-
p.log.info(`사용 가능한 레지스트리: ${availableIds.join(", ")}`);
|
|
101
|
+
if (options.registryIds?.length) {
|
|
102
|
+
const availableIds = publicRegistries.map((r) => r.id);
|
|
92
103
|
|
|
93
|
-
|
|
104
|
+
for (const registryId of options.registryIds) {
|
|
105
|
+
if (!availableIds.includes(registryId)) {
|
|
106
|
+
throw new CliError({
|
|
107
|
+
message: `레지스트리 '${registryId}'를 찾을 수 없어요.`,
|
|
108
|
+
details: [`사용 가능한 레지스트리: ${availableIds.join(", ")}`],
|
|
109
|
+
});
|
|
110
|
+
}
|
|
94
111
|
}
|
|
95
|
-
}
|
|
96
112
|
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
113
|
+
p.log.message(
|
|
114
|
+
`선택된 레지스트리의 모든 항목을 추가합니다: ${highlight(options.registryIds.join(", "))}`,
|
|
115
|
+
);
|
|
100
116
|
|
|
101
|
-
|
|
102
|
-
|
|
117
|
+
return options.registryIds;
|
|
118
|
+
}
|
|
103
119
|
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
120
|
+
const selected = await p.multiselect({
|
|
121
|
+
message: "추가할 레지스트리를 선택해주세요 (스페이스 바로 여러 개 선택 가능)",
|
|
122
|
+
options: publicRegistries
|
|
123
|
+
.filter(({ hideFromCLICatalog }) => !hideFromCLICatalog)
|
|
124
|
+
.sort((a, b) => b.items.length - a.items.length)
|
|
125
|
+
.map((registry) => {
|
|
126
|
+
const firstItemId = registry.items[0]?.id;
|
|
127
|
+
const hint = firstItemId
|
|
128
|
+
? `${registry.items.length}개 항목 (${firstItemId} 등)`
|
|
129
|
+
: `${registry.items.length}개 항목 (항목 없음)`;
|
|
130
|
+
|
|
131
|
+
return {
|
|
132
|
+
label: registry.id,
|
|
133
|
+
value: registry.id,
|
|
134
|
+
hint,
|
|
135
|
+
};
|
|
136
|
+
}),
|
|
137
|
+
});
|
|
138
|
+
|
|
139
|
+
if (p.isCancel(selected)) {
|
|
140
|
+
throw new CliCancelError();
|
|
141
|
+
}
|
|
115
142
|
|
|
116
|
-
|
|
117
|
-
p.log.error("취소되었어요.");
|
|
118
|
-
process.exit(0);
|
|
119
|
-
}
|
|
143
|
+
p.log.message(`선택된 레지스트리의 항목을 추가합니다: ${highlight(selected.join(", "))}`);
|
|
120
144
|
|
|
121
|
-
|
|
145
|
+
return selected;
|
|
146
|
+
})();
|
|
122
147
|
|
|
123
|
-
|
|
124
|
-
|
|
148
|
+
const selectedRegistries = publicRegistries.filter((r) =>
|
|
149
|
+
selectedRegistryIds.includes(r.id),
|
|
150
|
+
);
|
|
125
151
|
|
|
126
|
-
|
|
152
|
+
const itemKeys = selectedRegistries.flatMap((registry) =>
|
|
153
|
+
registry.items
|
|
154
|
+
.filter((item) => {
|
|
155
|
+
if (item.deprecated) return options.includeDeprecated;
|
|
127
156
|
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
157
|
+
return true;
|
|
158
|
+
})
|
|
159
|
+
.map((item) => `${registry.id}:${item.id}`),
|
|
160
|
+
);
|
|
132
161
|
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
162
|
+
const deprecatedCount = selectedRegistries.reduce(
|
|
163
|
+
(count, r) => count + r.items.filter((item) => item.deprecated).length,
|
|
164
|
+
0,
|
|
165
|
+
);
|
|
137
166
|
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
167
|
+
if (!options.includeDeprecated && deprecatedCount > 0) {
|
|
168
|
+
p.log.info(
|
|
169
|
+
`${deprecatedCount}개의 deprecated 항목은 제외되었어요. --include-deprecated 옵션을 사용하면 추가할 수 있어요.`,
|
|
170
|
+
);
|
|
171
|
+
}
|
|
141
172
|
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
);
|
|
146
|
-
}
|
|
173
|
+
if (!itemKeys.length) {
|
|
174
|
+
throw new CliCancelError("추가할 항목이 없어요.");
|
|
175
|
+
}
|
|
147
176
|
|
|
148
|
-
|
|
149
|
-
p.log.error("추가할 항목이 없어요.");
|
|
177
|
+
p.log.message(`총 ${highlight(itemKeys.length.toString())}개의 항목을 추가합니다.`);
|
|
150
178
|
|
|
151
|
-
|
|
152
|
-
|
|
179
|
+
const { registryItemsToAdd, npmDependenciesToAdd } = resolveDependencies({
|
|
180
|
+
selectedItemKeys: itemKeys,
|
|
181
|
+
publicRegistries,
|
|
182
|
+
});
|
|
153
183
|
|
|
154
|
-
|
|
184
|
+
const compatibilityReport = analyzeRegistryItemCompatibility({
|
|
185
|
+
publicRegistries,
|
|
186
|
+
itemKeys: registryItemsToAdd.flatMap(({ registryId, items }) =>
|
|
187
|
+
items.map((item) => `${registryId}:${item.id}`),
|
|
188
|
+
),
|
|
189
|
+
projectPackageVersions: getProjectSeedPackageVersionSpecs(options.cwd),
|
|
190
|
+
});
|
|
155
191
|
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
192
|
+
logCompatibilityReport({
|
|
193
|
+
report: compatibilityReport,
|
|
194
|
+
title: "현재 프로젝트 버전과 호환되지 않을 수 있는 스니펫이 있어요.",
|
|
195
|
+
});
|
|
160
196
|
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
197
|
+
await writeRegistryItemSnippets({
|
|
198
|
+
registryItemsToAdd,
|
|
199
|
+
rootPath,
|
|
200
|
+
cwd,
|
|
201
|
+
baseUrl,
|
|
202
|
+
config,
|
|
203
|
+
onDiff: options.onDiff,
|
|
204
|
+
});
|
|
169
205
|
|
|
170
|
-
try {
|
|
171
206
|
const { installed, filtered } = await installDependencies({
|
|
172
207
|
cwd,
|
|
173
208
|
deps: Array.from(npmDependenciesToAdd),
|
|
@@ -188,23 +223,37 @@ export const addAllCommand = (cli: CAC) => {
|
|
|
188
223
|
}
|
|
189
224
|
|
|
190
225
|
p.outro("완료했어요.");
|
|
226
|
+
|
|
227
|
+
// add-all 성공 이벤트 추적
|
|
228
|
+
const duration = Date.now() - startTime;
|
|
229
|
+
try {
|
|
230
|
+
await analytics.track(options.cwd, {
|
|
231
|
+
event: "add-all",
|
|
232
|
+
properties: {
|
|
233
|
+
registries: selectedRegistryIds,
|
|
234
|
+
items_count: itemKeys.length,
|
|
235
|
+
include_deprecated: options.includeDeprecated || false,
|
|
236
|
+
dependencies_count: npmDependenciesToAdd.size,
|
|
237
|
+
duration_ms: duration,
|
|
238
|
+
},
|
|
239
|
+
});
|
|
240
|
+
} catch (telemetryError) {
|
|
241
|
+
if (verbose) {
|
|
242
|
+
console.error("[Telemetry] add-all tracking failed:", telemetryError);
|
|
243
|
+
}
|
|
244
|
+
}
|
|
191
245
|
} catch (error) {
|
|
192
|
-
|
|
193
|
-
|
|
246
|
+
if (isCliCancelError(error)) {
|
|
247
|
+
p.outro(highlight(error.message));
|
|
248
|
+
process.exit(0);
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
handleCliError(error, {
|
|
252
|
+
defaultMessage: "추가에 실패했어요.",
|
|
253
|
+
defaultHint: "`--verbose` 옵션으로 상세 오류를 확인해보세요.",
|
|
254
|
+
verbose,
|
|
255
|
+
});
|
|
194
256
|
process.exit(1);
|
|
195
257
|
}
|
|
196
|
-
|
|
197
|
-
// add-all 성공 이벤트 추적
|
|
198
|
-
const duration = Date.now() - startTime;
|
|
199
|
-
await analytics.track(options.cwd, {
|
|
200
|
-
event: "add-all",
|
|
201
|
-
properties: {
|
|
202
|
-
registries: selectedRegistryIds,
|
|
203
|
-
items_count: itemKeys.length,
|
|
204
|
-
include_deprecated: options.includeDeprecated || false,
|
|
205
|
-
dependencies_count: npmDependenciesToAdd.size,
|
|
206
|
-
duration_ms: duration,
|
|
207
|
-
},
|
|
208
|
-
});
|
|
209
258
|
});
|
|
210
259
|
};
|