@@ -4,8 +4,24 @@ import { run, RunOptions } from "npm-check-updates";
44import { installDependencies } from "../utils/installDependencies.js" ;
55import { readJSONFileSync , writeJSONFile } from "../utils/fileSystem.js" ;
66import { logger } from "../utils/logger.js" ;
7+ import { z } from "zod" ;
8+
9+ export const UpdateCommandOptionsSchema = z . object ( {
10+ to : z . string ( ) . optional ( ) ,
11+ } ) ;
12+
13+ export type UpdateCommandOptions = z . infer < typeof UpdateCommandOptionsSchema > ;
14+
15+ type NcuRunOptionTarget = "latest" | `@${string } `;
16+
17+ export async function updateCommand ( projectPath : string , anyOptions : any ) {
18+ const parseRes = UpdateCommandOptionsSchema . safeParse ( anyOptions ) ;
19+ if ( ! parseRes . success ) {
20+ logger . error ( parseRes . error . message ) ;
21+ return ;
22+ }
23+ const options = parseRes . data ;
724
8- export async function updateCommand ( projectPath : string ) {
925 const triggerDevPackage = "@trigger.dev" ;
1026 const packageJSONPath = path . join ( projectPath , "package.json" ) ;
1127 const packageData = readJSONFileSync ( packageJSONPath ) ;
@@ -27,12 +43,14 @@ export async function updateCommand(projectPath: string) {
2743 } ;
2844 } ) ;
2945
46+ const targetVersion = getTargetVersion ( options . to ) ;
47+
3048 // Use npm-check-updates to get updated dependency versions
3149 const ncuOptions : RunOptions = {
3250 packageData,
3351 upgrade : true ,
3452 jsonUpgraded : true ,
35- target : "latest" ,
53+ target : targetVersion ,
3654 } ;
3755
3856 // Can either give a json like package.json or just with deps and their new versions
@@ -69,6 +87,39 @@ export async function updateCommand(projectPath: string) {
6987 return ;
7088 }
7189
90+ let applyUpdates = targetVersion !== "latest" ;
91+
92+ if ( targetVersion === "latest" ) {
93+ applyUpdates = await hasUserConfirmed ( packagesToUpdate , packageMaps , updatedDependencies ) ;
94+ }
95+
96+ if ( applyUpdates ) {
97+ const newPackageJSON = packageData ;
98+ packagesToUpdate . forEach ( ( packageName ) => {
99+ const tmp = packageMaps [ packageName ] ;
100+ if ( tmp ) {
101+ newPackageJSON [ tmp . type ] [ packageName ] = updatedDependencies [ packageName ] ;
102+ }
103+ } ) ;
104+ await writeJSONFile ( packageJSONPath , newPackageJSON ) ;
105+ await installDependencies ( projectPath ) ;
106+ }
107+ }
108+
109+ // expects a version number, or latest.
110+ // if version number is specified, prepend it with '@' for ncu.
111+ function getTargetVersion ( toVersion ?: string ) : NcuRunOptionTarget {
112+ if ( ! toVersion ) {
113+ return "latest" ;
114+ }
115+ return toVersion === "latest" ? "latest" : `@${ toVersion } ` ;
116+ }
117+
118+ async function hasUserConfirmed (
119+ packagesToUpdate : string [ ] ,
120+ packageMaps : { [ x : string ] : { type : string ; version : string } } ,
121+ updatedDependencies : { [ x : string ] : any }
122+ ) : Promise < boolean > {
72123 // Inform the user of the dependencies that can be updated
73124 console . log ( "\nNewer versions found for the following packages:" ) ;
74125 console . table (
@@ -86,15 +137,5 @@ export async function updateCommand(projectPath: string) {
86137 message : "Do you want to update these packages in package.json and re-install dependencies?" ,
87138 } ) ;
88139
89- if ( confirm ) {
90- const newPackageJSON = packageData ;
91- packagesToUpdate . forEach ( ( packageName ) => {
92- const tmp = packageMaps [ packageName ] ;
93- if ( tmp ) {
94- newPackageJSON [ tmp . type ] [ packageName ] = updatedDependencies [ packageName ] ;
95- }
96- } ) ;
97- await writeJSONFile ( packageJSONPath , newPackageJSON ) ;
98- await installDependencies ( projectPath ) ;
99- }
140+ return confirm ;
100141}
0 commit comments