@@ -8,10 +8,12 @@ import { getDyadAppPath } from "../../paths/paths";
88import { DyadError , DyadErrorKind } from "@/errors/dyad_error" ;
99import {
1010 isComponentTaggerUpgradeNeeded ,
11- isCapacitorUpgradeNeeded ,
1211 applyComponentTagger ,
13- applyCapacitor ,
1412} from "../utils/app_upgrade_utils" ;
13+ import fs from "node:fs" ;
14+ import path from "node:path" ;
15+ import { spawn } from "node:child_process" ;
16+ import { gitAddAll , gitCommit } from "../utils/git_utils" ;
1517
1618export const logger = log . scope ( "app_upgrade_handlers" ) ;
1719const handle = createLoggedHandler ( logger ) ;
@@ -46,6 +48,100 @@ async function getApp(appId: number) {
4648 return app ;
4749}
4850
51+ function isViteApp ( appPath : string ) : boolean {
52+ const viteConfigPathJs = path . join ( appPath , "vite.config.js" ) ;
53+ const viteConfigPathTs = path . join ( appPath , "vite.config.ts" ) ;
54+
55+ return fs . existsSync ( viteConfigPathTs ) || fs . existsSync ( viteConfigPathJs ) ;
56+ }
57+
58+ function isCapacitorUpgradeNeeded ( appPath : string ) : boolean {
59+ // Check if it's a Vite app first
60+ if ( ! isViteApp ( appPath ) ) {
61+ return false ;
62+ }
63+
64+ // Check if Capacitor is already installed
65+ const capacitorConfigJs = path . join ( appPath , "capacitor.config.js" ) ;
66+ const capacitorConfigTs = path . join ( appPath , "capacitor.config.ts" ) ;
67+ const capacitorConfigJson = path . join ( appPath , "capacitor.config.json" ) ;
68+
69+ // If any Capacitor config exists, the upgrade is not needed
70+ if (
71+ fs . existsSync ( capacitorConfigJs ) ||
72+ fs . existsSync ( capacitorConfigTs ) ||
73+ fs . existsSync ( capacitorConfigJson )
74+ ) {
75+ return false ;
76+ }
77+
78+ return true ;
79+ }
80+
81+ async function applyCapacitor ( {
82+ appName,
83+ appPath,
84+ } : {
85+ appName : string ;
86+ appPath : string ;
87+ } ) {
88+ // Install Capacitor dependencies
89+ await simpleSpawn ( {
90+ command :
91+ "pnpm add @capacitor/core@7.4.4 @capacitor/cli@7.4.4 @capacitor/ios@7.4.4 @capacitor/android@7.4.4 || npm install @capacitor/core@7.4.4 @capacitor/cli@7.4.4 @capacitor/ios@7.4.4 @capacitor/android@7.4.4 --legacy-peer-deps" ,
92+ cwd : appPath ,
93+ successMessage : "Capacitor dependencies installed successfully" ,
94+ errorPrefix : "Failed to install Capacitor dependencies" ,
95+ } ) ;
96+
97+ // Initialize Capacitor
98+ await simpleSpawn ( {
99+ command : `npx cap init "${ appName } " "com.example.${ appName . toLowerCase ( ) . replace ( / [ ^ a - z 0 - 9 ] / g, "" ) } " --web-dir=dist` ,
100+ cwd : appPath ,
101+ successMessage : "Capacitor initialized successfully" ,
102+ errorPrefix : "Failed to initialize Capacitor" ,
103+ } ) ;
104+
105+ // Intentionally omit PNPM_INSTALL_POLICY_ARGS because:
106+ // 1. confirmModulesPurge will almost never be needed for capacitor (i.e. user would need to switch from npm to pnpm and not triggered a rebuild).
107+ // 2. strictBuildDeps should be kept true (default value) in case capacitor has native deps.
108+ await simpleSpawn ( {
109+ command :
110+ "pnpm install --prod=false || npm install --include=dev --legacy-peer-deps" ,
111+ cwd : appPath ,
112+ successMessage : "Development dependencies installed successfully" ,
113+ errorPrefix : "Failed to install development dependencies" ,
114+ } ) ;
115+
116+ // Add iOS and Android platforms
117+ await simpleSpawn ( {
118+ command : "npx cap add ios && npx cap add android" ,
119+ cwd : appPath ,
120+ successMessage : "iOS and Android platforms added successfully" ,
121+ errorPrefix : "Failed to add iOS and Android platforms" ,
122+ } ) ;
123+
124+ // Commit changes
125+ try {
126+ logger . info ( "Staging and committing Capacitor changes" ) ;
127+ await gitAddAll ( { path : appPath } ) ;
128+ await gitCommit ( {
129+ path : appPath ,
130+ message : "[dyad] add Capacitor for mobile app support" ,
131+ } ) ;
132+ logger . info ( "Successfully committed Capacitor changes" ) ;
133+ } catch ( err ) {
134+ logger . warn (
135+ `Failed to commit changes. This may happen if the project is not in a git repository, or if there are no changes to commit.` ,
136+ err ,
137+ ) ;
138+ throw new Error (
139+ "Failed to commit Capacitor changes. Please commit them manually. Error: " +
140+ err ,
141+ ) ;
142+ }
143+ }
144+
49145export function registerAppUpgradeHandlers ( ) {
50146 handle (
51147 "get-app-upgrades" ,
0 commit comments