Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import { createFetch } from "@better-fetch/fetch";
- import { createClient } from "@supabase/supabase-js";
- import { validateAccessToken } from "./avatarTokens";
- /**
- * Interface representing the environment variables required for the application.
- */
- export interface Env {
- SUPABASE_URL: string;
- SUPABASE_KEY: string;
- SUPABASE_STORAGE_BUCKET_NAME: string;
- }
- /**
- * Fetch handler for processing user image requests.
- *
- * u/param request - The incoming request object.
- * u/param env - The environment variables containing configuration such as Supabase URL and keys.
- * @param ctx - The execution context for the request.
- * @returns A promise that resolves to a Response object.
- */
- export default {
- async fetch(
- request: Request,
- env: Env,
- ctx: ExecutionContext,
- ): Promise<Response> {
- // Get the user id and access token from the request path
- const [userId, accessToken] =
- (new URL(request.url).pathname || "/")
- .split("/")
- ?.filter((part) => part !== "") || [];
- // Make sure the user id and access tokens are populated. If empty, return 400
- if (userId === "" || accessToken === "")
- return new Response("Malformed Request (Bad Request)", {
- status: 400,
- });
- // Validate the access token. If invalid, return 401
- if (validateAccessToken(accessToken) === false)
- return new Response("Unauthorized", { status: 401 });
- // Read the response headers into a constant
- const responseHeaders = new Headers();
- // Extract the visitor IP address
- const ip = request.headers.get("CF-Connecting-IP") as string;
- // Initialise better-fetch for use with Supabase
- const $fetch = createFetch({
- headers: {
- "X-Forwarded-For": ip,
- },
- retry: 2,
- onRetry: (response) => {
- console.log("Retrying request...");
- },
- });
- // Initialize the Supabase client
- const supabase = createClient(env.SUPABASE_URL, env.SUPABASE_KEY, {
- db: {
- schema: "public",
- },
- global: { fetch: $fetch },
- });
- // Retrieve the user avatar from the Storage bucket
- const { data } = supabase.storage
- .from(env.SUPABASE_STORAGE_BUCKET_NAME)
- .getPublicUrl(`${userId}.jpg`);
- console.log(userId, data);
- // If the image is not found, return 404
- if (!data) return new Response("Not Found", { status: 404 });
- // Resize the image to 100x100
- const resizedImage = await resizeImage({
- url: new URL(data?.publicUrl as string),
- width: 100,
- height: 100,
- quality: 100,
- request,
- });
- // Return the resized image
- return resizedImage;
- },
- } satisfies ExportedHandler<Env>;
- /**
- * Resizes an image from a given URL using Cloudflare-specific options.
- *
- * @param {Object} params - The parameters for resizing the image.
- * @param {string} params.url - The URL of the image to resize.
- * @param {number} params.width - The desired width of the resized image.
- * @param {number} params.height - The desired height of the resized image.
- * @param {number} params.quality - The quality of the resized image.
- * @param {Request} params.request - The original request object containing headers.
- * @returns {Promise<Response>} A promise that resolves to the response containing the resized image.
- */
- const resizeImage = async ({
- url,
- width,
- height,
- quality,
- request,
- }: ResizeImageProps) => {
- // Automatically correct the height, width, and quality values if required
- width = height = Math.max(1, Math.min(256, Math.round(width)));
- quality = Math.max(1, Math.min(100, Math.round(quality)));
- // Cloudflare-specific options are in the cf object.
- const options: RequestInit<RequestInitCfProperties> = {
- cf: {
- image: {
- width,
- height,
- quality,
- format: "webp",
- anim: false,
- fit: "crop",
- gravity: "auto",
- metadata: "none",
- },
- },
- };
- // Build a request that passes through request headers
- const imageRequest = new Request(url, {
- headers: request.headers,
- });
- // Returning fetch() with resizing options will pass through response with the resized image.
- return await fetch(imageRequest, options);
- };
- /**
- * Interface representing the properties required to resize an image.
- */
- export interface ResizeImageProps {
- /**
- * The URL of the image to be resized.
- */
- url: URL;
- /**
- * The desired width of the resized image.
- */
- width: number;
- /**
- * The desired height of the resized image.
- */
- height: number;
- /**
- * The quality of the resized image.
- */
- quality: number;
- /**
- * The request object associated with the image resizing operation.
- */
- request: Request;
- }
Advertisement
Add Comment
Please, Sign In to add comment