@seed-design/cli 1.2.1 → 1.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/index.mjs +11 -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/init.ts +56 -67
- package/src/index.ts +4 -0
- package/src/schema.ts +15 -2
- package/src/tests/compatibility.test.ts +148 -0
- package/src/tests/resolve-dependencies.test.ts +1 -1
- package/src/utils/analytics.ts +2 -2
- package/src/utils/compatibility.ts +291 -0
- package/src/utils/error.ts +160 -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,16 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import*as
|
|
3
|
-
${
|
|
4
|
-
|
|
5
|
-
${
|
|
6
|
-
`),
|
|
2
|
+
import*as W from"@clack/prompts";import{cosmiconfig as We}from"cosmiconfig";import{z as Q}from"zod";import*as F from"@clack/prompts";import{ZodError as Ge}from"zod";import Be from"picocolors";var a=e=>Be.cyan(e);var x=class extends Error{hint;details;constructor({message:t,hint:r,details:s=[],cause:n}){super(t,{cause:n}),this.name="CliError",this.hint=r,this.details=s}},E=class extends Error{constructor(t="\uC791\uC5C5\uC774 \uCDE8\uC18C\uB410\uC5B4\uC694."){super(t),this.name="CliCancelError"}};function U(e){return e instanceof E}function L(e){return!e||typeof e!="object"||!("verbose"in e)?!1:e.verbose===!0}function He(e,t){if(e instanceof x)return{reason:e.message,hint:e.hint??t,details:e.details,stack:qe(e.cause??e)};if(e instanceof Ge){let r=e.issues.map(s=>`${s.path.join(".")||"(root)"}: ${s.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:r,stack:e.stack}}if(e instanceof Error){let r=e,s=[];return(r.escapedCommand||r.command)&&s.push(`\uC2E4\uD589 \uBA85\uB839\uC5B4: ${r.escapedCommand??r.command}`),typeof r.exitCode=="number"&&s.push(`\uC885\uB8CC \uCF54\uB4DC: ${r.exitCode}`),r.stderr?.trim()?s.push(`stderr: ${r.stderr.trim()}`):r.stdout?.trim()&&s.push(`stdout: ${r.stdout.trim()}`),{reason:r.shortMessage??e.message,hint:t,details:s,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 qe(e){if(e instanceof Error)return e.stack}function B(e,{defaultMessage:t,defaultHint:r,verbose:s=!1}){let n=He(e,r);F.log.error(t),F.log.error(`\uC6D0\uC778: ${n.reason}`);for(let i of n.details)F.log.info(i);n.hint&&F.log.info(`\uD574\uACB0 \uD78C\uD2B8: ${n.hint}`),s&&n.stack&&(F.log.message(a(`
|
|
3
|
+
[verbose] stack trace`)),F.log.message(n.stack)),F.outro(a("\uC791\uC5C5\uC5D0 \uC2E4\uD328\uD588\uC5B4\uC694."))}import*as G from"@clack/prompts";import Je from"fs-extra";import Ce from"path";var _={rsc:!1,tsx:!0,path:"./seed-design",telemetry:!0};async function $e(){return await G.group({tsx:()=>G.confirm({message:`${a("TypeScript")}\uB97C \uC0AC\uC6A9\uC911\uC774\uC2E0\uAC00\uC694?`,initialValue:_.tsx}),rsc:()=>G.confirm({message:`${a("React Server Components")}\uB97C \uC0AC\uC6A9\uC911\uC774\uC2E0\uAC00\uC694?`,initialValue:_.rsc}),path:()=>G.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:_.path,defaultValue:_.path,placeholder:_.path}),telemetry:()=>G.confirm({message:`\uAC1C\uC120\uC744 \uC704\uD574 ${a("\uC775\uBA85 \uC0AC\uC6A9 \uB370\uC774\uD130")}\uB97C \uC218\uC9D1\uD560\uAE4C\uC694?`,initialValue:_.telemetry})},{onCancel:()=>{throw new E}})}async function me({cwd:e,config:t}){let r=Ce.resolve(e,"seed-design.json");return await Je.writeFile(r,`${JSON.stringify(t,null,2)}
|
|
4
|
+
`,"utf-8"),{relativePath:Ce.relative(process.cwd(),r),targetPath:r}}var Pe="seed-design",Ye=We(Pe,{searchPlaces:[`${Pe}.json`]}),xe=Q.object({$schema:Q.string().optional(),rsc:Q.coerce.boolean().default(!1),tsx:Q.coerce.boolean().default(!0),path:Q.string(),telemetry:Q.coerce.boolean().optional().default(!0)}).strict();async function de(e){let t=await pe(e);if(t)return t;W.log.error("\uD504\uB85C\uC81D\uD2B8 \uB8E8\uD2B8 \uACBD\uB85C\uC5D0 `seed-design.json` \uD30C\uC77C\uC774 \uC5C6\uC5B4\uC694.");let r=await W.confirm({message:"seed-design.json \uD30C\uC77C\uC744 \uC0DD\uC131\uD558\uC2DC\uACA0\uC5B4\uC694?"});if(W.isCancel(r)||!r)throw new E;try{return await me({cwd:e,config:_}),W.log.message("seed-design.json \uD30C\uC77C\uC774 \uC0DD\uC131\uB410\uC5B4\uC694."),xe.parse(_)}catch(s){throw new x({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:s})}}async function pe(e){let t=await Ye.search(e);if(!t||t.isEmpty)return null;try{return xe.parse(t.config)}catch(r){throw new x({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:r})}}function fe({selectedItemKeys:e,publicRegistries:t}){let r=[],s=new Set;function n(i,o){let c=r.find(l=>l.registryId===i);if(!c?.items.some(l=>l.id===o.id)){if(c?c.items.push(o):r.push({registryId:i,items:[o]}),o.dependencies?.length)for(let l of o.dependencies)s.add(l);if(o.innerDependencies?.length)for(let l of o.innerDependencies)for(let d of l.itemIds){let h=t.find(b=>b.id===l.registryId)?.items.find(b=>b.id===d);if(!h)throw new Error(`Cannot find dependency item: ${l.registryId}:${d}`);n(l.registryId,h)}}}for(let i of e){let[o,...c]=i.split(":"),l=c.join(":");if(!o||!l)throw new Error(`Invalid snippet format: "${i}"`);let d=t.find(h=>h.id===o)?.items.find(h=>h.id===l);if(!d)throw new Error(`Cannot find snippet: "${i}"`);n(o,d)}return{registryItemsToAdd:r,npmDependenciesToAdd:s}}import*as Ie from"@clack/prompts";import{z as u}from"zod";var we=u.object({id:u.string(),description:u.string().optional(),deprecated:u.boolean().optional(),hideFromCLICatalog:u.boolean().optional(),dependencies:u.array(u.string()).optional(),innerDependencies:u.array(u.object({registryId:u.string(),itemIds:u.array(u.string())})).optional(),snippets:u.array(u.object({path:u.string(),dependencies:u.record(u.string(),u.string()).optional(),content:u.string()}))}),be=u.object({id:u.string(),hideFromCLICatalog:u.boolean().optional(),items:u.array(we.omit({snippets:!0}).extend({snippets:u.array(u.object({path:u.string(),dependencies:u.record(u.string(),u.string()).optional()}))}))}),Re=u.array(u.object({id:u.string()}));async function ee({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 r=await t.json(),{success:s,data:n,error:i}=Re.safeParse(r);if(!s)throw new Error(`Failed to parse registries: ${i?.message}`);return n}async function te({baseUrl:e,registryId:t}){let r=await fetch(`${e}/__registry__/${t}/index.json`);if(!r.ok)throw new Error(`Failed to fetch ${t} registry: ${r.status} ${r.statusText}`);let s=await r.json(),{success:n,data:i,error:o}=be.safeParse(s);if(!n)throw new Error(`Failed to parse ${t} registry: ${o?.message}`);return i}async function Xe({baseUrl:e,registryId:t,registryItemId:r}){let s=await fetch(`${e}/__registry__/${t}/${r}.json`);if(!s.ok)throw new Error(`Failed to fetch ${r}: ${s.status} ${s.statusText}`);let n=await s.json(),{success:i,data:o,error:c}=we.safeParse(n);if(!i)throw new Error(`Failed to parse ${r}: ${c?.message}`);return o}async function ke({baseUrl:e,registryId:t,registryItemIds:r}){return await Promise.all(r.map(async s=>{try{return await Xe({baseUrl:e,registryId:t,registryItemId:s})}catch(n){let i=await fetch(`${e}/__registry__/${t}/index.json`);if(!i.ok)throw new Error(`${t} \uB808\uC9C0\uC2A4\uD2B8\uB9AC\uB97C \uAC00\uC838\uC624\uC9C0 \uBABB\uD588\uC5B4\uC694: ${i.status} ${i.statusText}`);let o=await i.json(),{success:c,data:l}=be.safeParse(o);throw c?(Ie.log.error(`${s} \uC2A4\uB2C8\uD3AB\uC774 ${t} \uB808\uC9C0\uC2A4\uD2B8\uB9AC\uC5D0 \uC5C6\uC5B4\uC694.`),Ie.log.info(`${t} \uB808\uC9C0\uC2A4\uD2B8\uB9AC\uC5D0 \uC874\uC7AC\uD558\uB294 \uC2A4\uB2C8\uD3AB:
|
|
5
|
+
${l.items.map(d=>d.id).join(`
|
|
6
|
+
`)}`),n):new Error(`Failed to parse registry index for ${t}`)}}))}import{promises as it}from"fs";import{tmpdir as st}from"os";import ve from"path";import{transformFromAstSync as Ze}from"@babel/core";import Qe from"@babel/plugin-transform-typescript";import*as ge from"recast";import{parse as et}from"@babel/parser";var tt={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"]},Ee=async({sourceFile:e,config:t})=>{let r=e.getFullText();if(t.tsx)return r;let s=ge.parse(r,{parser:{parse:i=>et(i,tt)}}),n=Ze(s,r,{cloneInputAst:!1,code:!1,ast:!0,plugins:[Qe],configFile:!1});if(!n||!n.ast)throw new Error("Failed to transform JSX");return ge.print(n.ast).code};import{SyntaxKind as rt}from"ts-morph";var Se=async({sourceFile:e,config:t})=>{if(t.rsc)return e;let r=e.getFirstChildByKind(rt.ExpressionStatement);if(!r)return e;let s=r.getExpression();if(!s)return e;let n=s.getText().trim();if(n!=='"use client"'&&n!=="'use client'")return e;let i=r.getText(),o=r.getFullText();if(i.trim()===o.trim())return e;let l=o.replace(i,"").replace(/^\s*\n/,"").replace(/\n\s*$/,"");return r.replaceWithText(l),e};import{Project as ot,ScriptKind as nt}from"ts-morph";var at=[Se],ct=new ot({compilerOptions:{}});async function pt(e){let t=await it.mkdtemp(ve.join(st(),"seed-design-"));return ve.join(t,e)}async function Ae(e){let t=await pt(e.filename),r=ct.createSourceFile(t,e.raw,{scriptKind:nt.TSX});for(let s of at)s({sourceFile:r,...e});return await Ee({sourceFile:r,...e})}import*as D from"@clack/prompts";import re from"fs-extra";import M from"path";import{createPatch as lt}from"diff";import mt from"@npmcli/disparity-colors";async function ue({registryItemsToAdd:e,rootPath:t,cwd:r,baseUrl:s,config:n,onDiff:i}){let o=[];for(let{registryId:c,items:l}of e){let d=M.join(t,c);re.ensureDirSync(d);let h=await ke({baseUrl:s,registryId:c,registryItemIds:l.map(b=>b.id)});for(let{id:b,snippets:$}of h){let k=await Promise.all($.map(async f=>{let g=await Ae({filename:f.path,config:n,raw:f.content}),w=M.join(d,f.path);return n.tsx||(w=w.replace(/\.tsx$/,".jsx"),w=w.replace(/\.ts$/,".js")),{filePath:w,content:g,relativePath:M.relative(r,w),name:`${c}:${b}`}})),y=[];for(let f of k){let{filePath:g,content:w,relativePath:v}=f;if(await re.ensureDir(M.dirname(g)),re.existsSync(g)){let J=await re.readFile(g,"utf-8");if(J===w){D.log.info(`${a(v)}: \uC774\uBBF8 \uCD5C\uC2E0 \uC0C1\uD0DC\uC608\uC694.`);continue}let V=M.basename(g),K=M.extname(g),Z=M.basename(g,K),ce=Date.now(),I=`legacy-${Z}-${ce}${K}`,p=await(async()=>{if(i)return i;let m=lt(v,J,w),R=mt(m);return D.log.message(`
|
|
7
|
+
${a(v)}: \uD604\uC7AC \uD30C\uC77C\uACFC \uBC1B\uC73C\uB824\uB294 \uD30C\uC77C\uC758 \uB0B4\uC6A9\uC774 \uB2EC\uB77C\uC694.
|
|
8
|
+
`),D.log.message(R),D.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:`${V} \uB36E\uC5B4\uC4F0\uAE30`},{value:"backup",label:`\uAE30\uC874 \uD30C\uC77C \uB0B4\uC6A9\uC744 ${I}\uC73C\uB85C \uC62E\uAE30\uACE0 ${V} \uBC1B\uAE30`},{value:"skip",label:"\uC0C8 \uD30C\uC77C \uBC1B\uC9C0 \uC54A\uACE0 \uADF8\uB300\uB85C \uB450\uAE30"}]})})();if(D.isCancel(p)||p==="skip"){D.log.info(`${a(v)}: \uD30C\uC77C\uC744 \uBC1B\uC9C0 \uC54A\uACE0 \uAC74\uB108\uB6F0\uC5C8\uC5B4\uC694.`);continue}if(p==="backup"){let m=M.dirname(g),R=M.join(m,I);await re.rename(g,R),D.log.info(`${a(v)}: \uAE30\uC874 \uD30C\uC77C\uC744 ${a(M.relative(r,R))}\uB85C \uC62E\uACBC\uC5B4\uC694.`)}}await re.writeFile(g,w),y.push(f)}if(y.length>0){let f=y.map(({name:g,relativePath:w})=>({name:g,path:w}));o.push(...f),D.log.success(`${a(`${c}:${b}`)} \uAD00\uB828 \uC2A4\uB2C8\uD3AB \uB2E4\uC6B4\uB85C\uB4DC \uC644\uB8CC: ${a(f.map(g=>g.path).join(", "))}`)}}}}import*as C from"@clack/prompts";import Dt from"path";import{z as X}from"zod";var ie="https://seed-design.io";import*as Te from"@clack/prompts";import{execa as ht}from"execa";import{detect as dt}from"@antfu/ni";async function je(e){let t=await dt({programmatic:!0,cwd:e});return t==="yarn@berry"?"yarn":t==="pnpm@6"?"pnpm":t==="bun"?"bun":t==="deno"?"deno":t??"npm"}import ft from"findup-sync";import gt from"fs-extra";var ut="package.json";function yt(e=process.cwd()){let t=ft(ut,{cwd:e});if(!t)throw new Error("No package.json file found in the project.");return t}function se(e=process.cwd()){let t=yt(e);return gt.readJSONSync(t)}async function ye({cwd:e,deps:t,dev:r=!1}){let{start:s,stop:n}=Te.spinner(),i=await je(e),c={...se(e).dependencies},l=new Set(t.filter(y=>!c[y])),d=new Set(t.filter(y=>c[y]));if(!l.size)return{installed:new Set,filtered:l};s("\uC758\uC874\uC131 \uC124\uCE58\uC911...");let $=[i==="npm"?"install":"add",r?"-D":null,...l].filter(Boolean),k=`${i} ${$.join(" ")}`;try{await ht(i,$,{cwd:e})}catch(y){throw n("\uC758\uC874\uC131 \uC124\uCE58\uC5D0 \uC2E4\uD328\uD588\uC5B4\uC694."),new x({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: ${k}`],cause:y})}return n("\uC758\uC874\uC131 \uC124\uCE58\uAC00 \uC644\uB8CC\uB410\uC5B4\uC694."),{installed:l,filtered:d}}import{randomUUID as wt}from"node:crypto";import*as De from"@clack/prompts";var bt="seed_cli";async function It(e){if(process.env.DISABLE_TELEMETRY==="true"||process.env.SEED_DISABLE_TELEMETRY==="true")return!1;try{if((await pe(e))?.telemetry===!1)return!1}catch{}return!0}function Ct(){return wt()}var $t=Ct(),_e=!1;async function Pt(e,{event:t,properties:r={}}){if(!await It(e))return;let n=`${bt}.${t}`;_e||(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)"),_e=!0);try{let i="https://us.i.posthog.com/capture",o={"Content-Type":"application/json"},c={api_key:"phc_seod8HhifElOP1R92KmvsQybrtUmkOTgZBsq0mfCelR",event:n,distinct_id:$t,properties:{...r,$process_person_profile:!1},timestamp:new Date().toISOString()},l=new AbortController,d=setTimeout(()=>l.abort(),5e3);try{await fetch(i,{method:"POST",headers:o,body:JSON.stringify(c),signal:l.signal})}finally{clearTimeout(d)}}catch{}}var z={track:Pt};import*as Y from"@clack/prompts";import xt from"fs-extra";import Rt from"path";import{intersects as kt,satisfies as Et,valid as Me,validRange as Ke}from"semver";var le=["@seed-design/react","@seed-design/css"],Oe="workspace:",St="npm:";function oe(e){try{let t=se(e),r={...t.dependencies,...t.devDependencies,...t.peerDependencies,...t.optionalDependencies},s={};for(let n of le){let i=r[n];typeof i=="string"&&(s[n]=i)}return s}catch{return{}}}function ne({publicRegistries:e,itemKeys:t,projectPackageVersions:r}){let s=Array.from(new Set(t)),n=new Map(e.flatMap(o=>o.items.map(c=>[`${o.id}:${c.id}`,c]))),i=[];for(let o of s){let c=n.get(o);if(!c)continue;let l=vt(c);for(let d of le){let h=Array.from(l[d]??[]);if(!h.length)continue;let b=r[d];if(!b){i.push({itemKey:o,packageName:d,requiredRanges:h,type:"missing-package"});continue}let $=At(b);if(!$){i.push({itemKey:o,packageName:d,requiredRanges:h,installedVersionSpec:b,type:"invalid-version-spec"});continue}h.every(y=>jt({currentVersionSpec:$,requiredRange:y}))||i.push({itemKey:o,packageName:d,requiredRanges:h,installedVersionSpec:b,type:"incompatible-version"})}}return{checkedItemKeys:s,projectPackageVersions:r,issues:i}}function ae({report:e,title:t}){if(!e.issues.length)return;Y.log.warn(t),Y.log.info(`\uD604\uC7AC \uD504\uB85C\uC81D\uD2B8 \uBC84\uC804: ${le.map(s=>`${s}@${a(e.projectPackageVersions[s]??"\uBBF8\uC124\uCE58")}`).join(", ")}`);let r=new Map;for(let s of e.issues){let n=r.get(s.itemKey)??[];n.push(s),r.set(s.itemKey,n)}for(let[s,n]of r.entries()){Y.log.warn(a(s));for(let i of n){let o=i.requiredRanges.join(" | ");if(i.type==="missing-package"){Y.log.info(` - ${i.packageName}: \uD328\uD0A4\uC9C0\uAC00 \uC124\uCE58\uB418\uC5B4 \uC788\uC9C0 \uC54A\uC544\uC694. \uD544\uC694 \uBC94\uC704: ${o}`);continue}if(i.type==="invalid-version-spec"){Y.log.info(` - ${i.packageName}: \uD604\uC7AC \uBC84\uC804 \uD615\uC2DD\uC744 \uD574\uC11D\uD558\uC9C0 \uBABB\uD588\uC5B4\uC694 (${i.installedVersionSpec}). \uD544\uC694 \uBC94\uC704: ${o}`);continue}Y.log.info(` - ${i.packageName}: \uD604\uC7AC ${i.installedVersionSpec}, \uD544\uC694 \uBC94\uC704 ${o}`)}}}function Ne({publicRegistries:e,rootPath:t}){let r=[];for(let s of e)for(let n of s.items)n.snippets.some(o=>Tt(o.path).some(c=>xt.existsSync(Rt.join(t,s.id,c))))&&r.push(`${s.id}:${n.id}`);return r}function vt(e){let t=Object.fromEntries(le.map(r=>[r,new Set]));for(let r of e.snippets)for(let[s,n]of Object.entries(r.dependencies??{}))_t(s)&&t[s].add(n);return t}function At(e){let t=e.trim();if(t.startsWith(Oe)&&(t=t.slice(Oe.length).trim()),t.startsWith(St)){let r=t.split("@").at(-1);if(!r)return null;t=r}return!t||t==="*"?null:Me(t)||Ke(t)?t:null}function jt({currentVersionSpec:e,requiredRange:t}){let r=Ke(t);return r?Me(e)?Et(e,r,{includePrerelease:!0}):kt(e,r,{includePrerelease:!0}):!1}function Tt(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 _t(e){return le.includes(e)}var Ot=X.object({itemIds:X.array(X.string()).optional(),all:X.boolean(),cwd:X.string(),baseUrl:X.string().optional(),onDiff:X.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:ie}).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,r)=>{let s=Date.now(),n=L(r);C.intro("seed-design add");try{let i=Ot.safeParse({itemIds:t,...r});if(!i.success)throw i.error;let{data:{all:o,...c}}=i;if(o)throw new x({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 l=c.cwd,d=c.baseUrl,h=await de(l),b=Dt.resolve(l,h.path),{start:$,stop:k}=C.spinner();$("Registry\uB97C \uAC00\uC838\uC624\uACE0 \uC788\uC5B4\uC694...");let y=await(async()=>{try{let p=await Promise.all((await ee({baseUrl:d})).map(async({id:m})=>te({baseUrl:d,registryId:m})));return k("Registry\uB97C \uAC00\uC838\uC654\uC5B4\uC694."),p}catch(p){throw k("Registry\uB97C \uAC00\uC838\uC624\uC9C0 \uBABB\uD588\uC5B4\uC694."),p}})(),f=await(async()=>{if(c.itemIds?.length)return c.itemIds;let p=await C.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:y.filter(({hideFromCLICatalog:m})=>!m).flatMap(({id:m,items:R})=>R.filter(({hideFromCLICatalog:T})=>!T).sort((T,A)=>T.id.localeCompare(A.id)).map(({id:T,description:A,deprecated:N})=>({label:`${N?"(deprecated) ":""}${a(m)}:${T}`,value:`${m}:${T}`,hint:A,deprecated:N,registryItemCount:R.length}))).sort((m,R)=>m.deprecated!==R.deprecated?m.deprecated?1:-1:R.registryItemCount-m.registryItemCount)});if(C.isCancel(p))throw new E;return p})();if(!f?.length)throw new E("\uCD94\uAC00\uD560 \uD56D\uBAA9\uC774 \uC120\uD0DD\uB418\uC9C0 \uC54A\uC558\uC5B4\uC694.");C.log.message(`\uC120\uD0DD\uB41C \uD56D\uBAA9: ${a(f.join(", "))}`);let g=[];for(let p of f){let[m,...R]=p.split(":"),T=R.join(":");if(!m||!T)throw new x({message:`${a(p)}: \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 A=y.find(N=>N.id===m)?.items.find(N=>N.id===T);if(!A)throw new x({message:`${a(p)}: \uD56D\uBAA9\uC744 \uCC3E\uC744 \uC218 \uC5C6\uC5B4\uC694.`});if(A.deprecated){let N=await C.confirm({message:`${a(A.id)}: deprecated \uB418\uC5C8\uC5B4\uC694. \uCD94\uAC00\uD560\uAE4C\uC694?`,initialValue:!1});if(C.isCancel(N))throw new E;if(N===!1){C.log.info(`${a(A.id)}: \uCD94\uAC00\uD558\uC9C0 \uC54A\uC744\uAC8C\uC694.`);continue}}g.push(p)}let{registryItemsToAdd:w,npmDependenciesToAdd:v}=fe({selectedItemKeys:g,publicRegistries:y}),J=ne({publicRegistries:y,itemKeys:w.flatMap(({registryId:p,items:m})=>m.map(R=>`${p}:${R.id}`)),projectPackageVersions:oe(c.cwd)});ae({report:J,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."}),C.log.info(`\uCD94\uAC00\uD560 \uD56D\uBAA9: ${a(w.map(p=>p.items.map(m=>`${p.registryId}:${m.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
|
-
`,"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.
|
|
10
|
+
\uC124\uCE58\uD560 \uC758\uC874\uC131: ${a(Array.from(v).join(", ")||"\uC5C6\uC74C")}`),await ue({registryItemsToAdd:w,rootPath:b,cwd:l,baseUrl:d,config:h,onDiff:c.onDiff});let{installed:V,filtered:K}=await ye({cwd:l,deps:Array.from(v)});V.size===0&&C.log.message("\uBAA8\uB4E0 \uC758\uC874\uC131\uC774 \uC774\uBBF8 \uC124\uCE58\uB418\uC5B4 \uC788\uC5B4\uC694."),V.size&&(C.log.message(`\uC758\uC874\uC131 \uC124\uCE58 \uC644\uB8CC: ${a(Array.from(V).join(", "))}`),K.size&&C.log.message(`\uC124\uCE58\uD558\uC9C0 \uC54A\uC740 \uC758\uC874\uC131 (\uC774\uBBF8 \uC124\uCE58\uB428): ${a(Array.from(K).join(", "))}`)),C.outro("\uC644\uB8CC\uD588\uC5B4\uC694.");let Z=Date.now()-s,ce=new Set(w.map(p=>p.registryId)),I=f.some(p=>{let[m,...R]=p.split(":"),T=R.join(":");return y.find(A=>A.id===m)?.items.find(A=>A.id===T)?.deprecated});try{await z.track(c.cwd,{event:"add",properties:{items_count:g.length,registries:Array.from(ce),has_deprecated:I,dependencies_count:v.size,duration_ms:Z}})}catch(p){n&&console.error("[Telemetry] add tracking failed:",p)}}catch(i){U(i)&&(C.outro(a(i.message)),process.exit(0)),B(i,{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 P from"@clack/prompts";import Mt from"path";import{z as H}from"zod";var Kt=H.object({registryIds:H.array(H.string()).optional(),all:H.boolean(),includeDeprecated:H.boolean().optional(),cwd:H.string(),baseUrl:H.string().optional(),onDiff:H.enum(["overwrite","backup"]).optional()}),ze=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:ie}).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,r)=>{let s=Date.now(),n=L(r);P.intro("seed-design add-all");try{let i=Kt.safeParse({registryIds:t,...r});if(!i.success)throw i.error;let{data:o}=i,c=o.cwd,l=o.baseUrl,d=await de(c),h=Mt.resolve(c,d.path),{start:b,stop:$}=P.spinner();b("Registry\uB97C \uAC00\uC838\uC624\uACE0 \uC788\uC5B4\uC694...");let k=await(async()=>{try{let I=await Promise.all((await ee({baseUrl:l})).map(async({id:p})=>te({baseUrl:l,registryId:p})));return $("Registry\uB97C \uAC00\uC838\uC654\uC5B4\uC694."),I}catch(I){throw $("Registry\uB97C \uAC00\uC838\uC624\uC9C0 \uBABB\uD588\uC5B4\uC694."),I}})(),y=await(async()=>{if(o.all){let p=k.map(m=>m.id);return P.log.message(`\uBAA8\uB4E0 \uB808\uC9C0\uC2A4\uD2B8\uB9AC\uC758 \uBAA8\uB4E0 \uD56D\uBAA9\uC744 \uCD94\uAC00\uD569\uB2C8\uB2E4: ${a(p.join(", "))}`),p}if(o.registryIds?.length){let p=k.map(m=>m.id);for(let m of o.registryIds)if(!p.includes(m))throw new x({message:`\uB808\uC9C0\uC2A4\uD2B8\uB9AC '${m}'\uB97C \uCC3E\uC744 \uC218 \uC5C6\uC5B4\uC694.`,details:[`\uC0AC\uC6A9 \uAC00\uB2A5\uD55C \uB808\uC9C0\uC2A4\uD2B8\uB9AC: ${p.join(", ")}`]});return P.log.message(`\uC120\uD0DD\uB41C \uB808\uC9C0\uC2A4\uD2B8\uB9AC\uC758 \uBAA8\uB4E0 \uD56D\uBAA9\uC744 \uCD94\uAC00\uD569\uB2C8\uB2E4: ${a(o.registryIds.join(", "))}`),o.registryIds}let I=await P.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:k.filter(({hideFromCLICatalog:p})=>!p).sort((p,m)=>m.items.length-p.items.length).map(p=>{let m=p.items[0]?.id,R=m?`${p.items.length}\uAC1C \uD56D\uBAA9 (${m} \uB4F1)`:`${p.items.length}\uAC1C \uD56D\uBAA9 (\uD56D\uBAA9 \uC5C6\uC74C)`;return{label:p.id,value:p.id,hint:R}})});if(P.isCancel(I))throw new E;return P.log.message(`\uC120\uD0DD\uB41C \uB808\uC9C0\uC2A4\uD2B8\uB9AC\uC758 \uD56D\uBAA9\uC744 \uCD94\uAC00\uD569\uB2C8\uB2E4: ${a(I.join(", "))}`),I})(),f=k.filter(I=>y.includes(I.id)),g=f.flatMap(I=>I.items.filter(p=>p.deprecated?o.includeDeprecated:!0).map(p=>`${I.id}:${p.id}`)),w=f.reduce((I,p)=>I+p.items.filter(m=>m.deprecated).length,0);if(!o.includeDeprecated&&w>0&&P.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.`),!g.length)throw new E("\uCD94\uAC00\uD560 \uD56D\uBAA9\uC774 \uC5C6\uC5B4\uC694.");P.log.message(`\uCD1D ${a(g.length.toString())}\uAC1C\uC758 \uD56D\uBAA9\uC744 \uCD94\uAC00\uD569\uB2C8\uB2E4.`);let{registryItemsToAdd:v,npmDependenciesToAdd:J}=fe({selectedItemKeys:g,publicRegistries:k}),V=ne({publicRegistries:k,itemKeys:v.flatMap(({registryId:I,items:p})=>p.map(m=>`${I}:${m.id}`)),projectPackageVersions:oe(o.cwd)});ae({report:V,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 ue({registryItemsToAdd:v,rootPath:h,cwd:c,baseUrl:l,config:d,onDiff:o.onDiff});let{installed:K,filtered:Z}=await ye({cwd:c,deps:Array.from(J)});K.size===0&&P.log.message("\uBAA8\uB4E0 \uC758\uC874\uC131\uC774 \uC774\uBBF8 \uC124\uCE58\uB418\uC5B4 \uC788\uC5B4\uC694."),K.size&&(P.log.message(`\uC758\uC874\uC131 \uC124\uCE58 \uC644\uB8CC: ${a(Array.from(K).join(", "))}`),Z.size&&P.log.message(`\uC124\uCE58\uD558\uC9C0 \uC54A\uC740 \uC758\uC874\uC131 (\uC774\uBBF8 \uC124\uCE58\uB428): ${a(Array.from(Z).join(", "))}`)),P.outro("\uC644\uB8CC\uD588\uC5B4\uC694.");let ce=Date.now()-s;try{await z.track(o.cwd,{event:"add-all",properties:{registries:y,items_count:g.length,include_deprecated:o.includeDeprecated||!1,dependencies_count:J.size,duration_ms:ce}})}catch(I){n&&console.error("[Telemetry] add-all tracking failed:",I)}}catch(i){U(i)&&(P.outro(a(i.message)),process.exit(0)),B(i,{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 S from"@clack/prompts";import Ve from"path";import{z as O}from"zod";var Nt=O.object({itemIds:O.array(O.string()).optional(),component:O.union([O.string(),O.array(O.string())]).optional(),all:O.boolean(),registry:O.string().optional(),cwd:O.string(),baseUrl:O.string().optional()});function Ft({itemIds:e,component:t}){let r=i=>i.trim().replace(/\s+/g,"-"),s=(e??[]).map(r).filter(Boolean),n=(Array.isArray(t)?t:[t]).filter(i=>!!i).flatMap(i=>i.split(",")).map(r).filter(Boolean);return Array.from(new Set([...s,...n]))}function zt({publicRegistries:e,targetInputs:t,defaultRegistry:r}){let s=e.filter(i=>typeof i.id=="string"&&Array.isArray(i.items)).flatMap(i=>i.items.filter(o=>typeof o.id=="string").map(o=>`${i.id}:${o.id}`)),n=new Set;for(let i of t){let o=i.includes(":")?i:r?`${r}:${i}`:(()=>{let c=s.filter(l=>l.endsWith(`:${i}`));if(!c.length)throw new x({message:`${a(i)}: \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 x({message:`${a(i)}: \uAC19\uC740 \uC774\uB984\uC758 \uD56D\uBAA9\uC774 \uC5EC\uB7EC \uB808\uC9C0\uC2A4\uD2B8\uB9AC\uC5D0 \uC788\uC5B4\uC694.`,details:c.map(l=>`- ${l}`),hint:`${a("ui:action-button")}\uCC98\uB7FC registry\uB97C \uD3EC\uD568\uD574\uC11C \uC785\uB825\uD574\uBCF4\uC138\uC694.`});return c[0]})();if(!s.includes(o))throw new x({message:`${a(o)}: \uD56D\uBAA9\uC744 \uCC3E\uC744 \uC218 \uC5C6\uC5B4\uC694.`});n.add(o)}return Array.from(n)}var Ue=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:ie}).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,r)=>{let s=Date.now(),n=L(r);S.intro("seed-design compat");try{let i=Nt.safeParse({itemIds:t,...r});if(!i.success)throw i.error;let{data:o}=i,{start:c,stop:l}=S.spinner();c("Registry\uB97C \uAC00\uC838\uC624\uACE0 \uC788\uC5B4\uC694...");let d=await(async()=>{try{let f=await Promise.all((await ee({baseUrl:o.baseUrl})).map(async({id:g})=>te({baseUrl:o.baseUrl,registryId:g})));return l("Registry\uB97C \uAC00\uC838\uC654\uC5B4\uC694."),f}catch(f){throw l("Registry\uB97C \uAC00\uC838\uC624\uC9C0 \uBABB\uD588\uC5B4\uC694."),f}})(),h=Ft({itemIds:o.itemIds,component:o.component}),b=o.all?d.flatMap(g=>g.items.map(w=>`${g.id}:${w.id}`)):h.length>0?zt({publicRegistries:d,targetInputs:h,defaultRegistry:o.registry}):pe(o.cwd),$=Array.isArray(b)?b:await(async()=>{let f=await b;if(!f)throw new x({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 g=Ve.resolve(o.cwd,f.path),w=Ne({publicRegistries:d,rootPath:g});return w.length?w:(S.log.info(`${a(Ve.relative(o.cwd,g)||f.path)}\uC5D0\uC11C \uC124\uCE58\uB41C \uC2A4\uB2C8\uD3AB\uC744 \uCC3E\uC9C0 \uBABB\uD588\uC5B4\uC694.`),[])})();$.length||(S.outro("\uAC80\uC0AC\uD560 \uC2A4\uB2C8\uD3AB\uC774 \uC5C6\uC5B4\uC694."),process.exit(0));let k=oe(o.cwd),y=ne({publicRegistries:d,itemKeys:$,projectPackageVersions:k});if(S.log.info(`\uAC80\uC0AC \uB300\uC0C1: ${a(y.checkedItemKeys.join(", "))}`),!y.issues.length){S.outro("\uBAA8\uB4E0 \uC2A4\uB2C8\uD3AB\uC774 \uD604\uC7AC @seed-design/react, @seed-design/css\uC640 \uD638\uD658\uB3FC\uC694.");try{await z.track(o.cwd,{event:"compat",properties:{checked_items_count:y.checkedItemKeys.length,incompatible_items_count:0,duration_ms:Date.now()-s}})}catch(f){n&&console.error("[Telemetry] compat tracking failed:",f)}process.exit(0)}ae({report:y,title:"\uD604\uC7AC \uD504\uB85C\uC81D\uD2B8 \uBC84\uC804\uACFC \uD638\uD658\uB418\uC9C0 \uC54A\uB294 \uC2A4\uB2C8\uD3AB\uC744 \uCC3E\uC558\uC5B4\uC694."}),S.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."),S.outro("\uD638\uD658\uC131 \uC774\uC288\uAC00 \uC788\uC5B4\uC694.");try{await z.track(o.cwd,{event:"compat",properties:{checked_items_count:y.checkedItemKeys.length,incompatible_items_count:new Set(y.issues.map(f=>f.itemKey)).size,issue_count:y.issues.length,duration_ms:Date.now()-s}})}catch(f){n&&console.error("[Telemetry] compat tracking failed:",f)}process.exit(1)}catch(i){U(i)&&(S.outro(a(i.message)),process.exit(0)),B(i,{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 j from"@clack/prompts";import{z as he}from"zod";import Vt from"dedent";var Ut=he.object({cwd:he.string(),yes:he.boolean().optional(),default:he.boolean().optional()}),Le=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 r=Date.now(),s=L(t);j.intro("seed-design.json \uD30C\uC77C \uC0DD\uC131");try{let n=Ut.safeParse(t);if(!n.success)throw n.error;let i=n.data,o=i.yes||i.default,c=o?_:await $e(),{start:l,stop:d}=j.spinner();l("seed-design.json \uD30C\uC77C \uC0DD\uC131\uC911...");let h=await(async()=>{try{return(await me({cwd:i.cwd,config:c})).relativePath}catch($){throw d("seed-design.json \uD30C\uC77C \uC0DD\uC131\uC774 \uC911\uB2E8\uB410\uC5B4\uC694."),$}})();d(`seed-design.json \uD30C\uC77C\uC774 ${a(h)}\uC5D0 \uC0DD\uC131\uB410\uC5B4\uC694.`),j.log.info(a("seed-design add {component} \uBA85\uB839\uC5B4\uB85C \uCEF4\uD3EC\uB10C\uD2B8\uB97C \uCD94\uAC00\uD574\uBCF4\uC138\uC694!")),j.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.")),j.note(Vt(`SEED Design CLI\uB294 \uAC1C\uC120\uC744 \uC704\uD574 \uC775\uBA85 \uC0AC\uC6A9 \uB370\uC774\uD130\uB97C \uC218\uC9D1\uD574\uC694.
|
|
10
11
|
|
|
11
12
|
\uBE44\uD65C\uC131\uD654\uD558\uB824\uBA74:
|
|
12
|
-
\u2022 seed-design.json\uC5D0\uC11C ${
|
|
13
|
-
\u2022 ${
|
|
13
|
+
\u2022 seed-design.json\uC5D0\uC11C ${a('"telemetry": false')}\uB85C \uC124\uC815
|
|
14
|
+
\u2022 ${a("DISABLE_TELEMETRY=true")} \uD658\uACBD \uBCC0\uC218 \uC124\uC815
|
|
14
15
|
|
|
15
|
-
\uC790\uC138\uD55C \uB0B4\uC6A9: https://seed-design.com/react/getting-started/cli/configuration#telemetry`),"Telemetry \uC548\uB0B4"),
|
|
16
|
+
\uC790\uC138\uD55C \uB0B4\uC6A9: https://seed-design.com/react/getting-started/cli/configuration#telemetry`),"Telemetry \uC548\uB0B4"),j.outro("\uC791\uC5C5\uC774 \uC644\uB8CC\uB410\uC5B4\uC694.");let b=Date.now()-r;try{await z.track(i.cwd,{event:"init",properties:{tsx:c.tsx,rsc:c.rsc,telemetry:c.telemetry,yes_option:o,duration_ms:b}})}catch($){s&&console.error("[Telemetry] init tracking failed:",$)}}catch(n){U(n)&&(j.outro(a(n.message)),process.exit(0)),B(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:s}),process.exit(1)}})};import{cac as Lt}from"cac";var Bt="seed-design",q=Lt(Bt);async function Gt(){let e=se();q.option("--verbose","\uC624\uB958 \uC0C1\uC138 \uC815\uBCF4\uB97C \uCD9C\uB825\uD569\uB2C8\uB2E4."),Fe(q),ze(q),Ue(q),Le(q),q.version(e.version||"1.0.0","-v, --version"),q.help(),q.parse()}Gt();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@seed-design/cli",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.2",
|
|
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
|
};
|