Guest User

Untitled

a guest
Jan 9th, 2025
15
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. import { createFetch } from "@better-fetch/fetch";
  2. import { createClient } from "@supabase/supabase-js";
  3. import { validateAccessToken } from "./avatarTokens";
  4.  
  5. /**
  6.  * Interface representing the environment variables required for the application.
  7.  */
  8. export interface Env {
  9.     SUPABASE_URL: string;
  10.     SUPABASE_KEY: string;
  11.     SUPABASE_STORAGE_BUCKET_NAME: string;
  12. }
  13.  
  14. /**
  15.  * Fetch handler for processing user image requests.
  16.  *
  17.  * u/param request - The incoming request object.
  18.  * u/param env - The environment variables containing configuration such as Supabase URL and keys.
  19.  * @param ctx - The execution context for the request.
  20.  * @returns A promise that resolves to a Response object.
  21.  */
  22. export default {
  23.     async fetch(
  24.         request: Request,
  25.         env: Env,
  26.         ctx: ExecutionContext,
  27.     ): Promise<Response> {
  28.         // Get the user id and access token from the request path
  29.         const [userId, accessToken] =
  30.             (new URL(request.url).pathname || "/")
  31.                 .split("/")
  32.                 ?.filter((part) => part !== "") || [];
  33.  
  34.         // Make sure the user id and access tokens are populated. If empty, return 400
  35.         if (userId === "" || accessToken === "")
  36.             return new Response("Malformed Request (Bad Request)", {
  37.                 status: 400,
  38.             });
  39.  
  40.         // Validate the access token. If invalid, return 401
  41.         if (validateAccessToken(accessToken) === false)
  42.             return new Response("Unauthorized", { status: 401 });
  43.  
  44.         // Read the response headers into a constant
  45.         const responseHeaders = new Headers();
  46.  
  47.         // Extract the visitor IP address
  48.         const ip = request.headers.get("CF-Connecting-IP") as string;
  49.  
  50.         // Initialise better-fetch for use with Supabase
  51.         const $fetch = createFetch({
  52.             headers: {
  53.                 "X-Forwarded-For": ip,
  54.             },
  55.             retry: 2,
  56.             onRetry: (response) => {
  57.                 console.log("Retrying request...");
  58.             },
  59.         });
  60.  
  61.         // Initialize the Supabase client
  62.         const supabase = createClient(env.SUPABASE_URL, env.SUPABASE_KEY, {
  63.             db: {
  64.                 schema: "public",
  65.             },
  66.             global: { fetch: $fetch },
  67.         });
  68.  
  69.         // Retrieve the user avatar from the Storage bucket
  70.         const { data } = supabase.storage
  71.             .from(env.SUPABASE_STORAGE_BUCKET_NAME)
  72.             .getPublicUrl(`${userId}.jpg`);
  73.  
  74.         console.log(userId, data);
  75.  
  76.         // If the image is not found, return 404
  77.         if (!data) return new Response("Not Found", { status: 404 });
  78.  
  79.         // Resize the image to 100x100
  80.         const resizedImage = await resizeImage({
  81.             url: new URL(data?.publicUrl as string),
  82.             width: 100,
  83.             height: 100,
  84.             quality: 100,
  85.             request,
  86.         });
  87.  
  88.         // Return the resized image
  89.         return resizedImage;
  90.     },
  91. } satisfies ExportedHandler<Env>;
  92.  
  93. /**
  94.  * Resizes an image from a given URL using Cloudflare-specific options.
  95.  *
  96.  * @param {Object} params - The parameters for resizing the image.
  97.  * @param {string} params.url - The URL of the image to resize.
  98.  * @param {number} params.width - The desired width of the resized image.
  99.  * @param {number} params.height - The desired height of the resized image.
  100.  * @param {number} params.quality - The quality of the resized image.
  101.  * @param {Request} params.request - The original request object containing headers.
  102.  * @returns {Promise<Response>} A promise that resolves to the response containing the resized image.
  103.  */
  104. const resizeImage = async ({
  105.     url,
  106.     width,
  107.     height,
  108.     quality,
  109.     request,
  110. }: ResizeImageProps) => {
  111.     // Automatically correct the height, width, and quality values if required
  112.     width = height = Math.max(1, Math.min(256, Math.round(width)));
  113.     quality = Math.max(1, Math.min(100, Math.round(quality)));
  114.  
  115.     // Cloudflare-specific options are in the cf object.
  116.     const options: RequestInit<RequestInitCfProperties> = {
  117.         cf: {
  118.             image: {
  119.                 width,
  120.                 height,
  121.                 quality,
  122.                 format: "webp",
  123.                 anim: false,
  124.                 fit: "crop",
  125.                 gravity: "auto",
  126.                 metadata: "none",
  127.             },
  128.         },
  129.     };
  130.  
  131.     // Build a request that passes through request headers
  132.     const imageRequest = new Request(url, {
  133.         headers: request.headers,
  134.     });
  135.  
  136.     // Returning fetch() with resizing options will pass through response with the resized image.
  137.     return await fetch(imageRequest, options);
  138. };
  139.  
  140. /**
  141.  * Interface representing the properties required to resize an image.
  142.  */
  143. export interface ResizeImageProps {
  144.     /**
  145.      * The URL of the image to be resized.
  146.      */
  147.     url: URL;
  148.  
  149.     /**
  150.      * The desired width of the resized image.
  151.      */
  152.     width: number;
  153.  
  154.     /**
  155.      * The desired height of the resized image.
  156.      */
  157.     height: number;
  158.  
  159.     /**
  160.      * The quality of the resized image.
  161.      */
  162.     quality: number;
  163.  
  164.     /**
  165.      * The request object associated with the image resizing operation.
  166.      */
  167.     request: Request;
  168. }
Advertisement
Add Comment
Please, Sign In to add comment