1-
21import * as fs from "fs" ;
32import * as path from "path" ;
43import chalk from "chalk" ;
54import * as inquirer from "inquirer" ;
5+ import * as _ from "lodash" ;
66
7- import { PackageJSON } from "package-json" ;
7+ import { PackageJSON , DependencyMap } from "package-json" ;
88import { outputCurrentState , output , outputDoom , debug } from "./output" ;
99import { promisify } from "util" ;
10- import { Crawl as LocalCrawl , NodeModuleResolutionExposed } from "./SecretDungeonCrawl" ;
10+ import { Crawl as LocalCrawl , NodeModuleResolutionExposed , isModuleResolutionError } from "./SecretDungeonCrawl" ;
11+
12+ // want to:
13+ // - make it find roots of packages, because it fails when it goes into a lib
14+ // - make it guess why it couldn't resolve a dev dependency
15+ // - make it "check GPS" to tell you what dir it's in
16+ // - make it report how many stairs you went up or down
17+ // - make it report the difference in versions?
1118
1219const readFile = promisify ( fs . readFile ) ;
1320const writeFile = promisify ( fs . writeFile ) ;
@@ -20,9 +27,9 @@ export async function youAreIn(appDir: string) {
2027 debug ( "Hello from " + appDir ) ;
2128
2229 if ( circumstances === "not a package" ) {
23- output ( `You are in ${ appDir } . It is completely dark in here. What even is this place?? ` ) ;
30+ outputDoom ( `You are in ${ appDir } .\nIt is completely dark in here.\nWhat even is this place?? ` ) ;
2431 } else if ( circumstances === "invalid package json" ) {
25- output ( `A rat bites your foot! The package.json is invalid in ${ appDir } ` ) ;
32+ outputDoom ( `A rat bites your foot! The package.json is invalid in ${ appDir } ` ) ;
2633 } else {
2734 outputCurrentState ( `You are in "${ circumstances . packageJson . name } ". It appears to be version ${ circumstances . packageJson . version } .` )
2835 return timeToAct ( { ...circumstances , crawl : await injectSecretDungeonCrawl ( appDir ) } ) ;
@@ -45,23 +52,24 @@ async function injectSecretDungeonCrawl(appDir: string): Promise<NodeModuleResol
4552
4653async function timeToAct ( p : PackageRoot & { crawl : NodeModuleResolutionExposed } ) : Promise < void > {
4754 const answers = await requestNextAction ( p ) ;
48- output ( `You have chosen: ${ answers . action } ` )
55+ debug ( `You have chosen: ${ answers . action } ` )
4956 switch ( answers . action ) {
5057 case "exit" :
5158 return ;
5259 case "doors" :
5360 output ( `You have examined all the doors before you, and chosen: ${ answers . door } ` ) ;
5461 const otherSide = findLibraryRoot ( answers . door , p . crawl ) ;
5562 if ( itsaTrap ( otherSide ) ) {
56- outputDoom ( chalk . red ( "It's a trap! " ) + otherSide . error . message )
63+ outputDoom ( chalk . red ( "It's a trap! " ) + otherSide . details || otherSide . error . message )
5764 return youAreIn ( p . appDir ) ;
5865 }
5966 return youAreIn ( otherSide ) ;
6067 }
6168}
6269
6370type Trap = {
64- error : Error
71+ error : Error ,
72+ details ?: string
6573}
6674
6775function itsaTrap ( t : Trap | string ) : t is Trap {
@@ -74,7 +82,9 @@ function findLibraryRoot(lib: string, crawl: NodeModuleResolutionExposed): strin
7482 try {
7583 whereIsIt = crawl . locateModule ( lib ) ;
7684 } catch ( error ) {
77- return { error } ;
85+ const details = isModuleResolutionError ( error ) ?
86+ `${ error . message } \nfrom ${ error . filename } \nPaths searched: ${ error . paths . join ( "\n" ) } ` : undefined ;
87+ return { error, details } ;
7888 }
7989 debug ( `Resolved ${ lib } to ${ whereIsIt } ` ) ;
8090 const dir = path . dirname ( whereIsIt ) ;
@@ -109,10 +119,22 @@ async function requestNextAction(p: PackageRoot): Promise<NextActionAnswers> {
109119 return response ;
110120}
111121
122+ function choicesFromDependencyObject ( optionalDeps : DependencyMap | undefined ,
123+ colorFn : ( txt : string ) => string ) : inquirer . objects . ChoiceOption [ ] {
124+ const deps = optionalDeps || { } ;
125+ return Object . keys ( deps ) . map ( d => ( {
126+ value : d ,
127+ name : colorFn ( d + ":" + deps [ d ] )
128+ } ) ) ;
129+ }
130+
112131function chooseDoor ( p : PackageRoot ) : inquirer . Question < NextActionAnswers > {
113- const listOfDependencies : inquirer . ChoiceType [ ] = Object . keys ( p . packageJson . dependencies || { } )
114- . concat ( Object . keys ( p . packageJson . devDependencies || { } ) . map ( devdep => chalk . gray ( devdep ) ) )
115- . sort ( )
132+ const allDependencies = choicesFromDependencyObject ( p . packageJson . dependencies , chalk . white )
133+ . concat ( choicesFromDependencyObject ( p . packageJson . devDependencies , chalk . grey ) )
134+ . concat ( choicesFromDependencyObject ( p . packageJson . peerDependencies , chalk . magenta ) ) ;
135+ const listOfDependencies = _ . sortBy (
136+ allDependencies ,
137+ ct => ct . value as string )
116138 // debug("The dependencies are: " + listOfDependencies.join(" & "))
117139 return {
118140 name : "door" ,
0 commit comments