@seed-design/cli 0.0.0-alpha-20241101030717 → 0.0.0-alpha-20241113031935

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/bin/index.mjs CHANGED
@@ -1,3 +1,3 @@
1
1
  #!/usr/bin/env node
2
- import{cosmiconfig as ee}from"cosmiconfig";import j from"path";import{z as g}from"zod";var $="seed-design",oe=ee($,{searchPlaces:[`${$}.json`]}),T=g.object({$schema:g.string().optional(),rsc:g.coerce.boolean().default(!1),tsx:g.coerce.boolean().default(!0),css:g.coerce.boolean().default(!0),path:g.string()}).strict(),ne=T.extend({resolvedUIPaths:g.string()});async function A(e){let n=await re(e);return n?await te(e,n):null}async function te(e,n){let t=j.resolve(e,n.path);return ne.parse({...n,resolvedUIPaths:j.join(t,"ui")})}async function re(e){try{let n=await oe.search(e);return n?T.parse(n.config):null}catch(n){throw console.log(n),new Error(`Invalid configuration found in ${e}/seed-design.json.`)}}import{z as c}from"zod";var M=c.object({name:c.string(),description:c.string().optional(),dependencies:c.array(c.string()).optional(),devDependencies:c.array(c.string()).optional(),innerDependencies:c.array(c.string()).optional(),files:c.array(c.string())}),O=c.array(M),ie=M.omit({files:!0}),ce=ie.extend({registries:c.array(c.object({name:c.string(),content:c.string()}))}),ze=c.array(ce);var k="https://v3.seed-design.io";async function b(e){try{return await Promise.all(e.map(async t=>await(await fetch(`${k}/__registry__/component/${t}.json`)).json()))}catch(n){throw console.log(n),new Error(`Failed to fetch registry from ${k}.`)}}async function F(){try{let[e]=await b(["index"]);return O.parse(e)}catch(e){throw console.log(e),new Error(`Failed to fetch components from ${k}.`)}}import{detect as se}from"@antfu/ni";async function D(e){let n=await se({programmatic:!0,cwd:e});return n==="yarn@berry"?"yarn":n==="pnpm@6"?"pnpm":n==="bun"?"bun":n??"npm"}import{promises as de}from"fs";import{tmpdir as fe}from"os";import G from"path";import{transformFromAstSync as ae}from"@babel/core";import pe from"@babel/plugin-transform-typescript";import*as v from"recast";import{parse as le}from"@babel/parser";var me={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"]},E=async({sourceFile:e,config:n})=>{let t=e.getFullText();if(n.tsx)return t;let i=v.parse(t,{parser:{parse:r=>le(r,me)}}),o=ae(i,t,{cloneInputAst:!1,code:!1,ast:!0,plugins:[pe],configFile:!1});if(!o||!o.ast)throw new Error("Failed to transform JSX");return v.print(o.ast).code};import{SyntaxKind as _e}from"ts-morph";var N=async({sourceFile:e,config:n})=>{if(n.rsc)return e;let t=e.getFirstChildByKind(_e.ExpressionStatement);return t?.getText()==='"use client";'&&t.remove(),e};var z=async({sourceFile:e,config:n})=>{if(n.css)return e;let i=e.getImportDeclarations().filter(o=>o.getModuleSpecifierValue().endsWith(".css"));for(let o of i)o.remove();return e};import{Project as ge,ScriptKind as ue}from"ts-morph";var he=[N,z],ye=new ge({compilerOptions:{}});async function we(e){let n=await de.mkdtemp(G.join(fe(),"seed-deisgn-"));return G.join(n,e)}async function J(e){let n=await we(e.filename),t=ye.createSourceFile(n,e.raw,{scriptKind:ue.TSX});for(let i of he)i({sourceFile:t,...e});return await E({sourceFile:t,...e})}import*as s from"@clack/prompts";import{execa as V}from"execa";import S from"fs-extra";import U from"path";import I from"picocolors";import{z as C}from"zod";function L(e,n){let t=new Set;function i(o){if(t.has(o))return;t.add(o);let r=n.find(l=>l.name===o);if(r&&r.innerDependencies)for(let l of r.innerDependencies)i(l)}for(let o of e)i(o);return Array.from(t)}var Ce=C.object({components:C.array(C.string()).optional(),cwd:C.string(),all:C.boolean()}),B=e=>{e.command("add [...components]","add component").option("-a, --all","Add all components",{default:!1}).option("-c, --cwd <cwd>","the working directory. defaults to the current directory.",{default:process.cwd()}).example("seed-design add box-button").example("seed-design add alert-dialog").action(async(n,t)=>{let i=Ce.parse({components:n,...t}),o=a=>I.cyan(a),r=i.cwd;S.existsSync(r)||(s.log.error(`The path ${r} does not exist. Please try again.`),process.exit(1));let l=await F(),d=i.all?l.map(a=>a.name):i.components;if(!i.components?.length&&!i.all){let a=await s.multiselect({message:"Select all components to add",options:l.map(_=>({label:_.name,value:_.name,hint:_.description}))});s.isCancel(a)&&(s.log.error("Aborted."),process.exit(0)),d=a}d?.length||(s.log.error("No components found."),process.exit(0));let y=L(d,l),x=y.filter(a=>!d.includes(a)),w=await A(r),Q=await b(y);s.log.message(`Selection: ${o(d.join(", "))}`),x.length&&s.log.message(`Inner Dependencies: ${o(x.join(", "))} will be also added.`);for(let a of Q){for(let m of a.registries){let f=w.resolvedUIPaths;S.existsSync(f)||await S.mkdir(f,{recursive:!0});let u=U.resolve(f,m.name),Y=await J({filename:m.name,config:w,raw:m.content});w.tsx||(u=u.replace(/\.tsx$/,".jsx"),u=u.replace(/\.ts$/,".js")),await S.writeFile(u,Y);let Z=U.relative(r,u);s.log.info(`Added ${o(m.name)} to ${o(Z)}`)}let _=await D(r),{start:P,stop:R}=s.spinner();if(a.dependencies?.length){P(I.gray("Installing dependencies"));let m=await V(_,[_==="npm"?"install":"add",...a.dependencies],{cwd:r});if(m.failed)console.error(m.all),process.exit(1);else{for(let f of a.dependencies)s.log.info(`- ${f}`);R("Dependencies installed.")}}if(a.devDependencies?.length){P(I.gray("Installing devDependencies"));let m=await V(_,[_==="npm"?"install":"add","-D",...a.devDependencies],{cwd:r});if(m.failed)console.error(m.all),process.exit(1);else{for(let f of a.devDependencies)s.log.info(`- ${f}`);R("Dependencies installed.")}}}s.outro("Components added.")})};import xe from"findup-sync";import ve from"fs-extra";var Se="package.json";function ke(){let e=xe(Se);if(!e)throw new Error("No package.json file found in the project.");return e}function K(){return ve.readJSONSync(ke())}import{cac as Te}from"cac";import*as p from"@clack/prompts";import be from"fs-extra";import W from"path";import Ie from"picocolors";import{z as q}from"zod";var Pe=q.object({cwd:q.string()}),X=e=>{e.command("init","initialize seed-design.json").option("-c, --cwd <cwd>","the working directory. defaults to the current directory.",{default:process.cwd()}).action(async n=>{let t=Pe.parse({...n}),i=w=>Ie.cyan(w),o=await p.group({tsx:()=>p.confirm({message:`Would you like to use ${i("TypeScript")} (recommended)?`,initialValue:!0}),rsc:()=>p.confirm({message:`Are you using ${i("React Server Components")}?`,initialValue:!1}),css:()=>p.confirm({message:`Would you like to use ${i("CSS Modules")}? (If true, CSS import will be added in components)`,initialValue:!0}),path:()=>p.text({message:`Enter the path to your ${i("seed-design directory")}`,initialValue:"./seed-design",defaultValue:"./seed-design",placeholder:"./seed-design"})},{onCancel:()=>{p.cancel("Operation cancelled."),process.exit(0)}}),r={rsc:o.rsc,tsx:o.tsx,css:o.css,path:o.path},{start:l,stop:d}=p.spinner();l("Writing seed-design.json...");let y=W.resolve(t.cwd,"seed-design.json");await be.writeFile(y,`${JSON.stringify(r,null,2)}
3
- `,"utf-8");let x=W.relative(process.cwd(),y);d(`seed-design.json written to ${i(x)}`)})};import Re from"node:fs";var H=e=>{e.command("check-deprecated-icon-files [path]","Check deprecated icon files").action(async n=>{let t=Re.readdirSync(n,{recursive:!0}),i=$e.flatMap(o=>{let r=o.replace("icon_","");return[o,r,o.replace(/_/g,"-"),o.replace(/_/g,""),`${o.replace(/_/g,"")}thin`,`${o.replace(/_/g,"")}regular`,`${o.replace(/_/g,"")}fill`,r.replace(/_/g,"-"),r.replace(/_/g,""),`${r.replace(/_/g,"")}thin`,`${r.replace(/_/g,"")}regular`,`${r.replace(/_/g,"")}fill`]});for(let o of t){if(typeof o!="string"||o.includes("node_modules/"))continue;let r=o.split("/").pop().split(".")[0].toLowerCase();je.every(l=>o.endsWith(l)===!1)||i.includes(r)&&console.log(`Possible deprecated icon file found: ${o}`)}})},je=[".tsx",".jsx",".svg",".png"],$e=["icon_add","icon_add_circle","icon_aeb","icon_ai","icon_android_share","icon_arrow","icon_arrow_downward","icon_arrow_drop_down","icon_arrow_drop_up","icon_arrow_upward","icon_article","icon_backward","icon_bill","icon_bold","icon_bookmark","icon_bookmark_list","icon_calendar","icon_call","icon_call_declined","icon_camera","icon_car","icon_car_around_view","icon_car_blind_spot","icon_car_cruise_control","icon_car_epb","icon_car_heated_seat","icon_car_heated_steering_wheel","icon_car_ldws","icon_car_leather_seat","icon_car_navigation","icon_car_power_trunk","icon_car_rear_camera","icon_car_rear_sensor","icon_car_smart_key","icon_car_ventilation_seat","icon_cart","icon_certification","icon_challenge","icon_chart","icon_chat_bubble_check","icon_chatting","icon_chatting_send","icon_check","icon_check_flower","icon_chevron_left","icon_chevron_right","icon_click","icon_clock","icon_close","icon_cobuying","icon_community","icon_condo","icon_confirmation","icon_confirmation_pay","icon_confirmation_profile","icon_contents","icon_convert","icon_copy","icon_coupon","icon_coupon_download_done","icon_coupon_used","icon_delete_keyboard","icon_delivery","icon_direction","icon_download","icon_edit","icon_emoticon","icon_emoticon_bad","icon_expand","icon_expand_less","icon_expand_more","icon_file","icon_filter02","icon_forward","icon_gender","icon_global","icon_gps","icon_gps_enable","icon_gps_enable2","icon_groupchat_king","icon_handle","icon_hashtag","icon_headphone","icon_heart","icon_help","icon_helpcenter","icon_helper","icon_home","icon_house","icon_housekeeping_book","icon_import","icon_info","icon_interest","icon_interest_list","icon_invite","icon_invite_friend","icon_ios_share","icon_jobs","icon_keyboard_hiding","icon_keyword","icon_laptop","icon_leaf","icon_list","icon_list_card","icon_list_check","icon_list_select","icon_list_thumbnail","icon_location","icon_lock","icon_loudspeaker","icon_map","icon_market","icon_market_check","icon_market_write","icon_mention","icon_menu","icon_mic","icon_mic_off","icon_mission","icon_mobile","icon_money_send","icon_money_won","icon_moon","icon_more_horiz","icon_more_vert","icon_my","icon_my_profile","icon_near_me","icon_newtopic","icon_note","icon_notification","icon_notification_fall","icon_notification_off","icon_order","icon_pause","icon_payment","icon_percent","icon_photo","icon_photo_edit","icon_photo_edit_crop","icon_photo_edit_draw","icon_photo_edit_rotate","icon_photo_several","icon_play","icon_poll","icon_price_won","icon_product","icon_profile","icon_profile_badge","icon_prohibition","icon_pushpin","icon_question_check","icon_redo","icon_refund","icon_remove_circle","icon_reply","icon_reply_mission","icon_reply_re","icon_report","icon_reservation","icon_restaurant","icon_retry","icon_review_star","icon_scanner","icon_search","icon_search_doc","icon_sell","icon_setting","icon_signout","icon_sort","icon_story","icon_story_article","icon_subtract_circle","icon_subtraction","icon_suggest","icon_sun","icon_talkingdown","icon_talkingup","icon_text","icon_thumb_down","icon_thumb_up","icon_toolbox","icon_translate","icon_trash","icon_undo","icon_user_group","icon_video","icon_view_count","icon_view_count_off","icon_volume_off","icon_volume_on","icon_vote","icon_voucher","icon_walk","icon_warning","icon_write","icon_write_frequent_use","icon_write_story"];var Ae="seed-design",h=Te(Ae);async function Me(){let e=K();B(h),X(h),H(h),h.version(e.version||"1.0.0","-v, --version"),h.help(),h.parse()}Me();
2
+ import{cosmiconfig as oe}from"cosmiconfig";import k from"path";import*as M from"@clack/prompts";import{z as d}from"zod";import ne from"picocolors";var j="seed-design",te=oe(j,{searchPlaces:[`${j}.json`]}),$=d.object({$schema:d.string().optional(),rsc:d.coerce.boolean().default(!1),tsx:d.coerce.boolean().default(!0),css:d.coerce.boolean().default(!0),path:d.string()}).strict(),re=$.extend({resolvedUIPaths:d.string(),resolbedHookPaths:d.string(),resolvedUtilPaths:d.string()});async function T(e){let n=await ce(e);return n?await ie(e,n):null}async function ie(e,n){let t=k.resolve(e,n.path);return re.parse({...n,resolvedUIPaths:k.join(t,"ui"),resolbedHookPaths:k.join(t,"hook"),resolvedUtilPaths:k.join(t,"util")})}async function ce(e){try{let n=await te.search(e);return n?$.parse(n.config):(M.log.message(ne.red(`${e} \uACBD\uB85C\uC5D0 seed-design.json \uD30C\uC77C\uC774 \uC5C6\uC2B5\uB2C8\uB2E4.`)),null)}catch(n){throw console.log(n),new Error(`${e} \uACBD\uB85C\uC5D0 seed-design.json \uD30C\uC77C\uC744 \uC77D\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4.`)}}import{z as c}from"zod";var se=c.union([c.literal("ui"),c.literal("hook"),c.literal("util")]),A=c.object({name:c.string(),description:c.string().optional(),dependencies:c.array(c.string()).optional(),devDependencies:c.array(c.string()).optional(),innerDependencies:c.array(c.string()).optional(),files:c.array(c.string())}),G=c.array(A),ae=A.omit({files:!0}),pe=ae.extend({registries:c.array(c.object({name:c.string(),type:se,content:c.string()}))}),He=c.array(pe);var C="https://v3.seed-design.io";async function b(e){try{return await Promise.all(e.map(async t=>await(await fetch(`${C}/__registry__/ui/${t}.json`)).json()))}catch(n){throw console.log(n),new Error(`Failed to fetch registry from ${C}.`)}}async function O(){try{let[e]=await b(["index"]);return G.parse(e)}catch(e){throw console.log(e),new Error(`Failed to fetch components from ${C}.`)}}import{detect as le}from"@antfu/ni";async function z(e){let n=await le({programmatic:!0,cwd:e});return n==="yarn@berry"?"yarn":n==="pnpm@6"?"pnpm":n==="bun"?"bun":n??"npm"}import{promises as ue}from"fs";import{tmpdir as he}from"os";import N from"path";import{transformFromAstSync as me}from"@babel/core";import _e from"@babel/plugin-transform-typescript";import*as S from"recast";import{parse as de}from"@babel/parser";var fe={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"]},D=async({sourceFile:e,config:n})=>{let t=e.getFullText();if(n.tsx)return t;let i=S.parse(t,{parser:{parse:r=>de(r,fe)}}),o=me(i,t,{cloneInputAst:!1,code:!1,ast:!0,plugins:[_e],configFile:!1});if(!o||!o.ast)throw new Error("Failed to transform JSX");return S.print(o.ast).code};import{SyntaxKind as ge}from"ts-morph";var E=async({sourceFile:e,config:n})=>{if(n.rsc)return e;let t=e.getFirstChildByKind(ge.ExpressionStatement);return t?.getText()==='"use client";'&&t.remove(),e};var F=async({sourceFile:e,config:n})=>{if(n.css)return e;let i=e.getImportDeclarations().filter(o=>o.getModuleSpecifierValue().endsWith(".css"));for(let o of i)o.remove();return e};import{Project as ye,ScriptKind as we}from"ts-morph";var xe=[E,F],Ie=new ye({compilerOptions:{}});async function ke(e){let n=await ue.mkdtemp(N.join(he(),"seed-deisgn-"));return N.join(n,e)}async function J(e){let n=await ke(e.filename),t=Ie.createSourceFile(n,e.raw,{scriptKind:we.TSX});for(let i of xe)i({sourceFile:t,...e});return await D({sourceFile:t,...e})}import*as s from"@clack/prompts";import{execa as L}from"execa";import v from"fs-extra";import V from"path";import P from"picocolors";import{z as x}from"zod";function H(e,n){let t=new Set;function i(o){if(t.has(o))return;t.add(o);let r=n.find(l=>l.name===o);if(r&&r.innerDependencies)for(let l of r.innerDependencies)i(l)}for(let o of e)i(o);return Array.from(t)}var Se=x.object({components:x.array(x.string()).optional(),cwd:x.string(),all:x.boolean()}),B=e=>{e.command("add [...components]","add component").option("-a, --all","Add all components",{default:!1}).option("-c, --cwd <cwd>","the working directory. defaults to the current directory.",{default:process.cwd()}).example("seed-design add box-button").example("seed-design add alert-dialog").action(async(n,t)=>{let i=Se.parse({components:n,...t}),o=a=>P.cyan(a),r=i.cwd;v.existsSync(r)||(s.log.error(`The path ${r} does not exist. Please try again.`),process.exit(1));let l=await O(),g=i.all?l.map(a=>a.name):i.components;if(!i.components?.length&&!i.all){let a=await s.multiselect({message:"Select all components to add",options:l.map(f=>({label:f.name,value:f.name,hint:f.description}))});s.isCancel(a)&&(s.log.error("Aborted."),process.exit(0)),g=a}g?.length||(s.log.error("No components found."),process.exit(0));let w=H(g,l),I=w.filter(a=>!g.includes(a)),u=await T(r),Y=await b(w);s.log.message(`Selection: ${o(g.join(", "))}`),I.length&&s.log.message(`Inner Dependencies: ${o(I.join(", "))} will be also added.`);for(let a of Y){for(let m of a.registries){let _="";switch(m.type){case"ui":_=u.resolvedUIPaths;break;case"hook":_=u.resolbedHookPaths;break;case"util":_=u.resolvedUtilPaths;break;default:break}v.existsSync(_)||await v.mkdir(_,{recursive:!0});let h=V.resolve(_,m.name),Z=await J({filename:m.name,config:u,raw:m.content});u.tsx||(h=h.replace(/\.tsx$/,".jsx"),h=h.replace(/\.ts$/,".js")),await v.writeFile(h,Z);let ee=V.relative(r,h);s.log.info(`Added ${o(m.name)} to ${o(ee)}`)}let f=await z(r),{start:U,stop:R}=s.spinner();if(a.dependencies?.length){U(P.gray("Installing dependencies"));let m=await L(f,[f==="npm"?"install":"add",...a.dependencies],{cwd:r});if(m.failed)console.error(m.all),process.exit(1);else{for(let _ of a.dependencies)s.log.info(`- ${_}`);R("Dependencies installed.")}}if(a.devDependencies?.length){U(P.gray("Installing devDependencies"));let m=await L(f,[f==="npm"?"install":"add","-D",...a.devDependencies],{cwd:r});if(m.failed)console.error(m.all),process.exit(1);else{for(let _ of a.devDependencies)s.log.info(`- ${_}`);R("Dependencies installed.")}}}s.outro("Components added.")})};import ve from"findup-sync";import Ce from"fs-extra";var be="package.json";function Pe(){let e=ve(be);if(!e)throw new Error("No package.json file found in the project.");return e}function K(){return Ce.readJSONSync(Pe())}import{cac as Ae}from"cac";import*as p from"@clack/prompts";import Ue from"fs-extra";import W from"path";import Re from"picocolors";import{z as q}from"zod";var je=q.object({cwd:q.string()}),X=e=>{e.command("init","initialize seed-design.json").option("-c, --cwd <cwd>","the working directory. defaults to the current directory.",{default:process.cwd()}).action(async n=>{let t=je.parse({...n}),i=u=>Re.cyan(u),o=await p.group({tsx:()=>p.confirm({message:`Would you like to use ${i("TypeScript")} (recommended)?`,initialValue:!0}),rsc:()=>p.confirm({message:`Are you using ${i("React Server Components")}?`,initialValue:!1}),css:()=>p.confirm({message:`Would you like to use ${i("CSS Modules")}? (If true, CSS import will be added in components)`,initialValue:!0}),path:()=>p.text({message:`Enter the path to your ${i("seed-design directory")}`,initialValue:"./seed-design",defaultValue:"./seed-design",placeholder:"./seed-design"})},{onCancel:()=>{p.cancel("Operation cancelled."),process.exit(0)}}),r={rsc:o.rsc,tsx:o.tsx,css:o.css,path:o.path},{start:l,stop:g}=p.spinner();l("Writing seed-design.json...");let w=W.resolve(t.cwd,"seed-design.json");await Ue.writeFile(w,`${JSON.stringify(r,null,2)}
3
+ `,"utf-8");let I=W.relative(process.cwd(),w);g(`seed-design.json written to ${i(I)}`)})};import Me from"node:fs";var Q=e=>{e.command("check-deprecated-icon-files [path]","Check deprecated icon files").action(async n=>{let t=Me.readdirSync(n,{recursive:!0}),i=Te.flatMap(o=>{let r=o.replace("icon_","");return[o,r,o.replace(/_/g,"-"),o.replace(/_/g,""),`${o.replace(/_/g,"")}thin`,`${o.replace(/_/g,"")}regular`,`${o.replace(/_/g,"")}fill`,r.replace(/_/g,"-"),r.replace(/_/g,""),`${r.replace(/_/g,"")}thin`,`${r.replace(/_/g,"")}regular`,`${r.replace(/_/g,"")}fill`]});for(let o of t){if(typeof o!="string"||o.includes("node_modules/"))continue;let r=o.split("/").pop().split(".")[0].toLowerCase();$e.every(l=>o.endsWith(l)===!1)||i.includes(r)&&console.log(`Possible deprecated icon file found: ${o}`)}})},$e=[".tsx",".jsx",".svg",".png"],Te=["icon_add","icon_add_circle","icon_aeb","icon_ai","icon_android_share","icon_arrow","icon_arrow_downward","icon_arrow_drop_down","icon_arrow_drop_up","icon_arrow_upward","icon_article","icon_backward","icon_bill","icon_bold","icon_bookmark","icon_bookmark_list","icon_calendar","icon_call","icon_call_declined","icon_camera","icon_car","icon_car_around_view","icon_car_blind_spot","icon_car_cruise_control","icon_car_epb","icon_car_heated_seat","icon_car_heated_steering_wheel","icon_car_ldws","icon_car_leather_seat","icon_car_navigation","icon_car_power_trunk","icon_car_rear_camera","icon_car_rear_sensor","icon_car_smart_key","icon_car_ventilation_seat","icon_cart","icon_certification","icon_challenge","icon_chart","icon_chat_bubble_check","icon_chatting","icon_chatting_send","icon_check","icon_check_flower","icon_chevron_left","icon_chevron_right","icon_click","icon_clock","icon_close","icon_cobuying","icon_community","icon_condo","icon_confirmation","icon_confirmation_pay","icon_confirmation_profile","icon_contents","icon_convert","icon_copy","icon_coupon","icon_coupon_download_done","icon_coupon_used","icon_delete_keyboard","icon_delivery","icon_direction","icon_download","icon_edit","icon_emoticon","icon_emoticon_bad","icon_expand","icon_expand_less","icon_expand_more","icon_file","icon_filter02","icon_forward","icon_gender","icon_global","icon_gps","icon_gps_enable","icon_gps_enable2","icon_groupchat_king","icon_handle","icon_hashtag","icon_headphone","icon_heart","icon_help","icon_helpcenter","icon_helper","icon_home","icon_house","icon_housekeeping_book","icon_import","icon_info","icon_interest","icon_interest_list","icon_invite","icon_invite_friend","icon_ios_share","icon_jobs","icon_keyboard_hiding","icon_keyword","icon_laptop","icon_leaf","icon_list","icon_list_card","icon_list_check","icon_list_select","icon_list_thumbnail","icon_location","icon_lock","icon_loudspeaker","icon_map","icon_market","icon_market_check","icon_market_write","icon_mention","icon_menu","icon_mic","icon_mic_off","icon_mission","icon_mobile","icon_money_send","icon_money_won","icon_moon","icon_more_horiz","icon_more_vert","icon_my","icon_my_profile","icon_near_me","icon_newtopic","icon_note","icon_notification","icon_notification_fall","icon_notification_off","icon_order","icon_pause","icon_payment","icon_percent","icon_photo","icon_photo_edit","icon_photo_edit_crop","icon_photo_edit_draw","icon_photo_edit_rotate","icon_photo_several","icon_play","icon_poll","icon_price_won","icon_product","icon_profile","icon_profile_badge","icon_prohibition","icon_pushpin","icon_question_check","icon_redo","icon_refund","icon_remove_circle","icon_reply","icon_reply_mission","icon_reply_re","icon_report","icon_reservation","icon_restaurant","icon_retry","icon_review_star","icon_scanner","icon_search","icon_search_doc","icon_sell","icon_setting","icon_signout","icon_sort","icon_story","icon_story_article","icon_subtract_circle","icon_subtraction","icon_suggest","icon_sun","icon_talkingdown","icon_talkingup","icon_text","icon_thumb_down","icon_thumb_up","icon_toolbox","icon_translate","icon_trash","icon_undo","icon_user_group","icon_video","icon_view_count","icon_view_count_off","icon_volume_off","icon_volume_on","icon_vote","icon_voucher","icon_walk","icon_warning","icon_write","icon_write_frequent_use","icon_write_story"];var Ge="seed-design",y=Ae(Ge);async function Oe(){let e=K();B(y),X(y),Q(y),y.version(e.version||"1.0.0","-v, --version"),y.help(),y.parse()}Oe();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@seed-design/cli",
3
- "version": "0.0.0-alpha-20241101030717",
3
+ "version": "0.0.0-alpha-20241113031935",
4
4
  "type": "module",
5
5
  "repository": {
6
6
  "type": "git",
@@ -1,5 +1,5 @@
1
1
  import { getConfig } from "@/src/utils/get-config";
2
- import { fetchRegistryComponentItem, getRegistryComponentIndex } from "@/src/utils/get-metadata";
2
+ import { fetchRegistryUIItem, getRegistryUIIndex } from "@/src/utils/get-metadata";
3
3
  import { getPackageManager } from "@/src/utils/get-package-manager";
4
4
  import { transform } from "@/src/utils/transformers";
5
5
  import * as p from "@clack/prompts";
@@ -45,7 +45,7 @@ export const addCommand = (cli: CAC) => {
45
45
  process.exit(1);
46
46
  }
47
47
 
48
- const registryComponentIndex = await getRegistryComponentIndex();
48
+ const registryComponentIndex = await getRegistryUIIndex();
49
49
 
50
50
  let selectedComponents: string[] = options.all
51
51
  ? registryComponentIndex.map((registry) => registry.name)
@@ -82,7 +82,7 @@ export const addCommand = (cli: CAC) => {
82
82
  const allComponents = addRelativeComponents(selectedComponents, registryComponentIndex);
83
83
  const addedComponents = allComponents.filter((c) => !selectedComponents.includes(c));
84
84
  const config = await getConfig(cwd);
85
- const registryComponentItems = await fetchRegistryComponentItem(allComponents);
85
+ const registryComponentItems = await fetchRegistryUIItem(allComponents);
86
86
 
87
87
  p.log.message(`Selection: ${highlight(selectedComponents.join(", "))}`);
88
88
  if (addedComponents.length) {
@@ -91,15 +91,29 @@ export const addCommand = (cli: CAC) => {
91
91
  );
92
92
  }
93
93
 
94
+ // 선택된 컴포넌트.json 레지스트리 파일 기반으로 컴포넌트를 추가합니다.
94
95
  for (const component of registryComponentItems) {
95
96
  for (const registry of component.registries) {
96
- const UIFolderPath = config.resolvedUIPaths;
97
+ let targetPath = "";
98
+ switch (registry.type) {
99
+ case "ui":
100
+ targetPath = config.resolvedUIPaths;
101
+ break;
102
+ case "hook":
103
+ targetPath = config.resolbedHookPaths;
104
+ break;
105
+ case "util":
106
+ targetPath = config.resolvedUtilPaths;
107
+ break;
108
+ default:
109
+ break;
110
+ }
97
111
 
98
- if (!fs.existsSync(UIFolderPath)) {
99
- await fs.mkdir(UIFolderPath, { recursive: true });
112
+ if (!fs.existsSync(targetPath)) {
113
+ await fs.mkdir(targetPath, { recursive: true });
100
114
  }
101
115
 
102
- let filePath = path.resolve(UIFolderPath, registry.name);
116
+ let filePath = path.resolve(targetPath, registry.name);
103
117
 
104
118
  const content = await transform({
105
119
  filename: registry.name,
package/src/schema.ts CHANGED
@@ -1,10 +1,11 @@
1
+ // TODO: Extract to shared package
1
2
  import { z } from "zod";
2
3
 
3
- // TODO: Extract this to a shared package.
4
- // INFO: also used in docs
5
- export const registryComponentItemSchema = z.object({
4
+ export const registryType = z.union([z.literal("ui"), z.literal("hook"), z.literal("util")]);
5
+
6
+ export const registryUIItemSchema = z.object({
6
7
  /**
7
- * @description 컴포넌트 이름
8
+ * @description 레지스트리 이름
8
9
  * @example chip-tabs, alert-dialog
9
10
  */
10
11
  name: z.string(),
@@ -12,50 +13,67 @@ export const registryComponentItemSchema = z.object({
12
13
  description: z.string().optional(),
13
14
 
14
15
  /**
15
- * @description 컴포넌트 의존성
16
+ * @description 레지스트리 의존성
16
17
  * @example @seed-design/react-tabs
17
18
  */
18
19
  dependencies: z.array(z.string()).optional(),
19
20
 
20
21
  /**
21
- * @description 컴포넌트 개발 의존성
22
+ * @description 레지스트리 개발 의존성
22
23
  */
23
24
  devDependencies: z.array(z.string()).optional(),
24
25
 
25
26
  /**
26
- * @description 컴포넌트 내부의 Seed Design 컴포넌트 의존성
27
+ * @description 레지스트리 내부의 Seed Design 컴포넌트 의존성
27
28
  * @example action-button
28
29
  */
29
30
  innerDependencies: z.array(z.string()).optional(),
30
31
 
31
32
  /**
32
- * @description 컴포넌트 코드 스니펫 경로, 여러 파일이 될 수 있어서 배열로 정의
33
- * @example component/alert-dialog.tsx
33
+ * @description
34
+ * 컴포넌트 코드 스니펫 경로, 여러 파일이 될 수 있어서 배열로 정의
35
+ * `:`를 기준으로 왼쪽은 {registryType}, 오른쪽은 파일 이름
36
+ * @example ui:alert-dialog.tsx
37
+ * @example hook:use-dismissible.ts
34
38
  */
35
39
  files: z.array(z.string()),
36
40
  });
41
+ export const registryUISchema = z.array(registryUIItemSchema);
37
42
 
38
- export const registryComponentSchema = z.array(registryComponentItemSchema);
39
-
40
- const omittedRegistryComponentSchema = registryComponentItemSchema.omit({ files: true });
41
- export const registryComponentItemMachineGeneratedSchema = omittedRegistryComponentSchema.extend({
43
+ /**
44
+ * @description 머신이 생성한 registry component schema
45
+ */
46
+ const omittedRegistryUISchema = registryUIItemSchema.omit({
47
+ files: true,
48
+ });
49
+ export const registryUIItemMachineGeneratedSchema = omittedRegistryUISchema.extend({
42
50
  registries: z.array(
43
51
  z.object({
44
52
  name: z.string(),
53
+ type: registryType,
45
54
  content: z.string(),
46
55
  }),
47
56
  ),
48
57
  });
49
-
50
58
  export const registryComponentMachineGeneratedSchema = z.array(
51
- registryComponentItemMachineGeneratedSchema,
59
+ registryUIItemMachineGeneratedSchema,
52
60
  );
53
61
 
54
- export type RegistryComponentItem = z.infer<typeof registryComponentItemSchema>;
55
- export type RegistryComponent = z.infer<typeof registryComponentSchema>;
56
- export type RegistryComponentItemMachineGenerated = z.infer<
57
- typeof registryComponentItemMachineGeneratedSchema
58
- >;
59
- export type RegistryComponentMachineGenerated = z.infer<
60
- typeof registryComponentMachineGeneratedSchema
61
- >;
62
+ // NOTE: 현재는 hook, util이 ui와 타입이 동일하지만, 따로 가져가야한다면 타입을 변경해야해요.
63
+ export const registryHookItemMachineGeneratedSchema = registryUIItemMachineGeneratedSchema;
64
+ export const registryUtilItemMachineGeneratedSchema = registryUIItemMachineGeneratedSchema;
65
+
66
+ // NOTE: 현재는 hook, util이 ui와 타입이 동일하지만, 따로 가져가야한다면 타입을 변경해야해요.
67
+ export type RegistryUtilItem = z.infer<typeof registryUIItemSchema>;
68
+ export type RegistryUtil = z.infer<typeof registryUISchema>;
69
+ export type RegistryHookItem = z.infer<typeof registryUIItemSchema>;
70
+ export type RegistryHook = z.infer<typeof registryUISchema>;
71
+ export type RegistryUIItem = z.infer<typeof registryUIItemSchema>;
72
+ export type RegistryUI = z.infer<typeof registryUISchema>;
73
+
74
+ export type RegistryUIItemMachineGenerated = z.infer<typeof registryUIItemMachineGeneratedSchema>;
75
+ export type RegistryUIMachineGenerated = z.infer<typeof registryComponentMachineGeneratedSchema>;
76
+ export type RegistryHookItemMachineGenerated = z.infer<typeof registryUIItemMachineGeneratedSchema>;
77
+ export type RegistryHookMachineGenerated = z.infer<typeof registryComponentMachineGeneratedSchema>;
78
+ export type RegistryUtilItemMachineGenerated = z.infer<typeof registryUIItemMachineGeneratedSchema>;
79
+ export type RegistryUtilMachineGenerated = z.infer<typeof registryComponentMachineGeneratedSchema>;
@@ -1,8 +1,8 @@
1
- import type { RegistryComponentMachineGenerated } from "@/src/schema";
1
+ import type { RegistryUIMachineGenerated } from "@/src/schema";
2
2
 
3
3
  export function addRelativeComponents(
4
4
  userSelects: string[],
5
- registryIndex: RegistryComponentMachineGenerated,
5
+ registryIndex: RegistryUIMachineGenerated,
6
6
  ) {
7
7
  const selectedComponents = new Set<string>();
8
8
 
@@ -1,6 +1,8 @@
1
1
  import { cosmiconfig } from "cosmiconfig";
2
2
  import path from "path";
3
+ import * as p from "@clack/prompts";
3
4
  import { z } from "zod";
5
+ import color from "picocolors";
4
6
 
5
7
  const MODULE_NAME = "seed-design";
6
8
 
@@ -22,6 +24,8 @@ export type RawConfig = z.infer<typeof rawConfigSchema>;
22
24
 
23
25
  export const configSchema = rawConfigSchema.extend({
24
26
  resolvedUIPaths: z.string(),
27
+ resolbedHookPaths: z.string(),
28
+ resolvedUtilPaths: z.string(),
25
29
  });
26
30
 
27
31
  export async function getConfig(cwd: string) {
@@ -42,6 +46,8 @@ export async function resolveConfigPaths(cwd: string, config: RawConfig) {
42
46
  return configSchema.parse({
43
47
  ...config,
44
48
  resolvedUIPaths: path.join(seedComponentRootPath, "ui"),
49
+ resolbedHookPaths: path.join(seedComponentRootPath, "hook"),
50
+ resolvedUtilPaths: path.join(seedComponentRootPath, "util"),
45
51
  });
46
52
  }
47
53
 
@@ -50,12 +56,13 @@ export async function getRawConfig(cwd: string): Promise<RawConfig | null> {
50
56
  const configResult = await explorer.search(cwd);
51
57
 
52
58
  if (!configResult) {
59
+ p.log.message(color.red(`${cwd} 경로에 seed-design.json 파일이 없습니다.`));
53
60
  return null;
54
61
  }
55
62
 
56
63
  return rawConfigSchema.parse(configResult.config);
57
64
  } catch (error) {
58
65
  console.log(error);
59
- throw new Error(`Invalid configuration found in ${cwd}/seed-design.json.`);
66
+ throw new Error(`${cwd} 경로에 seed-design.json 파일을 읽을 수 없습니다.`);
60
67
  }
61
68
  }
@@ -1,15 +1,15 @@
1
- import { registryComponentSchema, type RegistryComponentMachineGenerated } from "@/src/schema";
1
+ import { registryUISchema, type RegistryUIMachineGenerated } from "@/src/schema";
2
2
 
3
3
  const BASE_URL =
4
4
  process.env.NODE_ENV === "prod" ? "https://v3.seed-design.io" : "http://localhost:3000";
5
5
 
6
- export async function fetchRegistryComponentItem(
6
+ export async function fetchRegistryUIItem(
7
7
  fileNames?: string[],
8
- ): Promise<RegistryComponentMachineGenerated> {
8
+ ): Promise<RegistryUIMachineGenerated> {
9
9
  try {
10
10
  const results = await Promise.all(
11
11
  fileNames.map(async (fileName) => {
12
- const response = await fetch(`${BASE_URL}/__registry__/component/${fileName}.json`);
12
+ const response = await fetch(`${BASE_URL}/__registry__/ui/${fileName}.json`);
13
13
  return await response.json();
14
14
  }),
15
15
  );
@@ -21,11 +21,11 @@ export async function fetchRegistryComponentItem(
21
21
  }
22
22
  }
23
23
 
24
- export async function getRegistryComponentIndex() {
24
+ export async function getRegistryUIIndex() {
25
25
  try {
26
- const [result] = await fetchRegistryComponentItem(["index"]);
26
+ const [result] = await fetchRegistryUIItem(["index"]);
27
27
 
28
- return registryComponentSchema.parse(result);
28
+ return registryUISchema.parse(result);
29
29
  } catch (error) {
30
30
  console.log(error);
31
31
  throw new Error(`Failed to fetch components from ${BASE_URL}.`);