1
1
import * as subprocess from "child_process" ;
2
2
import * as path from "path" ;
3
3
import { promisify } from "util" ;
4
+ import * as fs from "fs/promises" ;
5
+ import * as os from "os" ;
4
6
5
7
import { expect } from "chai" ;
6
8
import * as yaml from "js-yaml" ;
@@ -185,15 +187,16 @@ async function runHttpDiscovery(modulePath: string): Promise<DiscoveryResult> {
185
187
}
186
188
}
187
189
188
- async function runStdioDiscovery ( modulePath : string ) : Promise < DiscoveryResult > {
190
+ async function runFileDiscovery ( modulePath : string ) : Promise < DiscoveryResult > {
191
+ const outputPath = path . join ( os . tmpdir ( ) , `firebase-functions-test-${ Date . now ( ) } .json` ) ;
192
+
189
193
return new Promise ( ( resolve , reject ) => {
190
194
const proc = subprocess . spawn ( "npx" , [ "firebase-functions" ] , {
191
195
cwd : path . resolve ( modulePath ) ,
192
196
env : {
193
197
PATH : process . env . PATH ,
194
198
GCLOUD_PROJECT : "test-project" ,
195
- FUNCTIONS_CONTROL_API : "true" ,
196
- FUNCTIONS_DISCOVERY_MODE : "stdio" ,
199
+ FUNCTIONS_MANIFEST_OUTPUT_PATH : outputPath ,
197
200
} ,
198
201
} ) ;
199
202
@@ -205,31 +208,26 @@ async function runStdioDiscovery(modulePath: string): Promise<DiscoveryResult> {
205
208
206
209
const timeoutId = setTimeout ( ( ) => {
207
210
proc . kill ( 9 ) ;
208
- reject ( new Error ( `Stdio discovery timed out after ${ TIMEOUT_M } ms`) ) ;
211
+ resolve ( { success : false , error : `File discovery timed out after ${ TIMEOUT_M } ms` } ) ;
209
212
} , TIMEOUT_M ) ;
210
213
211
- proc . on ( "close" , ( ) => {
214
+ proc . on ( "close" , async ( code ) => {
212
215
clearTimeout ( timeoutId ) ;
213
- const manifestMatch = stderr . match (
214
- / < F I R E B A S E _ F U N C T I O N S _ M A N I F E S T > \n ( [ \s \S ] + ?) \n < \/ F I R E B A S E _ F U N C T I O N S _ M A N I F E S T > /
215
- ) ;
216
- if ( manifestMatch ) {
217
- const base64 = manifestMatch [ 1 ] ;
218
- const manifestJson = Buffer . from ( base64 , "base64" ) . toString ( "utf8" ) ;
219
- const manifest = JSON . parse ( manifestJson ) as Record < string , unknown > ;
220
- resolve ( { success : true , manifest } ) ;
221
- return ;
222
- }
223
-
224
- const errorMatch = stderr . match (
225
- / < F I R E B A S E _ F U N C T I O N S _ M A N I F E S T _ E R R O R > \n ( [ \s \S ] + ?) \n < \/ F I R E B A S E _ F U N C T I O N S _ M A N I F E S T _ E R R O R > /
226
- ) ;
227
- if ( errorMatch ) {
228
- resolve ( { success : false , error : errorMatch [ 1 ] } ) ;
229
- return ;
216
+
217
+ if ( code === 0 ) {
218
+ try {
219
+ const manifestJson = await fs . readFile ( outputPath , "utf8" ) ;
220
+ const manifest = JSON . parse ( manifestJson ) as Record < string , unknown > ;
221
+ await fs . unlink ( outputPath ) . catch ( ( ) => { } ) ;
222
+ resolve ( { success : true , manifest } ) ;
223
+ } catch ( e ) {
224
+ resolve ( { success : false , error : `Failed to read manifest file: ${ e } ` } ) ;
225
+ }
226
+ } else {
227
+ const errorLines = stderr . split ( '\n' ) . filter ( line => line . trim ( ) ) ;
228
+ const errorMessage = errorLines . join ( ' ' ) || "No error message found" ;
229
+ resolve ( { success : false , error : errorMessage } ) ;
230
230
}
231
-
232
- resolve ( { success : false , error : "No manifest or error found" } ) ;
233
231
} ) ;
234
232
235
233
proc . on ( "error" , ( err ) => {
@@ -245,7 +243,7 @@ describe("functions.yaml", function () {
245
243
246
244
const discoveryMethods = [
247
245
{ name : "http" , fn : runHttpDiscovery } ,
248
- { name : "stdio " , fn : runStdioDiscovery } ,
246
+ { name : "file " , fn : runFileDiscovery } ,
249
247
] ;
250
248
251
249
function runDiscoveryTests (
0 commit comments