Skip to content

Commit

Permalink
feat: add firebase-app-hosting preset
Browse files Browse the repository at this point in the history
  • Loading branch information
pi0 committed Nov 8, 2024
1 parent 536d79b commit b2867f8
Show file tree
Hide file tree
Showing 6 changed files with 107 additions and 16 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ staticwebapp.config.json
.eslintcache
playground/firebase.json
.zeabur
.apphosting

test/fixture/functions
.data
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@
"semver": "^7.6.3",
"serve-placeholder": "^2.0.2",
"serve-static": "^1.16.2",
"std-env": "^3.7.0",
"std-env": "^3.8.0",
"ufo": "^1.5.4",
"uncrypto": "^0.1.3",
"unctx": "^2.3.1",
Expand Down
18 changes: 9 additions & 9 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions src/presets/_types.gen.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,6 @@ export interface PresetOptions {

export const presetsWithConfig = ["awsAmplify","awsLambda","azure","cloudflare","firebase","netlify","vercel"] as const;

export type PresetName = "alwaysdata" | "aws-amplify" | "aws-lambda" | "azure" | "azure-functions" | "azure-swa" | "base-worker" | "bun" | "cleavr" | "cli" | "cloudflare" | "cloudflare-durable" | "cloudflare-module" | "cloudflare-module-legacy" | "cloudflare-pages" | "cloudflare-pages-static" | "cloudflare-worker" | "deno" | "deno-deploy" | "deno-server" | "digital-ocean" | "edgio" | "firebase" | "flight-control" | "genezio" | "github-pages" | "gitlab-pages" | "heroku" | "iis" | "iis-handler" | "iis-node" | "koyeb" | "layer0" | "netlify" | "netlify-builder" | "netlify-edge" | "netlify-legacy" | "netlify-static" | "nitro-dev" | "nitro-prerender" | "node" | "node-cluster" | "node-listener" | "node-server" | "platform-sh" | "render-com" | "service-worker" | "static" | "stormkit" | "vercel" | "vercel-edge" | "vercel-static" | "winterjs" | "zeabur" | "zeabur-static" | "zerops" | "zerops-static";
export type PresetName = "alwaysdata" | "aws-amplify" | "aws-lambda" | "azure" | "azure-functions" | "azure-swa" | "base-worker" | "bun" | "cleavr" | "cli" | "cloudflare" | "cloudflare-durable" | "cloudflare-module" | "cloudflare-module-legacy" | "cloudflare-pages" | "cloudflare-pages-static" | "cloudflare-worker" | "deno" | "deno-deploy" | "deno-server" | "digital-ocean" | "edgio" | "firebase" | "firebase-app-hosting" | "flight-control" | "genezio" | "github-pages" | "gitlab-pages" | "heroku" | "iis" | "iis-handler" | "iis-node" | "koyeb" | "layer0" | "netlify" | "netlify-builder" | "netlify-edge" | "netlify-legacy" | "netlify-static" | "nitro-dev" | "nitro-prerender" | "node" | "node-cluster" | "node-listener" | "node-server" | "platform-sh" | "render-com" | "service-worker" | "static" | "stormkit" | "vercel" | "vercel-edge" | "vercel-static" | "winterjs" | "zeabur" | "zeabur-static" | "zerops" | "zerops-static";

export type PresetNameInput = "alwaysdata" | "aws-amplify" | "awsAmplify" | "aws_amplify" | "aws-lambda" | "awsLambda" | "aws_lambda" | "azure" | "azure-functions" | "azureFunctions" | "azure_functions" | "azure-swa" | "azureSwa" | "azure_swa" | "base-worker" | "baseWorker" | "base_worker" | "bun" | "cleavr" | "cli" | "cloudflare" | "cloudflare-durable" | "cloudflareDurable" | "cloudflare_durable" | "cloudflare-module" | "cloudflareModule" | "cloudflare_module" | "cloudflare-module-legacy" | "cloudflareModuleLegacy" | "cloudflare_module_legacy" | "cloudflare-pages" | "cloudflarePages" | "cloudflare_pages" | "cloudflare-pages-static" | "cloudflarePagesStatic" | "cloudflare_pages_static" | "cloudflare-worker" | "cloudflareWorker" | "cloudflare_worker" | "deno" | "deno-deploy" | "denoDeploy" | "deno_deploy" | "deno-server" | "denoServer" | "deno_server" | "digital-ocean" | "digitalOcean" | "digital_ocean" | "edgio" | "firebase" | "flight-control" | "flightControl" | "flight_control" | "genezio" | "github-pages" | "githubPages" | "github_pages" | "gitlab-pages" | "gitlabPages" | "gitlab_pages" | "heroku" | "iis" | "iis-handler" | "iisHandler" | "iis_handler" | "iis-node" | "iisNode" | "iis_node" | "koyeb" | "layer0" | "netlify" | "netlify-builder" | "netlifyBuilder" | "netlify_builder" | "netlify-edge" | "netlifyEdge" | "netlify_edge" | "netlify-legacy" | "netlifyLegacy" | "netlify_legacy" | "netlify-static" | "netlifyStatic" | "netlify_static" | "nitro-dev" | "nitroDev" | "nitro_dev" | "nitro-prerender" | "nitroPrerender" | "nitro_prerender" | "node" | "node-cluster" | "nodeCluster" | "node_cluster" | "node-listener" | "nodeListener" | "node_listener" | "node-server" | "nodeServer" | "node_server" | "platform-sh" | "platformSh" | "platform_sh" | "render-com" | "renderCom" | "render_com" | "service-worker" | "serviceWorker" | "service_worker" | "static" | "stormkit" | "vercel" | "vercel-edge" | "vercelEdge" | "vercel_edge" | "vercel-static" | "vercelStatic" | "vercel_static" | "winterjs" | "zeabur" | "zeabur-static" | "zeaburStatic" | "zeabur_static" | "zerops" | "zerops-static" | "zeropsStatic" | "zerops_static" | (string & {});
export type PresetNameInput = "alwaysdata" | "aws-amplify" | "awsAmplify" | "aws_amplify" | "aws-lambda" | "awsLambda" | "aws_lambda" | "azure" | "azure-functions" | "azureFunctions" | "azure_functions" | "azure-swa" | "azureSwa" | "azure_swa" | "base-worker" | "baseWorker" | "base_worker" | "bun" | "cleavr" | "cli" | "cloudflare" | "cloudflare-durable" | "cloudflareDurable" | "cloudflare_durable" | "cloudflare-module" | "cloudflareModule" | "cloudflare_module" | "cloudflare-module-legacy" | "cloudflareModuleLegacy" | "cloudflare_module_legacy" | "cloudflare-pages" | "cloudflarePages" | "cloudflare_pages" | "cloudflare-pages-static" | "cloudflarePagesStatic" | "cloudflare_pages_static" | "cloudflare-worker" | "cloudflareWorker" | "cloudflare_worker" | "deno" | "deno-deploy" | "denoDeploy" | "deno_deploy" | "deno-server" | "denoServer" | "deno_server" | "digital-ocean" | "digitalOcean" | "digital_ocean" | "edgio" | "firebase" | "firebase-app-hosting" | "firebaseAppHosting" | "firebase_app_hosting" | "flight-control" | "flightControl" | "flight_control" | "genezio" | "github-pages" | "githubPages" | "github_pages" | "gitlab-pages" | "gitlabPages" | "gitlab_pages" | "heroku" | "iis" | "iis-handler" | "iisHandler" | "iis_handler" | "iis-node" | "iisNode" | "iis_node" | "koyeb" | "layer0" | "netlify" | "netlify-builder" | "netlifyBuilder" | "netlify_builder" | "netlify-edge" | "netlifyEdge" | "netlify_edge" | "netlify-legacy" | "netlifyLegacy" | "netlify_legacy" | "netlify-static" | "netlifyStatic" | "netlify_static" | "nitro-dev" | "nitroDev" | "nitro_dev" | "nitro-prerender" | "nitroPrerender" | "nitro_prerender" | "node" | "node-cluster" | "nodeCluster" | "node_cluster" | "node-listener" | "nodeListener" | "node_listener" | "node-server" | "nodeServer" | "node_server" | "platform-sh" | "platformSh" | "platform_sh" | "render-com" | "renderCom" | "render_com" | "service-worker" | "serviceWorker" | "service_worker" | "static" | "stormkit" | "vercel" | "vercel-edge" | "vercelEdge" | "vercel_edge" | "vercel-static" | "vercelStatic" | "vercel_static" | "winterjs" | "zeabur" | "zeabur-static" | "zeaburStatic" | "zeabur_static" | "zerops" | "zerops-static" | "zeropsStatic" | "zerops_static" | (string & {});
42 changes: 39 additions & 3 deletions src/presets/firebase/preset.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
import { defineNitroPreset } from "nitropack/kit";
import { basename } from "pathe";
import { defineNitroPreset, writeFile } from "nitropack/kit";
import { version as nitroVersion } from "nitropack/meta";
import { basename, join } from "pathe";
import type { Plugin } from "rollup";
import { genSafeVariableName } from "knitwork";
import { stringifyYAML } from "confbox";
import { updatePackageJSON, writeFirebaseConfig } from "./utils";
import type { AppHostingOptions, AppHostingOutputBundleConfig } from "./types";

export type { FirebaseOptions as PresetOptions } from "./types";

Expand Down Expand Up @@ -68,4 +71,37 @@ const firebase = defineNitroPreset(
}
);

export default [firebase] as const;
const firebaseAppHosting = defineNitroPreset(
{
extends: "node-server",
serveStatic: true,
hooks: {
async compiled(nitro) {
await writeFile(
join(nitro.options.rootDir, ".apphosting/bundle.yaml"),
stringifyYAML({
version: "v1",
runConfig: {
runCommand: "node .output/server/index.mjs",
...(nitro.options.firebase as AppHostingOptions)?.appHosting,
},
metadata: {
framework: nitro.options.framework.name || "nitropack",
frameworkVersion: nitro.options.framework.version || "2.x",
adapterPackageName: "nitropack",
adapterVersion: nitroVersion,
},
} satisfies AppHostingOutputBundleConfig),
true
);
},
},
},
{
name: "firebase-app-hosting" as const,
stdName: "firebase_app_hosting",
url: import.meta.url,
}
);

export default [firebase, firebaseAppHosting] as const;
56 changes: 55 additions & 1 deletion src/presets/firebase/types.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
import type { RuntimeOptions, region } from "firebase-functions";
import type { HttpsOptions } from "firebase-functions/v2/https";

export type FirebaseOptions = FirebaseOptionsGen1 | FirebaseOptionsGen2;
export type FirebaseOptions =
| FirebaseOptionsGen1
| FirebaseOptionsGen2
| AppHostingOptions;

// ---- Firebase Functions ----

export interface FirebaseOptionsBase {
gen: 1 | 2;
Expand Down Expand Up @@ -40,3 +45,52 @@ export interface FirebaseOptionsGen2 extends FirebaseOptionsBase {
*/
httpsOptions?: HttpsOptions;
}

// ---- Firebase App Hosting ----

export interface AppHostingOptions {
appHosting: Partial<AppHostingOutputBundleConfig["runConfig"]>;
}

// Source: https://github.com/FirebaseExtended/firebase-framework-tools/blob/main/packages/%40apphosting/common/src/index.ts
export interface AppHostingOutputBundleConfig {
version: "v1";

// Fields needed to configure the App Hosting server
runConfig: {
/** Command to start the server (e.g. "node dist/index.js"). Assume this command is run from the root dir of the workspace. */
runCommand: string;
/** Environment variables set when the app is run. */
environmentVariables?: Array<{
/** Name of the variable. */
variable: string;
/** Value associated with the variable. */
value: string;
/** Where the variable will be available, for now only RUNTIME is supported. */
availability: "RUNTIME"[];
}>;
// See https://firebase.google.com/docs/reference/apphosting/rest/v1beta/projects.locations.backends.builds#runconfig for documentation on the next fields
/** The maximum number of concurrent requests that each server instance can receive. */
concurrency?: number;
/** The number of CPUs used in a single server instance. */
cpu?: number;
/** The amount of memory available for a server instance. */
memoryMiB?: number;
/** The limit on the minimum number of function instances that may coexist at a given time. */
minInstances?: number;
/** The limit on the maximum number of function instances that may coexist at a given time. */
maxInstances?: number;
};

// Additional fields needed for identifying the framework and adapter being used
metadata: {
// Name of the adapter (this should be the official package name) e.g. "@apphosting/adapter-nextjs"
adapterPackageName: string;
// Version of the adapter, e.g. "18.0.1"
adapterVersion: string;
// Name of the framework that is being supported, e.g. "angular"
framework: string;
// Version of the framework that is being supported, e.g. "18.0.1"
frameworkVersion?: string;
};
}

0 comments on commit b2867f8

Please sign in to comment.