11import path from 'path' ;
22import { isProd } from '@/constants' ;
3- import type { ToolType , ToolSetType } from './type' ;
3+ import type { ToolType , ToolConfigWithCbType , ToolSetConfigType } from './type' ;
44import { tools } from './constants' ;
55import { findToolIcon } from './utils/icon' ;
66import fs from 'fs' ;
77import { addLog } from '@/utils/log' ;
8+ import { ToolTypeEnum } from './type/tool' ;
89
910const saveFile = async ( url : string , path : string ) => {
1011 const response = await fetch ( url ) ;
@@ -16,92 +17,81 @@ const saveFile = async (url: string, path: string) => {
1617 return buffer ;
1718} ;
1819
19- export const LoadTool = ( mod : ToolType | ToolSetType , filename : string ) => {
20- const tmpTools : ToolType [ ] = [ ] ;
21- const defaultToolId = filename . split ( '.' ) . shift ( ) as string ;
22- const toolId = mod . toolId || defaultToolId ;
23- const defaultToolImg = findToolIcon ( defaultToolId ) ;
20+ // Load tool or toolset and its children
21+ export const LoadToolsByFilename = async (
22+ basePath : string ,
23+ filename : string
24+ ) : Promise < ToolType [ ] > => {
25+ const tools : ToolType [ ] = [ ] ;
2426
25- if ( 'children' in mod ) {
26- const children = mod . children as ToolType [ ] ;
27- tmpTools . push ( {
28- ... mod ,
29- icon : mod . icon || defaultToolImg ,
30- toolFile : filename ,
31- toolId ,
32- inputs : [ ] ,
33- outputs : [ ] ,
34- cb : ( ) => Promise . resolve ( { } )
35- } ) ;
36- tmpTools . push ( ... children . map ( ( child ) => ( { ... child , toolFile : filename } ) ) ) ;
37- } else {
38- tmpTools . push ( {
39- ... mod ,
40- icon : mod . icon || defaultToolImg ,
41- toolId ,
42- toolFile : filename
27+ const toolRootPath = path . join ( basePath , filename ) ;
28+ const childrenPath = path . join ( toolRootPath , 'children' ) ;
29+ const isToolSet = fs . existsSync ( childrenPath ) ;
30+
31+ const defaultIcon = findToolIcon ( filename ) ;
32+
33+ if ( isToolSet ) {
34+ const toolset = ( await import ( toolRootPath ) ) . default as ToolSetConfigType ;
35+ const toolsetId = toolset . toolId || filename ;
36+ const icon = toolset . icon || defaultIcon ;
37+
38+ tools . push ( {
39+ ... toolset ,
40+ toolId : toolsetId ,
41+ icon ,
42+ toolDirName : filename ,
43+ cb : ( ) => Promise . resolve ( { } ) ,
44+ versionList : [ ]
4345 } ) ;
44- }
46+ // Push children
47+ // 1. Read children
48+ const children = fs . readdirSync ( childrenPath ) ;
4549
46- return tmpTools ;
47- } ;
50+ for await ( const child of children ) {
51+ const childPath = path . join ( childrenPath , child ) ;
52+ const childMod = ( await import ( childPath ) ) . default as ToolConfigWithCbType ;
4853
49- const LoadToolsProd = async ( ) => {
50- const toolsDir = process . env . TOOLS_DIR || path . join ( process . cwd ( ) , 'dist' , 'tools' ) ;
51- // 两种方式:
52- // 1. 读取 tools 目录下所有目录的 index.js 文件作为 tool
53- const files = fs . readdirSync ( toolsDir ) ;
54- for ( const file of files ) {
55- const filePath = path . join ( toolsDir , file ) ;
56- const mod = ( await import ( filePath ) ) . default as ToolType ;
57- tools . push ( ...LoadTool ( mod , file ) ) ;
58- }
59- // 2. 读取 tools.json 文件中的配置(通过网络挂载)
60- const toolConfigPath = path . join ( process . cwd ( ) , 'dist' , 'tools.json' ) ;
61- if ( fs . existsSync ( toolConfigPath ) ) {
62- const toolConfig = JSON . parse ( fs . readFileSync ( toolConfigPath , 'utf-8' ) ) as {
63- toolId : string ;
64- url : string ;
65- } [ ] ;
66- // every string is a url to get a .js file
67- for ( const tool of toolConfig ) {
68- await saveFile ( tool . url , path . join ( toolsDir , tool . toolId + '.js' ) ) ;
69- const mod = ( await import ( path . join ( toolsDir , tool . toolId + '.js' ) ) ) . default as ToolType ;
70- tools . push ( ...LoadTool ( mod , tool . toolId ) ) ;
54+ const toolId = childMod . toolId || `${ toolsetId } /${ child } ` ;
55+
56+ tools . push ( {
57+ ...childMod ,
58+ toolId,
59+ parentId : toolsetId ,
60+ type : toolset . type ,
61+ icon,
62+ toolDirName : filename
63+ } ) ;
7164 }
65+ } else {
66+ const tool = ( await import ( toolRootPath ) ) . default as ToolConfigWithCbType ;
67+
68+ tools . push ( {
69+ ...tool ,
70+ type : tool . type || ToolTypeEnum . tools ,
71+ icon : tool . icon || defaultIcon ,
72+ toolId : tool . toolId || filename ,
73+ toolDirName : filename
74+ } ) ;
7275 }
73- addLog . info ( `\
7476
75- =================
76- reading tools in prod mode
77- tools:\n[ ${ tools . map ( ( tool ) => tool . toolId ) . join ( ', ' ) } ]
78- amount: ${ tools . length }
79- =================
80- ` ) ;
77+ return tools ;
8178} ;
8279
83- async function LoadToolsDev ( ) {
84- const toolsPath = path . join ( __dirname , 'packages' ) ;
85- const toolDirs = fs . readdirSync ( toolsPath ) ;
80+ export async function initTool ( ) {
81+ const basePath = isProd
82+ ? process . env . TOOLS_DIR || path . join ( process . cwd ( ) , 'dist' , 'tools' )
83+ : path . join ( __dirname , 'packages' ) ;
84+
85+ const toolDirs = fs . readdirSync ( basePath ) ;
8686 for ( const tool of toolDirs ) {
87- const toolPath = path . join ( toolsPath , tool ) ;
88- const mod = ( await import ( toolPath ) ) . default as ToolType | ToolSetType ;
89- tools . push ( ...LoadTool ( mod , tool ) ) ;
87+ const tmpTools = await LoadToolsByFilename ( basePath , tool ) ;
88+ tools . push ( ...tmpTools ) ;
9089 }
91- addLog . info ( `\
9290
91+ addLog . info ( `
9392=================
94- reading tools in dev mode
95- tools:\n[ ${ tools . map ( ( tool ) => tool . toolId ) . join ( ', ' ) } ]
93+ Load tools in prod mode
9694 amount: ${ tools . length }
9795=================
9896` ) ;
9997}
100-
101- export async function initTool ( ) {
102- if ( isProd ) {
103- await LoadToolsProd ( ) ;
104- } else {
105- await LoadToolsDev ( ) ;
106- }
107- }
0 commit comments