1- import type { Argv } from ' yargs' ;
1+ import type { Argv } from " yargs" ;
22
3- import fetches from ' @siberiacancode/fetches' ;
4- import chalk from ' chalk' ;
5- import { execa } from ' execa' ;
6- import fs from ' node:fs' ;
7- import path from ' node:path' ;
8- import ora from ' ora' ;
9- import prompts from ' prompts' ;
10- import { createMatchPath , loadConfig } from ' tsconfig-paths' ;
3+ import fetches from " @siberiacancode/fetches" ;
4+ import chalk from " chalk" ;
5+ import { execa } from " execa" ;
6+ import fs from " node:fs" ;
7+ import path from " node:path" ;
8+ import ora from " ora" ;
9+ import prompts from " prompts" ;
10+ import { createMatchPath , loadConfig } from " tsconfig-paths" ;
1111
12- import type { AddOptionsSchema , ConfigSchema , Registry } from ' @/utils/types' ;
12+ import type { AddOptionsSchema , ConfigSchema , Registry } from " @/utils/types" ;
1313
14- import { APP_PATH , REPO_URLS } from ' @/utils/constants' ;
15- import { getConfig , getPackageManager , toCase } from ' @/utils/helpers' ;
16- import { addOptionsSchema } from ' @/utils/types' ;
14+ import { APP_PATH , REPO_URLS } from " @/utils/constants" ;
15+ import { getConfig , getPackageManager , toCase } from " @/utils/helpers" ;
16+ import { addOptionsSchema } from " @/utils/types" ;
1717
18- type FileType = ' hook' | ' package' | ' util' ;
18+ type FileType = " hook" | " package" | " util" ;
1919interface FileItem {
2020 name : string ;
2121 parent : string ;
2222 type : FileType ;
2323}
2424
25- const resolveDependencies = ( registry : Registry , hooks : string [ ] ) : Map < string , FileItem > => {
25+ const resolveDependencies = (
26+ registry : Registry ,
27+ hooks : string [ ]
28+ ) : Map < string , FileItem > => {
2629 const files = new Map < string , FileItem > ( ) ;
2730
2831 const addFile = ( name : string , type : FileType , parent : string ) =>
@@ -33,10 +36,10 @@ const resolveDependencies = (registry: Registry, hooks: string[]): Map<string, F
3336
3437 const item = registry [ hook ] ! ;
3538
36- addFile ( hook , ' hook' , item . name ) ;
39+ addFile ( hook , " hook" , item . name ) ;
3740
38- item . utils . forEach ( ( util ) => addFile ( util , ' util' , item . name ) ) ;
39- item . packages . forEach ( ( pkg ) => addFile ( pkg , ' package' , item . name ) ) ;
41+ item . utils . forEach ( ( util ) => addFile ( util , " util" , item . name ) ) ;
42+ item . packages . forEach ( ( pkg ) => addFile ( pkg , " package" , item . name ) ) ;
4043 item . hooks . forEach ( resolveDependency ) ;
4144 } ;
4245
@@ -51,18 +54,19 @@ interface UpdateImportsRules {
5154}
5255
5356const updateImports = async ( filePath : string , config : ConfigSchema ) => {
54- const fileContent = fs . readFileSync ( filePath , ' utf-8' ) ;
57+ const fileContent = fs . readFileSync ( filePath , " utf-8" ) ;
5558
5659 const rules : UpdateImportsRules [ ] = [
5760 {
5861 regex : / i m p o r t \s + \{ ( [ ^ } ] + ) \} \s + f r o m \s + [ ' " ] ( @ \/ u t i l s [ ^ ' " ] * ) [ ' " ] / g,
59- replacer : ( _ , imports ) => `import {${ imports } } from '${ config . aliases . utils } '`
62+ replacer : ( _ , imports ) =>
63+ `import { ${ imports } } from '${ config . aliases . utils } '` ,
6064 } ,
6165 {
6266 regex : / i m p o r t \s + (?: t y p e \s + ) ? \{ ( [ ^ } ] + ) \} \s + f r o m \s + [ ' " ] ( \. [ ^ ' " ] * ) [ ' " ] / g,
6367 replacer : ( _ , imports , internalPath ) =>
64- `import {${ imports } } from '${ toCase ( internalPath , config . case ) } '`
65- }
68+ `import { ${ imports } } from '${ toCase ( internalPath , config . case ) } '` ,
69+ } ,
6670 ] ;
6771
6872 const updatedContent = rules . reduce (
@@ -74,39 +78,40 @@ const updateImports = async (filePath: string, config: ConfigSchema) => {
7478} ;
7579
7680export const add = {
77- command : ' add [hooks...]' ,
78- describe : ' Add a hook to your project' ,
81+ command : " add [hooks...]" ,
82+ describe : " Add a hook to your project" ,
7983 builder : ( yargs : Argv ) =>
8084 yargs
81- . positional ( ' hooks' , {
82- describe : ' List of hooks to add' ,
83- type : ' string' ,
85+ . positional ( " hooks" , {
86+ describe : " List of hooks to add" ,
87+ type : " string" ,
8488 demandOption : true ,
8589 array : true ,
86- default : [ ]
90+ default : [ ] ,
8791 } )
88- . option ( ' all' , {
89- alias : 'a' ,
90- type : ' boolean' ,
92+ . option ( " all" , {
93+ alias : "a" ,
94+ type : " boolean" ,
9195 default : false ,
92- description : ' add all available hooks'
96+ description : " add all available hooks" ,
9397 } )
94- . option ( 'cwd' , {
95- type : 'string' ,
96- description : 'the working directory. defaults to the current directory.' ,
97- default : APP_PATH
98+ . option ( "cwd" , {
99+ type : "string" ,
100+ description :
101+ "the working directory. defaults to the current directory." ,
102+ default : APP_PATH ,
98103 } )
99- . option ( ' overwrite' , {
100- alias : 'o' ,
101- type : ' boolean' ,
104+ . option ( " overwrite" , {
105+ alias : "o" ,
106+ type : " boolean" ,
102107 default : false ,
103- description : ' overwrite existing files'
108+ description : " overwrite existing files" ,
104109 } )
105- . option ( ' registry' , {
106- type : ' string' ,
107- description : ' url of the registry to use' ,
110+ . option ( " registry" , {
111+ type : " string" ,
112+ description : " url of the registry to use" ,
108113 demandOption : true ,
109- default : ' https://siberiacancode.github.io/reactuse/registry.json'
114+ default : " https://siberiacancode.github.io/reactuse/registry.json" ,
110115 } ) ,
111116
112117 handler : async ( argv : AddOptionsSchema ) => {
@@ -115,30 +120,30 @@ export const add = {
115120 all : argv . all ,
116121 registry : argv . registry ,
117122 overwrite : argv . overwrite ,
118- cwd : argv . cwd
123+ cwd : argv . cwd ,
119124 } ) ;
120125
121126 const registryResponse = await fetches . get < Registry > ( options . registry ) ;
122127 const registry = registryResponse . data ;
123128
124129 if ( ! registry ) {
125- console . log ( ' Registry is missing. Please check the url.' ) ;
130+ console . log ( " Registry is missing. Please check the url." ) ;
126131 process . exit ( 1 ) ;
127132 }
128133
129134 let selectedHooks = options . all ? Object . keys ( registry ) : options . hooks ;
130135 if ( ! selectedHooks . length ) {
131136 const { hooks } = await prompts ( {
132- type : ' multiselect' ,
133- name : ' hooks' ,
134- message : `Which ${ chalk . cyan ( ' hooks' ) } would you like to add?` ,
135- hint : ' Space to select. A to toggle all. Enter to submit.' ,
137+ type : " multiselect" ,
138+ name : " hooks" ,
139+ message : `Which ${ chalk . cyan ( " hooks" ) } would you like to add?` ,
140+ hint : " Space to select. A to toggle all. Enter to submit." ,
136141 instructions : false ,
137142 choices : Object . values ( registry ) . map ( ( hook ) => ( {
138143 title : hook . name ,
139144 value : hook . name ,
140- selected : false
141- } ) )
145+ selected : false ,
146+ } ) ) ,
142147 } ) ;
143148 if ( hooks ) selectedHooks = hooks ;
144149 }
@@ -153,35 +158,51 @@ export const add = {
153158 }
154159
155160 if ( ! selectedHooks . length ) {
156- console . log ( ' No hooks selected.' ) ;
161+ console . log ( " No hooks selected." ) ;
157162 process . exit ( 0 ) ;
158163 }
159164
160165 const config = await getConfig ( options . cwd ) ;
161- const language = config ?. ts ? 'ts' : 'js' ;
166+ const language = config ?. ts ? "ts" : "js" ;
162167
163168 const projectConfig = loadConfig ( options . cwd ) ;
164- if ( projectConfig . resultType === ' failed' ) {
169+ if ( projectConfig . resultType === " failed" ) {
165170 throw new Error (
166- `Failed to load ${ language } config.json. ${ projectConfig . message ?? '' } ` . trim ( )
171+ `Failed to load ${ language } config.json. ${
172+ projectConfig . message ?? ""
173+ } `. trim ( )
167174 ) ;
168175 }
169176
170- const matchPath = createMatchPath ( projectConfig . absoluteBaseUrl , projectConfig . paths ) ;
171- const pathToLoadHooks = matchPath ( config . aliases . hooks , undefined , ( ) => true ) ;
172- const pathToLoadUtils = matchPath ( config . aliases . utils , undefined , ( ) => true ) ;
177+ const matchPath = createMatchPath (
178+ projectConfig . absoluteBaseUrl ,
179+ projectConfig . paths
180+ ) ;
181+ const pathToLoadHooks = matchPath (
182+ config . aliases . hooks ,
183+ undefined ,
184+ ( ) => true
185+ ) ;
186+ const pathToLoadUtils = matchPath (
187+ config . aliases . utils ,
188+ undefined ,
189+ ( ) => true
190+ ) ;
173191
174192 if ( ! pathToLoadHooks || ! pathToLoadUtils ) {
175- console . log ( ' Failed to load paths.' ) ;
193+ console . log ( " Failed to load paths." ) ;
176194 process . exit ( 1 ) ;
177195 }
178196
179197 const dependencies = resolveDependencies ( registry , selectedHooks ) ;
180198 const packages : string [ ] = [ ] ;
181199 const files = Array . from ( dependencies . values ( ) )
182200 . map ( ( dependency ) => {
183- if ( dependency . type === 'hook' ) {
184- const filePath = toCase ( `${ dependency . name } /${ dependency . name } ` , config . case ) ;
201+ if ( dependency . type === "hook" ) {
202+ const filePath = toCase (
203+ `${ dependency . name } /${ dependency . name } ` ,
204+ config . case
205+ ) ;
185206 const directoryPath = `${ pathToLoadHooks } /${ filePath } .${ language } ` ;
186207 const registryPath = `${
187208 REPO_URLS [ language . toUpperCase ( ) as keyof typeof REPO_URLS ]
@@ -193,11 +214,11 @@ export const add = {
193214 registryPath,
194215 type : dependency . type ,
195216 indexPath,
196- filePath
217+ filePath,
197218 } ;
198219 }
199220
200- if ( dependency . type === ' util' ) {
221+ if ( dependency . type === " util" ) {
201222 const filePath = toCase ( `${ dependency . name } ` , config . case ) ;
202223 const directoryPath = `${ pathToLoadUtils } /${ filePath } .${ language } ` ;
203224 const registryPath = `${
@@ -210,11 +231,11 @@ export const add = {
210231 registryPath,
211232 type : dependency . type ,
212233 indexPath,
213- filePath
234+ filePath,
214235 } ;
215236 }
216237
217- if ( dependency . type === ' package' ) {
238+ if ( dependency . type === " package" ) {
218239 packages . push ( dependency . name ) ;
219240 return undefined ;
220241 }
@@ -223,25 +244,28 @@ export const add = {
223244 } )
224245 . filter ( Boolean ) ;
225246
226- const spinner = ora ( ' Installing files...' ) . start ( ) ;
247+ const spinner = ora ( " Installing files..." ) . start ( ) ;
227248 for ( const file of files ) {
228- const { directoryPath, registryPath, indexPath, filePath, name, type } = file ! ;
249+ const { directoryPath, registryPath, indexPath, filePath, name, type } =
250+ file ! ;
229251 spinner . text = `Installing ${ name } ...` ;
230252 const directory = path . dirname ( directoryPath ) ;
231253
232254 const isExists = fs . existsSync ( directory ) ;
233255 if ( isExists && ! options . overwrite ) {
234256 spinner . stop ( ) ;
235257 const { overwrite } = await prompts ( {
236- type : ' confirm' ,
237- name : ' overwrite' ,
258+ type : " confirm" ,
259+ name : " overwrite" ,
238260 message : `File ${ name } already exists. Would you like to overwrite?` ,
239- initial : false
261+ initial : false ,
240262 } ) ;
241263
242264 if ( ! overwrite ) {
243265 console . log (
244- `Skipped ${ name } . To overwrite, run with the ${ chalk . green ( '--overwrite' ) } flag.`
266+ `Skipped ${ name } . To overwrite, run with the ${ chalk . green (
267+ "--overwrite"
268+ ) } flag.`
245269 ) ;
246270 continue ;
247271 }
@@ -257,30 +281,34 @@ export const add = {
257281
258282 const exportStatement = `export * from './${ filePath } ';\n` ;
259283
260- if ( ! fs . existsSync ( indexPath ) ) fs . writeFileSync ( indexPath , '' ) ;
261- const indexFileContent = fs . readFileSync ( indexPath , ' utf-8' ) ;
284+ if ( ! fs . existsSync ( indexPath ) ) fs . writeFileSync ( indexPath , "" ) ;
285+ const indexFileContent = fs . readFileSync ( indexPath , " utf-8" ) ;
262286 if ( ! indexFileContent . includes ( exportStatement ) )
263- fs . appendFileSync ( indexPath , exportStatement , ' utf-8' ) ;
287+ fs . appendFileSync ( indexPath , exportStatement , " utf-8" ) ;
264288 }
265289
266290 const packageManager = await getPackageManager ( options . cwd ) ;
267291
268- spinner . text = `Installing packages ${ chalk . bold ( packages . join ( ', ' ) ) } with ${ chalk . cyan (
269- packageManager
270- ) } `;
292+ spinner . text = `Installing packages ${ chalk . bold (
293+ packages . join ( ", " )
294+ ) } with ${ chalk . cyan ( packageManager ) } `;
271295 if ( packages . length ) {
272- await execa ( packageManager , [ packageManager === 'npm' ? 'install' : 'add' , ...packages ] , {
273- cwd : options . cwd
274- } ) ;
296+ await execa (
297+ packageManager ,
298+ [ packageManager === "npm" ? "install" : "add" , ...packages ] ,
299+ {
300+ cwd : options . cwd ,
301+ }
302+ ) ;
275303 }
276304
277305 spinner . stop ( ) ;
278306
279307 const installedHooks = files
280- . filter ( ( file ) => file ! . type === ' hook' )
308+ . filter ( ( file ) => file ! . type === " hook" )
281309 . map ( ( file ) => chalk . green ( file ! . name ) )
282- . join ( ', ' ) ;
310+ . join ( ", " ) ;
283311 console . log ( `\nInstalled hooks: ${ installedHooks } ` ) ;
284- console . log ( chalk . bold ( ' \nπ Hooks added successfully! π' ) ) ;
285- }
312+ console . log ( chalk . bold ( " \nπ Hooks added successfully! π" ) ) ;
313+ } ,
286314} ;
0 commit comments