@@ -2,7 +2,7 @@ import { readdir as readDir, writeFile, mkdir as mkDir, readFile, copyFile, stat
22import { watch as watchDir } from "chokidar"
33import { minify } from "terser"
44import { resolve as resolvePath , basename , extname } from "path"
5- import { transpileModule , ScriptTarget } from "typescript"
5+ import { transpileModule , ScriptTarget , CompilerOptions , createProgram , createCompilerHost } from "typescript"
66import { format } from "prettier"
77
88interface Info {
@@ -144,8 +144,8 @@ export function push(srcDir: string, hackmudDir: string, users: string[], script
144144 * @param scripts scripts to push from (pushes from all if empty)
145145 * @param onPush function that's called after each script has been built and written
146146 */
147- export function watch ( srcDir : string , hackmudDir : string , users : string [ ] , scripts : string [ ] , onPush ?: ( info : Info ) => void ) {
148- watchDir ( "" , { depth : 1 , cwd : srcDir , awaitWriteFinish : { stabilityThreshold : 100 } } ) . on ( "change" , async path => {
147+ export function watch ( srcDir : string , hackmudDir : string , users : string [ ] , scripts : string [ ] , onPush ?: ( info : Info ) => void , { genTypes } : { genTypes ?: string } = { } ) {
148+ const watcher = watchDir ( "" , { depth : 1 , cwd : srcDir , awaitWriteFinish : { stabilityThreshold : 100 } } ) . on ( "change" , async path => {
149149 const extension = extname ( path )
150150
151151 if ( supportedExtensions . includes ( extension ) ) {
@@ -242,6 +242,12 @@ export function watch(srcDir: string, hackmudDir: string, users: string[], scrip
242242 }
243243 }
244244 } )
245+
246+ if ( genTypes ) {
247+ generateTypings ( srcDir , resolvePath ( srcDir , genTypes ) , hackmudDir )
248+ watcher . on ( "add" , ( ) => generateTypings ( srcDir , resolvePath ( srcDir , genTypes ) , hackmudDir ) )
249+ watcher . on ( "unlink" , ( ) => generateTypings ( srcDir , resolvePath ( srcDir , genTypes ) , hackmudDir ) )
250+ }
245251}
246252
247253/**
@@ -323,9 +329,85 @@ export async function test(srcPath: string) {
323329 return errors
324330}
325331
326- // export async function generateTypings(srcPath: string) {
332+ export async function generateTypings ( srcDir : string , target : string , hackmudPath ?: string ) {
333+ const users = new Set < string > ( )
334+
335+ if ( hackmudPath )
336+ for ( const dirent of await readDir ( hackmudPath , { withFileTypes : true } ) )
337+ if ( dirent . isFile ( ) && extname ( dirent . name ) == ".key" )
338+ users . add ( basename ( dirent . name , ".key" ) )
339+
340+ const wildScripts : string [ ] = [ ]
341+ const allScripts : Record < string , string [ ] > = { }
342+
343+ for ( const dirent of await readDir ( srcDir , { withFileTypes : true } ) )
344+ if ( dirent . isFile ( ) && extname ( dirent . name ) == ".ts" )
345+ wildScripts . push ( basename ( dirent . name , ".ts" ) )
346+ else if ( dirent . isDirectory ( ) ) {
347+ const scripts : string [ ] = allScripts [ dirent . name ] = [ ]
348+
349+ users . add ( dirent . name )
350+
351+ for ( const file of await readDir ( resolvePath ( srcDir , dirent . name ) , { withFileTypes : true } ) )
352+ if ( file . isFile ( ) && extname ( file . name ) == ".ts" )
353+ scripts . push ( basename ( file . name , ".ts" ) )
354+ }
355+
356+ let o = ""
357+
358+ for ( const script of wildScripts )
359+ o += `import { script as $${ script } $ } from "src/${ script } "\n`
360+
361+ o += "\n"
362+
363+ for ( const user in allScripts ) {
364+ const scripts = allScripts [ user ]
365+
366+ for ( const script of scripts )
367+ o += `import { script as $${ user } $${ script } $ } from "src/${ user } /${ script } "\n`
368+ }
369+
370+ o += `
371+ type Subscript<T extends (...args: any) => any> = Parameters<T>[1] extends undefined
372+ ? (args?: Parameters<T>[1]) => ReturnType<T> | ScriptFailure
373+ : (args?: Parameters<T>[1]) => ReturnType<T> | ScriptFailure
374+
375+ type WildFullsec = Record<string, () => ScriptFailure> & {
376+ `
377+
378+ for ( const script of wildScripts )
379+ o += `\t${ script } : Subscript<typeof $${ script } $>\n`
380+
381+ o += "}\n\nexport type PlayerFullsec = {"
382+
383+ for ( const user of users ) {
384+ const scripts = allScripts [ user ]
385+
386+ o += `\n\t${ user } : WildFullsec`
387+
388+ if ( scripts && scripts . length ) {
389+ o += " & {\n"
390+
391+ for ( const script of scripts )
392+ o += `\t\t${ script } : Subscript<typeof $${ user } $${ script } $>\n`
393+
394+ o += "\t}"
395+ }
396+
397+ o += "\n"
398+ }
399+
400+ o += `\
401+ }
402+
403+ export type PlayerHighsec = {}
404+ export type PlayerMidsec = {}
405+ export type PlayerLowsec = {}
406+ export type PlayerNullsec = {}
407+ `
327408
328- // }
409+ await writeFile ( target , o )
410+ }
329411
330412/**
331413 * Minifies a given script
0 commit comments