@@ -5,16 +5,13 @@ import FormData from 'form-data';
55import ApiConst from './ApiConst' ;
66import AppConst from './AppConst' ;
77import { getApkName } from './CommonUtils' ;
8-
9- const FileType = {
10- Apk : 'apk' ,
11- Ipa : 'ipa'
12- } ;
13-
14- const FileContentType = {
15- Ipa : 'application/octet-stream' ,
16- Apk : 'application/vnd.android.package-archive'
17- } ;
8+ import jwt from 'jsonwebtoken' ;
9+ import {
10+ AppPlatform ,
11+ DecodedToken ,
12+ FileContentType ,
13+ FileType
14+ } from './types/CommonTypes' ;
1815
1916/**
2017 * Extract the build data from the file
@@ -83,7 +80,7 @@ const deployApp = async (
8380 applicationId : string ,
8481 buildPath : string ,
8582 appToken : any ,
86- baseUrl : string ,
83+ baseUrl ? : string ,
8784 releaseNotes ?: string
8885) => {
8986 // Use applicationId and buildPath in your deployment logic
@@ -102,73 +99,127 @@ const deployApp = async (
10299 console . error ( 'App token is missing' ) ;
103100 process . exit ( 1 ) ;
104101 }
105- if ( ! baseUrl ) {
106- console . error ( 'Base URL is missing' ) ;
102+
103+ const decodedToken = jwt . decode ( appToken ) as DecodedToken ;
104+
105+ const decodedApplicationId = decodedToken ? decodedToken . app : '' ;
106+
107+ if ( applicationId !== decodedApplicationId ) {
108+ console . error ( 'Application ID does not match the application token.' ) ;
107109 process . exit ( 1 ) ;
108110 }
109111
112+ const decodedBaseUrl = decodedToken ?. baseUrl ;
113+ const currentUrl = baseUrl || decodedBaseUrl ;
114+
115+ if ( ! currentUrl ) {
116+ console . error ( 'Base URL is missing' ) ;
117+ process . exit ( 1 ) ;
118+ }
110119 const fileType = buildPath ?. split ( '.' ) ?. pop ( ) ?? FileType . Apk ;
111120
112121 const currentFileContentType =
113122 fileType === FileType . Ipa ? FileContentType . Ipa : FileContentType . Apk ;
114123
115124 const fileBuffer = fs . readFileSync ( buildPath ) ;
116125
117- const formData = new FormData ( ) ;
126+ const chunkSize = AppConst . chunkSize * 1024 * 1024 ; // 100MB
127+
128+ const fileSize = fs . statSync ( buildPath ) . size ;
129+
130+ const totalChunks = Math . ceil ( fileSize / chunkSize ) ;
131+
132+ const fileStream = fs . createReadStream ( buildPath , {
133+ highWaterMark : chunkSize
134+ } ) ;
135+
136+ let chunkNumber = 1 ;
118137
119138 const blobData = new Blob ( [ fileBuffer ] , {
120139 type : currentFileContentType
121140 } ) ;
122141
123- if ( blobData ?. size > AppConst . maximumFileSize * 1024 * 1024 ) {
124- throw new Error (
125- `File size exceeds the allowed limit of ${ AppConst . maximumFileSize } MB.`
126- ) ;
127- }
128-
129142 try {
130143 console . log ( 'Processing build...' ) ;
131144 const buildInfo = await fileDataExtract ( buildPath , fileType , blobData ) ;
132145
133- formData . append ( 'appToken' , appToken ) ;
134- formData . append ( 'currentFileContentType' , currentFileContentType ) ;
135- formData . append ( 'baseUrl' , baseUrl ) ;
136- formData . append ( 'applicationId' , applicationId ) ;
137- formData . append ( 'buildInfo' , JSON . stringify ( buildInfo ) ) ;
146+ // Check if the build already exists
147+ const buildExistResponse = await axios . post (
148+ `${ currentUrl } /${ ApiConst . buildsExist } ` ,
149+ {
150+ application_id : applicationId ,
151+ version_code : buildInfo . versionCode ?. toString ( ) ,
152+ version_name : buildInfo . versionName ?. toString ( ) ,
153+ platform :
154+ buildInfo . fileType === FileType . Ipa
155+ ? AppPlatform . IOS
156+ : AppPlatform . Android
157+ } ,
158+ {
159+ headers : {
160+ 'Content-Type' : 'application/json' ,
161+ Authorization : `Bearer ${ appToken } `
162+ }
163+ }
164+ ) ;
138165
139- if ( releaseNotes ) {
140- releaseNotes = `<pre>${ releaseNotes } </pre>` ;
141- formData . append ( 'releaseNotes' , releaseNotes ) ;
166+ if ( buildExistResponse . status === 409 ) {
167+ return buildExistResponse ;
142168 }
143169
144- const fileStream = fs . createReadStream ( buildPath ) ;
170+ for await ( const chunk of fileStream ) {
171+ const formData = new FormData ( ) ;
145172
146- fileStream . on ( 'error' , err => {
147- console . error ( 'Error reading the file:' , err ) ;
148- } ) ;
173+ formData . append ( 'applicationId' , applicationId ) ;
174+ formData . append ( 'buildInfo' , JSON . stringify ( buildInfo ) ) ;
175+ formData . append ( 'currentFileContentType' , currentFileContentType ) ;
176+ formData . append ( 'baseUrl' , currentUrl ) ;
177+ formData . append ( 'appToken' , appToken ) ;
149178
150- formData . append ( 'file' , fileStream , {
151- contentType : currentFileContentType ,
152- filename : `${ AppConst . appDefaultName } .${ fileType } `
153- } ) ;
179+ if ( releaseNotes ) {
180+ formData . append ( 'releaseNotes' , `<pre>${ releaseNotes } </pre>` ) ;
181+ }
154182
155- console . log ( 'deployAppToPocketDeploy' ) ;
156- const response = await axios . post (
157- `${ baseUrl } ${ ApiConst . deployAppToPocketDeploy } ` ,
158- formData ,
159- {
160- headers : {
161- ...formData . getHeaders ( ) ,
162- Authorization : `Bearer ${ appToken } `
183+ fileStream . on ( 'error' , err => {
184+ console . error ( 'Error reading the file:' , err ) ;
185+ } ) ;
186+ // Add current chunk
187+ formData . append ( 'file' , chunk , {
188+ contentType : currentFileContentType ,
189+ filename : `chunk-${ chunkNumber } `
190+ } ) ;
191+
192+ // Add chunk metadata
193+ formData . append ( 'chunkNumber' , chunkNumber ) ;
194+ formData . append ( 'totalChunks' , totalChunks ) ;
195+
196+ const response = await axios . post (
197+ `${ currentUrl } /${ ApiConst . deployAppToPocketDeploy } ` ,
198+ formData ,
199+ {
200+ headers : {
201+ ...formData . getHeaders ( ) ,
202+ Authorization : `Bearer ${ appToken } `
203+ }
163204 }
205+ ) ;
206+
207+ if ( response . status === 200 ) {
208+ const percentage = Math . floor ( ( chunkNumber / totalChunks ) * 100 ) ;
209+ console . log ( `Upload Progress: ${ percentage } %` ) ;
210+
211+ // Increment the chunk number
212+ chunkNumber ++ ;
213+ } else {
214+ throw new Error ( `Failed to upload build` ) ;
164215 }
165- ) ;
216+ }
166217
167218 console . log ( 'Build Uploaded successfully' ) ;
168- return response ;
219+ return ;
169220 } catch ( error ) {
170221 console . error (
171- 'Error during post-build process :' ,
222+ 'Error during uploading the build :' ,
172223 error . response ?. data ?? error
173224 ) ;
174225 }
0 commit comments