Skip to content

Instantly share code, notes, and snippets.

@danReynolds
Created March 21, 2024 22:30
Show Gist options
  • Save danReynolds/f3ae575bc08c7c5177975ed70a7e09b3 to your computer and use it in GitHub Desktop.
Save danReynolds/f3ae575bc08c7c5177975ed70a7e09b3 to your computer and use it in GitHub Desktop.
function wrappers
import { ZodTypeAny, z } from "zod";
import {
DeploymentOptions,
FunctionBuilder,
https,
} from "firebase-functions/v1";
import { assert, validate } from "./validate.js";
import Logger from "./logger.js";
const logger = new Logger("Precheck");
// The onCall pre-check is used as a pre-execute step for cloud functions. It validates user auth
// and request schemas for all routes.
function onCallPrecheck<T extends ZodTypeAny>(
originalFn: any,
{
requireAuthentication,
schema,
}: {
requireAuthentication: boolean;
schema?: T;
}
) {
return (
handler: (
data: z.infer<T>,
context: https.CallableContext
) => any | Promise<any>
) =>
originalFn((data: any, context: https.CallableContext) => {
logger.log("Pre-check started.");
// If authentication is required on the route, then validate that the auth user is present.
assert(!requireAuthentication || !!context.auth?.uid, "Failed precheck");
// Validate the route request schema.
if (schema) {
validate(schema, data);
}
logger.log("Pre-check complete.");
return handler(data, context);
});
}
export function runWith<T extends ZodTypeAny>(
options: DeploymentOptions & {
schema?: T;
requireAuthentication?: boolean;
}
) {
const {
schema,
requireAuthentication = true,
...deploymentOptions
} = options;
const functionBuilder = new FunctionBuilder({
...deploymentOptions,
});
return {
onCall: onCallPrecheck(functionBuilder.https.onCall, {
schema,
requireAuthentication,
}),
};
}
export function onCall<T extends ZodTypeAny>(
schema: T,
handler: (
request: z.infer<T>,
context: https.CallableContext
) => any | Promise<any>
) {
const { onCall: _onCall } = runWith({
schema,
});
return _onCall(handler);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment