Skip to content

Commit bf5e751

Browse files
committed
feat: add stdio-based function discovery mode
Adds an alternative discovery mechanism that outputs function manifests via stderr instead of starting an HTTP server. This improves reliability by avoiding issues where module loading blocks the HTTP endpoint from becoming available. When FUNCTIONS_DISCOVERY_MODE=stdio is set: - Outputs base64-encoded manifest to stderr with __FIREBASE_FUNCTIONS_MANIFEST__: prefix - Outputs errors to stderr with __FIREBASE_FUNCTIONS_MANIFEST_ERROR__: prefix - Exits immediately without starting HTTP server - Maintains backward compatibility (HTTP remains default)
1 parent 534505c commit bf5e751

File tree

1 file changed

+45
-26
lines changed

1 file changed

+45
-26
lines changed

src/bin/firebase-functions.ts

Lines changed: 45 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -49,34 +49,53 @@ if (args.length > 1) {
4949
functionsDir = args[0];
5050
}
5151

52-
let server: http.Server = undefined;
53-
const app = express();
54-
55-
function handleQuitquitquit(req: express.Request, res: express.Response) {
56-
res.send("ok");
57-
server.close();
52+
async function runStdioDiscovery() {
53+
try {
54+
const stack = await loadStack(functionsDir);
55+
const wireFormat = stackToWire(stack);
56+
const manifestJson = JSON.stringify(wireFormat);
57+
const base64 = Buffer.from(manifestJson).toString("base64");
58+
process.stderr.write(`__FIREBASE_FUNCTIONS_MANIFEST__:${base64}\n`);
59+
process.exit(0);
60+
} catch (e) {
61+
console.error("Failed to generate manifest from function source:", e);
62+
process.stderr.write(`__FIREBASE_FUNCTIONS_MANIFEST_ERROR__:${e.message}\n`);
63+
process.exit(1);
64+
}
5865
}
5966

60-
app.get("/__/quitquitquit", handleQuitquitquit);
61-
app.post("/__/quitquitquit", handleQuitquitquit);
67+
if (process.env.FUNCTIONS_CONTROL_API === "true" && process.env.FUNCTIONS_DISCOVERY_MODE === "stdio") {
68+
runStdioDiscovery();
69+
} else {
70+
let server: http.Server = undefined;
71+
const app = express();
6272

63-
if (process.env.FUNCTIONS_CONTROL_API === "true") {
64-
app.get("/__/functions.yaml", async (req, res) => {
65-
try {
66-
const stack = await loadStack(functionsDir);
67-
res.setHeader("content-type", "text/yaml");
68-
res.send(JSON.stringify(stackToWire(stack)));
69-
} catch (e) {
70-
console.error(e);
71-
res.status(400).send(`Failed to generate manifest from function source: ${e}`);
72-
}
73-
});
74-
}
73+
function handleQuitquitquit(req: express.Request, res: express.Response) {
74+
res.send("ok");
75+
server.close();
76+
}
7577

76-
let port = 8080;
77-
if (process.env.PORT) {
78-
port = Number.parseInt(process.env.PORT);
79-
}
78+
app.get("/__/quitquitquit", handleQuitquitquit);
79+
app.post("/__/quitquitquit", handleQuitquitquit);
8080

81-
console.log("Serving at port", port);
82-
server = app.listen(port);
81+
if (process.env.FUNCTIONS_CONTROL_API === "true") {
82+
app.get("/__/functions.yaml", async (req, res) => {
83+
try {
84+
const stack = await loadStack(functionsDir);
85+
res.setHeader("content-type", "text/yaml");
86+
res.send(JSON.stringify(stackToWire(stack)));
87+
} catch (e) {
88+
console.error(e);
89+
res.status(400).send(`Failed to generate manifest from function source: ${e}`);
90+
}
91+
});
92+
}
93+
94+
let port = 8080;
95+
if (process.env.PORT) {
96+
port = Number.parseInt(process.env.PORT);
97+
}
98+
99+
console.log("Serving at port", port);
100+
server = app.listen(port);
101+
}

0 commit comments

Comments
 (0)