From 5bd05e4099c1d8081ec52912068e994de91aabfe Mon Sep 17 00:00:00 2001 From: thorwebdev Date: Fri, 17 Feb 2023 14:09:27 +0800 Subject: [PATCH] chore: update to import_map and serve. --- examples/edge-functions/README.md | 21 +++++------ .../edge-functions.code-workspace | 3 +- .../supabase/.env.local.example | 25 +++++++++++-- .../supabase/functions/.vscode/settings.json | 4 +- .../functions/browser-with-cors/index.ts | 2 +- .../functions/cloudflare-turnstile/README.md | 4 ++ .../functions/cloudflare-turnstile/index.ts | 4 +- .../supabase/functions/discord-bot/README.md | 6 ++- .../supabase/functions/discord-bot/index.ts | 4 +- .../functions/file-upload-storage/index.ts | 8 ++-- .../get-tshirt-competition/README.md | 4 +- .../functions/get-tshirt-competition/index.ts | 4 +- .../functions/github-action-deploy/index.ts | 21 ++++------- .../supabase/functions/import_map.json | 18 +++++++++ .../supabase/functions/location/README.md | 8 ++++ .../supabase/functions/location/index.ts | 29 ++++++++++----- .../supabase/functions/oak-server/README.md | 4 +- .../supabase/functions/oak-server/index.ts | 2 +- .../og-image-with-storage-cdn/README.md | 2 +- .../og-image-with-storage-cdn/handler.tsx | 8 ++-- .../og-image-with-storage-cdn/index.ts | 2 +- .../supabase/functions/opengraph/README.md | 2 +- .../supabase/functions/opengraph/handler.tsx | 4 +- .../supabase/functions/opengraph/index.ts | 2 +- .../functions/postgres-on-the-edge/index.ts | 4 +- .../supabase/functions/puppeteer/README.md | 8 ++++ .../supabase/functions/puppeteer/index.ts | 11 ++++-- .../supabase/functions/read-storage/index.ts | 4 +- .../supabase/functions/restful-tasks/index.ts | 4 +- .../select-from-table-with-auth-rls/index.ts | 4 +- .../functions/send-email-smtp/README.md | 2 +- .../functions/send-email-smtp/index.ts | 10 ++--- .../functions/stripe-webhooks/README.md | 2 +- .../functions/stripe-webhooks/index.ts | 37 +++++-------------- .../supabase/functions/telegram-bot/index.ts | 24 +++++------- .../upstash-redis-counter/.env.example | 2 - .../functions/upstash-redis-counter/README.md | 6 +-- .../functions/upstash-redis-counter/index.ts | 4 +- 38 files changed, 177 insertions(+), 136 deletions(-) create mode 100644 examples/edge-functions/supabase/functions/import_map.json delete mode 100644 examples/edge-functions/supabase/functions/upstash-redis-counter/.env.example diff --git a/examples/edge-functions/README.md b/examples/edge-functions/README.md index f32e56e2357..47e624783a9 100644 --- a/examples/edge-functions/README.md +++ b/examples/edge-functions/README.md @@ -6,23 +6,17 @@ ## Example Functions -The function examples are located in [`./supabase/functions`](./supabase/functions): - -- [`browser-with-cors`](./supabase/functions/browser-with-cors/index.ts): Handle CORS headers for function invocations from browser environments. -- [`select-from-table-with-auth-rls`](./supabase/functions/select-from-table-with-auth-rls/index.ts): Retrieve data from an authenticated user via RLS. -- [`send-email-smtp`](./supabase/functions/send-email-smtp/index.ts): Send an email using SMTP credentials. -- [`stripe-webhooks`](./supabase/functions/stripe-webhooks/index.ts): Handle Stripe Webhooks. -- [`telegram-bot`](./supabase/functions/telegram-bot/index.ts): Webhook handler for Telegram bots using [grammY](https://grammy.dev/). +We're constantly adding new Function Examples, [check our docs](https://supabase.com/docs/guides/functions#examples) for a complete list! ## Develop locally - Run `supabase start` (make sure your Docker daemon is running.) -- Run `mv ./supabase/.env.local.example ./supabase/.env.local` to rename the local `.env` file. -- Set the required variables to run the desired edge functions in the `.env.local` file. -- Run `supabase functions serve your-function-name --env-file ./supabase/.env.local` +- Run `cp ./supabase/.env.local.example ./supabase/.env.local` to create your local `.env` file. +- Set the required variables for the corresponding edge functions in the `.env.local` file. +- Run `supabase functions serve --env-file ./supabase/.env.local --no-verify-jwt` - Run the CURL command in the example function, or use the [invoke method](https://supabase.com/docs/reference/javascript/invoke) on the Supabase client or use the test client [app](./app/). -## Test +## Test Client This example includes a create-react-app in the [`./app/`](./app/) directory which you can use as a sort of postman to make test requests both locally and to your deployed functions. @@ -45,10 +39,13 @@ Note: when testing locally, the select dropdown doesn't have any effect, and inv - Link your project - Within your project root run `supabase link --project-ref your-project-ref` - Set up your secrets + - Run `supabase secrets set --env-file ./supabase/.env.local` to set the environment variables. - + (This is assuming your local and production secrets are the same. The recommended way is to create a separate `.env` file for storing production secrets, and then use it to set the environment variables while deploying.) + - You can run `supabase secrets list` to check that it worked and also to see what other env vars are set by default. + - Deploy the function - Within your project root run `supabase functions deploy your-function-name` - In your [`./app/.env`](./app/.env) file remove the `SUPA_FUNCTION_LOCALHOST` variable and restart your Expo app. diff --git a/examples/edge-functions/edge-functions.code-workspace b/examples/edge-functions/edge-functions.code-workspace index 80054980ded..d3e694fd61c 100644 --- a/examples/edge-functions/edge-functions.code-workspace +++ b/examples/edge-functions/edge-functions.code-workspace @@ -18,6 +18,7 @@ "node_modules/": true, "app/": true, "supabase/functions/": true - } + }, + "deno.importMap": "./supabase/functions/import_map.json" } } diff --git a/examples/edge-functions/supabase/.env.local.example b/examples/edge-functions/supabase/.env.local.example index 2f2c44b56a5..981b2fdc1c4 100644 --- a/examples/edge-functions/supabase/.env.local.example +++ b/examples/edge-functions/supabase/.env.local.example @@ -1,3 +1,18 @@ +# cloudflare-turnstile +CLOUDFLARE_TURNSTILE_SECRET_KEY=your_secret_key + +# discord-bot +DISCORD_PUBLIC_KEY= + +# location +IPINFO_TOKEN="your https://ipinfo.io token" + +# postgres-on-the-edge +DATABASE_URL= + +# puppeteer +PUPPETEER_BROWSERLESS_IO_TOKEN= + # send-email-smtp SMTP_HOSTNAME="your.hostname.com" SMTP_PORT="2587" @@ -5,10 +20,14 @@ SMTP_USERNAME="your_username" SMTP_PASSWORD="your_password" SMTP_FROM="no-reply@example.com" +# stripe-webhooks +STRIPE_API_KEY="" +STRIPE_WEBHOOK_SIGNING_SECRET="" + # telegram-bot TELEGRAM_BOT_TOKEN="get it from https://t.me/BotFather" FUNCTION_SECRET="random secret" -# stripe-webhooks -STRIPE_API_KEY="" -STRIPE_WEBHOOK_SIGNING_SECRET="" \ No newline at end of file +# upstash-redis-counter +UPSTASH_REDIS_REST_URL= +UPSTASH_REDIS_REST_TOKEN= \ No newline at end of file diff --git a/examples/edge-functions/supabase/functions/.vscode/settings.json b/examples/edge-functions/supabase/functions/.vscode/settings.json index e40716fdd7e..1d800e858b2 100644 --- a/examples/edge-functions/supabase/functions/.vscode/settings.json +++ b/examples/edge-functions/supabase/functions/.vscode/settings.json @@ -1,5 +1,5 @@ { "deno.enable": true, - "deno.lint": true, - "deno.unstable": true + "deno.unstable": true, + "deno.importMap": "./import_map.json" } diff --git a/examples/edge-functions/supabase/functions/browser-with-cors/index.ts b/examples/edge-functions/supabase/functions/browser-with-cors/index.ts index 1ab04de4e1f..d022ef6035f 100644 --- a/examples/edge-functions/supabase/functions/browser-with-cors/index.ts +++ b/examples/edge-functions/supabase/functions/browser-with-cors/index.ts @@ -2,7 +2,7 @@ // https://deno.land/manual/getting_started/setup_your_environment // This enables autocomplete, go to definition, etc. -import { serve } from 'https://deno.land/std@0.131.0/http/server.ts' +import { serve } from 'std/server' import { corsHeaders } from '../_shared/cors.ts' console.log(`Function "browser-with-cors" up and running!`) diff --git a/examples/edge-functions/supabase/functions/cloudflare-turnstile/README.md b/examples/edge-functions/supabase/functions/cloudflare-turnstile/README.md index 4d8bc5008cd..3ec3bf986bc 100644 --- a/examples/edge-functions/supabase/functions/cloudflare-turnstile/README.md +++ b/examples/edge-functions/supabase/functions/cloudflare-turnstile/README.md @@ -2,6 +2,10 @@ Turnstile is Cloudflare's CAPTCHA alternative: https://developers.cloudflare.com/turnstile/get-started/ +## Watch the Video Tutorial + +[![video tutorial](https://img.youtube.com/vi/OwW0znboh60/0.jpg)](https://www.youtube.com/watch?v=OwW0znboh60) + ## Setup - Follow these steps to set up a new site: https://developers.cloudflare.com/turnstile/get-started/ diff --git a/examples/edge-functions/supabase/functions/cloudflare-turnstile/index.ts b/examples/edge-functions/supabase/functions/cloudflare-turnstile/index.ts index 5d831d18ab7..02e440f3460 100644 --- a/examples/edge-functions/supabase/functions/cloudflare-turnstile/index.ts +++ b/examples/edge-functions/supabase/functions/cloudflare-turnstile/index.ts @@ -2,7 +2,7 @@ // https://deno.land/manual/getting_started/setup_your_environment // This enables autocomplete, go to definition, etc. -import { serve } from 'https://deno.land/std@0.131.0/http/server.ts' +import { serve } from 'std/server' import { corsHeaders } from '../_shared/cors.ts' console.log(`Function "cloudflare-turnstile" up and running!`) @@ -55,7 +55,7 @@ serve(async (req) => { }) // To invoke: -// curl -i --location --request POST 'http://localhost:54321/functions/v1/' \ +// curl -i --location --request POST 'http://localhost:54321/functions/v1/cloudflare-turnstile' \ // --header 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZS1kZW1vIiwicm9sZSI6ImFub24iLCJleHAiOjE5ODM4MTI5OTZ9.CRXP1A7WOeoJeXxjNni43kdQwgnWNReilDMblYTn_I0' \ // --header 'Content-Type: application/json' \ // --data '{"token":"cf-turnstile-response"}' diff --git a/examples/edge-functions/supabase/functions/discord-bot/README.md b/examples/edge-functions/supabase/functions/discord-bot/README.md index 5e9ad79f29b..7d66deb798c 100644 --- a/examples/edge-functions/supabase/functions/discord-bot/README.md +++ b/examples/edge-functions/supabase/functions/discord-bot/README.md @@ -5,6 +5,10 @@ - https://deno.com/deploy/docs/tutorial-discord-slash - https://discord.com/developers/docs/interactions/application-commands#slash-commands +## Watch the Video Tutorial + +[![video tutorial](https://img.youtube.com/vi/J24Bvo_m7DM/0.jpg)](https://www.youtube.com/watch?v=J24Bvo_m7DM) + ## Create an application on Discord Developer Portal 1. Go to [https://discord.com/developers/applications](https://discord.com/developers/applications) (login using your discord account if required). @@ -59,6 +63,6 @@ Open Discord, type `/Promise` and press **Enter**. ## Run locally ```bash -supabase functions serve discord-bot --no-verify-jwt --env-file ./supabase/functions/discord-bot/.env +supabase functions serve discord-bot --no-verify-jwt --env-file ./supabase/.env.local ngrok http 54321 ``` diff --git a/examples/edge-functions/supabase/functions/discord-bot/index.ts b/examples/edge-functions/supabase/functions/discord-bot/index.ts index 140bb30b767..abbf5985f2d 100644 --- a/examples/edge-functions/supabase/functions/discord-bot/index.ts +++ b/examples/edge-functions/supabase/functions/discord-bot/index.ts @@ -5,10 +5,10 @@ // Sift is a small routing library that abstracts away details like starting a // listener on a port, and provides a simple function (serve) that has an API // to invoke a function for a specific path. -import { json, serve, validateRequest } from 'https://deno.land/x/sift@0.6.0/mod.ts' +import { json, serve, validateRequest } from 'sift' // TweetNaCl is a cryptography library that we use to verify requests // from Discord. -import nacl from 'https://cdn.skypack.dev/tweetnacl@v1.0.3?dts' +import nacl from 'nacl' enum DiscordCommandType { Ping = 1, diff --git a/examples/edge-functions/supabase/functions/file-upload-storage/index.ts b/examples/edge-functions/supabase/functions/file-upload-storage/index.ts index 5593c0b6581..208619a7b49 100644 --- a/examples/edge-functions/supabase/functions/file-upload-storage/index.ts +++ b/examples/edge-functions/supabase/functions/file-upload-storage/index.ts @@ -1,8 +1,8 @@ // This example shows how to use Edge Functions to read incoming multipart/form-data request, // and write files to Supabase Storage and other fields to a database table. -import { Application, Router } from 'https://deno.land/x/oak/mod.ts' -import { createClient } from 'https://esm.sh/@supabase/supabase-js@2' +import { Application } from 'oak' +import { createClient } from '@supabase/supabase-js' const MB = 1024 * 1024 @@ -25,9 +25,9 @@ app.use(async (ctx) => { const supabaseClient = createClient( // Supabase API URL - env var exported by default. - Deno.env.get('SUPABASE_URL') ?? '', + Deno.env.get('SUPABASE_URL')!, // Supabase API ANON KEY - env var exported by default. - Deno.env.get('SUPABASE_ANON_KEY') ?? '' + Deno.env.get('SUPABASE_ANON_KEY')! ) //upload image to Storage diff --git a/examples/edge-functions/supabase/functions/get-tshirt-competition/README.md b/examples/edge-functions/supabase/functions/get-tshirt-competition/README.md index 8d0bcb0dd72..b83a049526c 100644 --- a/examples/edge-functions/supabase/functions/get-tshirt-competition/README.md +++ b/examples/edge-functions/supabase/functions/get-tshirt-competition/README.md @@ -15,9 +15,11 @@ Good luck trying to GET a T-Shirt! ### Serve this function locally ```bash -supabase functions serve --no-verify-jwt get-tshirt-competition +supabase functions serve --no-verify-jwt ``` +Navigate to http://localhost:54321/functions/v1/get-tshirt-competition?email=testr@test.de&twitter=thorwebdev&size=2XL&answer=20 + ### Deploy this function ```bash diff --git a/examples/edge-functions/supabase/functions/get-tshirt-competition/index.ts b/examples/edge-functions/supabase/functions/get-tshirt-competition/index.ts index 01e03605441..76b09b974c9 100644 --- a/examples/edge-functions/supabase/functions/get-tshirt-competition/index.ts +++ b/examples/edge-functions/supabase/functions/get-tshirt-competition/index.ts @@ -2,8 +2,8 @@ // https://deno.land/manual/getting_started/setup_your_environment // This enables autocomplete, go to definition, etc. -import { serve } from 'https://deno.land/std@0.131.0/http/server.ts' -import { createClient } from 'https://esm.sh/@supabase/supabase-js@2' +import { serve } from 'std/server' +import { createClient } from '@supabase/supabase-js' import { corsHeaders } from '../_shared/cors.ts' console.log(`Function "get-tshirt-competition" up and running!`) diff --git a/examples/edge-functions/supabase/functions/github-action-deploy/index.ts b/examples/edge-functions/supabase/functions/github-action-deploy/index.ts index 2dc629d0cf8..423445b1608 100644 --- a/examples/edge-functions/supabase/functions/github-action-deploy/index.ts +++ b/examples/edge-functions/supabase/functions/github-action-deploy/index.ts @@ -2,23 +2,18 @@ // https://deno.land/manual/getting_started/setup_your_environment // This enables autocomplete, go to definition, etc. -import { serve } from "https://deno.land/std@0.131.0/http/server.ts"; +import { serve } from 'std/server' -console.log("Hello from Functions!"); +console.log('Hello from Functions!') -serve(async (req) => { - const { name } = await req.json(); +serve((_req) => { const data = { message: `I was deployed via GitHub Actions!`, - }; + } return new Response(JSON.stringify(data), { - headers: { "Content-Type": "application/json" }, - }); -}); + headers: { 'Content-Type': 'application/json' }, + }) +}) -// To invoke: -// curl -i --location --request POST 'http://localhost:54321/functions/v1/' \ -// --header 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZS1kZW1vIiwicm9sZSI6ImFub24ifQ.625_WdcF3KHqz5amU0x2X5WWHP-OEs_4qj0ssLNHzTs' \ -// --header 'Content-Type: application/json' \ -// --data '{"name":"Functions"}' +// To invoke: http://localhost:54321/functions/v1/github-action-deploy diff --git a/examples/edge-functions/supabase/functions/import_map.json b/examples/edge-functions/supabase/functions/import_map.json new file mode 100644 index 00000000000..087feb7c033 --- /dev/null +++ b/examples/edge-functions/supabase/functions/import_map.json @@ -0,0 +1,18 @@ +{ + "imports": { + "denomailer": "https://deno.land/x/denomailer@0.12.0/mod.ts", + "nacl": "https://cdn.skypack.dev/tweetnacl@v1.0.3?dts", + "oak": "https://deno.land/x/oak@v11.1.0/mod.ts", + "og_edge": "https://deno.land/x/og_edge@0.0.4/mod.ts", + "grammy": "https://deno.land/x/grammy@v1.8.3/mod.ts", + "react": "https://esm.sh/react@18.2.0", + "std/server": "https://deno.land/std@0.177.0/http/server.ts", + "stripe": "https://esm.sh/stripe@11.1.0?target=deno", + "sift": "https://deno.land/x/sift@0.6.0/mod.ts", + "@supabase/supabase-js": "https://esm.sh/@supabase/supabase-js@2.7.1", + "postgres": "https://deno.land/x/postgres@v0.14.2/mod.ts", + "puppeteer": "https://deno.land/x/puppeteer@16.2.0/mod.ts", + "React": "https://esm.sh/react@18.2.0?deno-std=0.177.0", + "upstash_redis": "https://deno.land/x/upstash_redis@v1.19.3/mod.ts" + } +} diff --git a/examples/edge-functions/supabase/functions/location/README.md b/examples/edge-functions/supabase/functions/location/README.md index b2c0bacceb7..de3010f4440 100644 --- a/examples/edge-functions/supabase/functions/location/README.md +++ b/examples/edge-functions/supabase/functions/location/README.md @@ -4,6 +4,14 @@ This example shows how you can get user location based on the IP provided in X-F You will need to signup for an account in https://ipinfo.io and provide it as `IPINFO_TOKEN` environment variable ([learn how to set environment variables to your functions](https://supabase.com/docs/guides/functions#secrets-and-environment-variables)). +## Develop locally + +```bash +supabase functions serve --env-file ./supabase/.env.local --no-verify-jwt +``` + +Navigate to http://localhost:54321/functions/v1/location + ## Deploy ```bash diff --git a/examples/edge-functions/supabase/functions/location/index.ts b/examples/edge-functions/supabase/functions/location/index.ts index c9df62475af..cda85ab7837 100644 --- a/examples/edge-functions/supabase/functions/location/index.ts +++ b/examples/edge-functions/supabase/functions/location/index.ts @@ -2,20 +2,29 @@ // https://deno.land/manual/getting_started/setup_your_environment // This enables autocomplete, go to definition, etc. -import { serve } from "https://deno.land/std@0.131.0/http/server.ts" +import { serve } from 'std/server' function ips(req: Request) { - return req.headers.get("x-forwarded-for")?.split(/\s*,\s*/); + return req.headers.get('x-forwarded-for')?.split(/\s*,\s*/) } serve(async (req) => { - const clientIps = ips(req) || ['']; - const res = await fetch(`https://ipinfo.io/${clientIps[0]}?token=${Deno.env.get('IPINFO_TOKEN')}`, { - headers: { 'Content-Type': 'application/json'}}); - const { city, country } = await res.json(); - - return new Response( - JSON.stringify(`You're accessing from ${city}, ${country}`), - { headers: { "Content-Type": "application/json" } }, + const clientIps = ips(req) || [''] + const res = await fetch( + `https://ipinfo.io/${clientIps[0]}?token=${Deno.env.get('IPINFO_TOKEN')}`, + { + headers: { 'Content-Type': 'application/json' }, + } ) + if (res.ok) { + const { city, country } = await res.json() + + return new Response(JSON.stringify(`You're accessing from ${city}, ${country}`), { + headers: { 'Content-Type': 'application/json' }, + }) + } else { + return new Response(await res.text(), { + status: 400, + }) + } }) diff --git a/examples/edge-functions/supabase/functions/oak-server/README.md b/examples/edge-functions/supabase/functions/oak-server/README.md index b1db6166231..ed2795cfc71 100644 --- a/examples/edge-functions/supabase/functions/oak-server/README.md +++ b/examples/edge-functions/supabase/functions/oak-server/README.md @@ -5,7 +5,7 @@ This example shows how you can write functions using Oak server middleware (http ## Run locally ```bash -supabase functions serve oak-server +supabase functions serve --no-verify-jwt ``` Use cURL or Postman to make a POST request to http://localhost:54321/functions/v1/oak-server. @@ -20,5 +20,5 @@ Use cURL or Postman to make a POST request to http://localhost:54321/functions/v ## Deploy ```bash -supabase functions deploy oak-server +supabase functions deploy oak-server --no-verify-jwt ``` diff --git a/examples/edge-functions/supabase/functions/oak-server/index.ts b/examples/edge-functions/supabase/functions/oak-server/index.ts index 9be189be65a..965da32e4a0 100644 --- a/examples/edge-functions/supabase/functions/oak-server/index.ts +++ b/examples/edge-functions/supabase/functions/oak-server/index.ts @@ -1,4 +1,4 @@ -import { Application, Router } from 'https://deno.land/x/oak/mod.ts' +import { Application, Router } from 'oak' const router = new Router() router diff --git a/examples/edge-functions/supabase/functions/og-image-with-storage-cdn/README.md b/examples/edge-functions/supabase/functions/og-image-with-storage-cdn/README.md index 2adb83328c7..05158fd957e 100644 --- a/examples/edge-functions/supabase/functions/og-image-with-storage-cdn/README.md +++ b/examples/edge-functions/supabase/functions/og-image-with-storage-cdn/README.md @@ -9,7 +9,7 @@ Generate Open Graph images with Deno and Supabase Edge Functions and cache the g ## Run locally ```bash -supabase functions serve og-image-with-storage-cdn --no-verify-jwt +supabase functions serve --no-verify-jwt ``` Navigate to http://localhost:54321/functions/v1/og-image-with-storage-cdn?ticketNumber=3524&username=thorwebdev&name=Thor%20%E9%9B%B7%E7%A5%9E%20Schaeff diff --git a/examples/edge-functions/supabase/functions/og-image-with-storage-cdn/handler.tsx b/examples/edge-functions/supabase/functions/og-image-with-storage-cdn/handler.tsx index 80ef24e2ccd..202684370ea 100644 --- a/examples/edge-functions/supabase/functions/og-image-with-storage-cdn/handler.tsx +++ b/examples/edge-functions/supabase/functions/og-image-with-storage-cdn/handler.tsx @@ -1,6 +1,6 @@ -import React from 'https://esm.sh/react@18.2.0?deno-std=0.140.0' -import { ImageResponse } from 'https://deno.land/x/og_edge@0.0.4/mod.ts' -import { createClient } from 'https://esm.sh/@supabase/supabase-js@2' +import React from 'React' +import { ImageResponse } from 'og_edge' +import { createClient } from '@supabase/supabase-js' import { corsHeaders } from '../_shared/cors.ts' const STORAGE_URL = 'https://obuldanrptloktxcffvn.supabase.co/storage/v1/object/public/images/lw6' @@ -213,7 +213,7 @@ export async function handler(req: Request) { }) if (error) throw error - return generatedImage + return await fetch(`${STORAGE_URL}/tickets/${username}.png?v=3`) } catch (error) { return new Response(JSON.stringify({ error: error.message }), { headers: { ...corsHeaders, 'Content-Type': 'application/json' }, diff --git a/examples/edge-functions/supabase/functions/og-image-with-storage-cdn/index.ts b/examples/edge-functions/supabase/functions/og-image-with-storage-cdn/index.ts index 5b2cf3da0b9..0cf64b6e552 100644 --- a/examples/edge-functions/supabase/functions/og-image-with-storage-cdn/index.ts +++ b/examples/edge-functions/supabase/functions/og-image-with-storage-cdn/index.ts @@ -2,7 +2,7 @@ // https://deno.land/manual/getting_started/setup_your_environment // This enables autocomplete, go to definition, etc. -import { serve } from 'https://deno.land/std@0.140.0/http/server.ts' +import { serve } from 'std/server' import { handler } from './handler.tsx' diff --git a/examples/edge-functions/supabase/functions/opengraph/README.md b/examples/edge-functions/supabase/functions/opengraph/README.md index 9242524394e..866f222465a 100644 --- a/examples/edge-functions/supabase/functions/opengraph/README.md +++ b/examples/edge-functions/supabase/functions/opengraph/README.md @@ -8,7 +8,7 @@ Generate Open Graph images with Deno and Supabase Edge Functions, no framework n ## Run locally ```bash -supabase functions serve opengraph --no-verify-jwt +supabase functions serve --no-verify-jwt ``` Navigate to http://localhost:54321/functions/v1/opengraph diff --git a/examples/edge-functions/supabase/functions/opengraph/handler.tsx b/examples/edge-functions/supabase/functions/opengraph/handler.tsx index ef64dc4b8e9..d1bbcd5b2c2 100644 --- a/examples/edge-functions/supabase/functions/opengraph/handler.tsx +++ b/examples/edge-functions/supabase/functions/opengraph/handler.tsx @@ -1,5 +1,5 @@ -import React from 'https://esm.sh/react@18.2.0?deno-std=0.140.0' -import { ImageResponse } from 'https://deno.land/x/og_edge@0.0.4/mod.ts' +import React from 'React' +import { ImageResponse } from 'og_edge' export function handler(req: Request) { return new ImageResponse( diff --git a/examples/edge-functions/supabase/functions/opengraph/index.ts b/examples/edge-functions/supabase/functions/opengraph/index.ts index 5a7c90237cf..0a928de50a7 100644 --- a/examples/edge-functions/supabase/functions/opengraph/index.ts +++ b/examples/edge-functions/supabase/functions/opengraph/index.ts @@ -2,7 +2,7 @@ // https://deno.land/manual/getting_started/setup_your_environment // This enables autocomplete, go to definition, etc. -import { serve } from 'https://deno.land/std@0.140.0/http/server.ts' +import { serve } from 'std/server' import { handler } from './handler.tsx' diff --git a/examples/edge-functions/supabase/functions/postgres-on-the-edge/index.ts b/examples/edge-functions/supabase/functions/postgres-on-the-edge/index.ts index 6ce14f6990d..871d24679fe 100644 --- a/examples/edge-functions/supabase/functions/postgres-on-the-edge/index.ts +++ b/examples/edge-functions/supabase/functions/postgres-on-the-edge/index.ts @@ -1,5 +1,5 @@ -import * as postgres from 'https://deno.land/x/postgres@v0.14.2/mod.ts' -import { serve } from 'https://deno.land/std@0.168.0/http/server.ts' +import * as postgres from 'postgres' +import { serve } from 'std/server' // Get the connection string from the environment variable "DATABASE_URL" const databaseUrl = Deno.env.get('DATABASE_URL')! diff --git a/examples/edge-functions/supabase/functions/puppeteer/README.md b/examples/edge-functions/supabase/functions/puppeteer/README.md index 353df27fd05..57e99a74781 100644 --- a/examples/edge-functions/supabase/functions/puppeteer/README.md +++ b/examples/edge-functions/supabase/functions/puppeteer/README.md @@ -4,6 +4,14 @@ This example shows how you can use Puppeteer and a headless-browser to generate Since Edge Functions cannot run a Headless Browser instance due to resource constraints, you will need to use a hosted browser service like https://browserless.io. +## Develop locally + +```bash +supabase functions serve --env-file ./supabase/.env.local --no-verify-jwt +``` + +Navigate to http://localhost:54321/functions/v1/puppeteer + ## Deploy ```bash diff --git a/examples/edge-functions/supabase/functions/puppeteer/index.ts b/examples/edge-functions/supabase/functions/puppeteer/index.ts index 7eac140f29f..72efb56a723 100644 --- a/examples/edge-functions/supabase/functions/puppeteer/index.ts +++ b/examples/edge-functions/supabase/functions/puppeteer/index.ts @@ -1,11 +1,14 @@ -import { serve } from 'https://deno.land/std@0.131.0/http/server.ts' -import puppeteer from 'https://deno.land/x/puppeteer@16.2.0/mod.ts' +import { serve } from 'std/server' +import puppeteer from 'puppeteer' serve(async (req) => { try { + console.log(`wss://chrome.browserless.io?token=${Deno.env.get('PUPPETEER_BROWSERLESS_IO_KEY')}`) // Visit browserless.io to get your free API token const browser = await puppeteer.connect({ - browserWSEndpoint: 'wss://chrome.browserless.io?token=YOUR_API_TOKEN', + browserWSEndpoint: `wss://chrome.browserless.io?token=${Deno.env.get( + 'PUPPETEER_BROWSERLESS_IO_KEY' + )}`, }) const page = await browser.newPage() @@ -17,7 +20,7 @@ serve(async (req) => { return new Response(screenshot, { headers: { 'Content-Type': 'image/png' } }) } catch (e) { console.error(e) - return new Response(JSON.stringify(`Error occurred when generating the screenshot`), { + return new Response(JSON.stringify({ error: e.message }), { headers: { 'Content-Type': 'application/json' }, status: 500, }) diff --git a/examples/edge-functions/supabase/functions/read-storage/index.ts b/examples/edge-functions/supabase/functions/read-storage/index.ts index d7247b800dc..c32ccfd91bc 100644 --- a/examples/edge-functions/supabase/functions/read-storage/index.ts +++ b/examples/edge-functions/supabase/functions/read-storage/index.ts @@ -2,8 +2,8 @@ // https://deno.land/manual/getting_started/setup_your_environment // This enables autocomplete, go to definition, etc. -import { serve } from 'https://deno.land/std@0.131.0/http/server.ts' -import { createClient } from 'https://esm.sh/@supabase/supabase-js@2' +import { serve } from 'std/server' +import { createClient } from '@supabase/supabase-js' const corsHeaders = { 'Access-Control-Allow-Origin': '*', diff --git a/examples/edge-functions/supabase/functions/restful-tasks/index.ts b/examples/edge-functions/supabase/functions/restful-tasks/index.ts index 67c36ed0a98..eea5219a074 100644 --- a/examples/edge-functions/supabase/functions/restful-tasks/index.ts +++ b/examples/edge-functions/supabase/functions/restful-tasks/index.ts @@ -2,8 +2,8 @@ // https://deno.land/manual/getting_started/setup_your_environment // This enables autocomplete, go to definition, etc. -import { serve } from 'https://deno.land/std@0.131.0/http/server.ts' -import { createClient, SupabaseClient } from 'https://esm.sh/@supabase/supabase-js@2' +import { serve } from 'std/server' +import { createClient, SupabaseClient } from '@supabase/supabase-js' const corsHeaders = { 'Access-Control-Allow-Origin': '*', diff --git a/examples/edge-functions/supabase/functions/select-from-table-with-auth-rls/index.ts b/examples/edge-functions/supabase/functions/select-from-table-with-auth-rls/index.ts index f9dedb16a7d..72b95575cb9 100644 --- a/examples/edge-functions/supabase/functions/select-from-table-with-auth-rls/index.ts +++ b/examples/edge-functions/supabase/functions/select-from-table-with-auth-rls/index.ts @@ -2,8 +2,8 @@ // https://deno.land/manual/getting_started/setup_your_environment // This enables autocomplete, go to definition, etc. -import { serve } from 'https://deno.land/std@0.131.0/http/server.ts' -import { createClient } from 'https://esm.sh/@supabase/supabase-js@2' +import { serve } from 'std/server' +import { createClient } from '@supabase/supabase-js' import { corsHeaders } from '../_shared/cors.ts' console.log(`Function "select-from-table-with-auth-rls" up and running!`) diff --git a/examples/edge-functions/supabase/functions/send-email-smtp/README.md b/examples/edge-functions/supabase/functions/send-email-smtp/README.md index 02e6d5a6b08..68b7dbad82b 100644 --- a/examples/edge-functions/supabase/functions/send-email-smtp/README.md +++ b/examples/edge-functions/supabase/functions/send-email-smtp/README.md @@ -13,4 +13,4 @@ Note: `SMTP_PORT` must be a port other than `25`, `465`, and `587` as Deno Deplo ## Test locally - `cp ./supabase/.env.local.example ./supabase/.env.local` -- `supabase functions serve send-email-smtp --env-file ./supabase/.env.local` \ No newline at end of file +- `supabase functions serve --env-file ./supabase/.env.local` diff --git a/examples/edge-functions/supabase/functions/send-email-smtp/index.ts b/examples/edge-functions/supabase/functions/send-email-smtp/index.ts index 4958b8fa153..d0abf117129 100644 --- a/examples/edge-functions/supabase/functions/send-email-smtp/index.ts +++ b/examples/edge-functions/supabase/functions/send-email-smtp/index.ts @@ -2,14 +2,14 @@ // https://deno.land/manual/getting_started/setup_your_environment // This enables autocomplete, go to definition, etc. -import { serve } from 'https://deno.land/std@0.131.0/http/server.ts' -import { SmtpClient } from 'https://deno.land/x/denomailer@0.12.0/mod.ts' +import { serve } from 'std/server' +import { SmtpClient } from 'denomailer' const smtp = new SmtpClient() console.log(`Function "send-email-smtp" up and running!`) -serve(async (req) => { +serve(async (_req) => { await smtp.connect({ hostname: Deno.env.get('SMTP_HOSTNAME')!, port: Number(Deno.env.get('SMTP_PORT')!), @@ -24,7 +24,7 @@ serve(async (req) => { subject: `Hello from Supabase Edge Functions`, content: `Hello Functions \o/`, }) - } catch (error: any) { + } catch (error) { return new Response(error.message, { status: 500 }) } @@ -41,7 +41,7 @@ serve(async (req) => { }) // To invoke: -// curl -i --location --request POST 'http://localhost:54321/functions/v1/' \ +// curl -i --location --request POST 'http://localhost:54321/functions/v1/send-email-smtp' \ // --header 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZS1kZW1vIiwicm9sZSI6ImFub24ifQ.625_WdcF3KHqz5amU0x2X5WWHP-OEs_4qj0ssLNHzTs' \ // --header 'Content-Type: application/json' \ // --data '{"name":"Functions"}' diff --git a/examples/edge-functions/supabase/functions/stripe-webhooks/README.md b/examples/edge-functions/supabase/functions/stripe-webhooks/README.md index 2d5a7a24d5d..337352277fb 100644 --- a/examples/edge-functions/supabase/functions/stripe-webhooks/README.md +++ b/examples/edge-functions/supabase/functions/stripe-webhooks/README.md @@ -9,7 +9,7 @@ Also check out our full Stripe Payments examples for [React Native (Expo)](https ## Test locally - Terminal 1: - - `supabase functions serve --no-verify-jwt stripe-webhooks --env-file ./supabase/.env.local` + - `supabase functions serve --no-verify-jwt --env-file ./supabase/.env.local` - Terminal 2: - `stripe listen --forward-to localhost:54321/functions/v1/` - Terminal 3 (optional): diff --git a/examples/edge-functions/supabase/functions/stripe-webhooks/index.ts b/examples/edge-functions/supabase/functions/stripe-webhooks/index.ts index 6b159a2a5b4..a0bbb7dc958 100644 --- a/examples/edge-functions/supabase/functions/stripe-webhooks/index.ts +++ b/examples/edge-functions/supabase/functions/stripe-webhooks/index.ts @@ -2,20 +2,21 @@ // https://deno.land/manual/getting_started/setup_your_environment // This enables autocomplete, go to definition, etc. -import { serve } from 'https://deno.land/std@0.132.0/http/server.ts' +import { serve } from 'std/server' -// esm.sh is used to compile stripe-node to be compatible with ES modules. -import Stripe from 'https://esm.sh/stripe@10.13.0?target=deno&no-check&deno-std=0.132.0' +// Import via bare specifier thanks to the import_map.json file. +import Stripe from 'stripe' -const stripe = Stripe(Deno.env.get('STRIPE_API_KEY'), { +const stripe = new Stripe(Deno.env.get('STRIPE_API_KEY') as string, { // This is needed to use the Fetch API rather than relying on the Node http // package. + apiVersion: '2022-11-15', httpClient: Stripe.createFetchHttpClient(), }) // This is needed in order to use the Web Crypto API in Deno. const cryptoProvider = Stripe.createSubtleCryptoProvider() -console.log(`Function "stripe-webhooks" up and running!`) +console.log('Hello from Stripe Webhook!') serve(async (request) => { const signature = request.headers.get('Stripe-Signature') @@ -27,8 +28,8 @@ serve(async (request) => { try { receivedEvent = await stripe.webhooks.constructEventAsync( body, - signature, - Deno.env.get('STRIPE_WEBHOOK_SIGNING_SECRET'), + signature!, + Deno.env.get('STRIPE_WEBHOOK_SIGNING_SECRET')!, undefined, cryptoProvider ) @@ -36,25 +37,5 @@ serve(async (request) => { return new Response(err.message, { status: 400 }) } console.log(`🔔 Event received: ${receivedEvent.id}`) - - // Secondly, we use this event to query the Stripe API in order to avoid - // handling any forged event. If available, we use the idempotency key. - const requestOptions = - receivedEvent.request && receivedEvent.request.idempotency_key - ? { - idempotencyKey: receivedEvent.request.idempotency_key, - } - : {} - - let retrievedEvent - try { - retrievedEvent = await stripe.events.retrieve(receivedEvent.id, requestOptions) - } catch (err) { - return new Response(err.message, { status: 400 }) - } - - return new Response(JSON.stringify({ id: retrievedEvent.id, status: 'ok' }), { - status: 200, - headers: { 'Content-Type': 'application/json' }, - }) + return new Response(JSON.stringify({ ok: true }), { status: 200 }) }) diff --git a/examples/edge-functions/supabase/functions/telegram-bot/index.ts b/examples/edge-functions/supabase/functions/telegram-bot/index.ts index eab5aed9fd6..ecaa9916327 100644 --- a/examples/edge-functions/supabase/functions/telegram-bot/index.ts +++ b/examples/edge-functions/supabase/functions/telegram-bot/index.ts @@ -2,34 +2,28 @@ // https://deno.land/manual/getting_started/setup_your_environment // This enables autocomplete, go to definition, etc. -import { serve } from "https://deno.land/std@0.131.0/http/server.ts" +import { serve } from 'std/server' console.log(`Function "telegram-bot" up and running!`) -import { Bot, webhookCallback } from "https://deno.land/x/grammy@v1.8.3/mod.ts"; +import { Bot, webhookCallback } from 'grammy' -const bot = new Bot(Deno.env.get('TELEGRAM_BOT_TOKEN') || ''); +const bot = new Bot(Deno.env.get('TELEGRAM_BOT_TOKEN') || '') -bot.command("start", (ctx) => ctx.reply("Welcome! Up and running.")); +bot.command('start', (ctx) => ctx.reply('Welcome! Up and running.')) bot.command('ping', (ctx) => ctx.reply(`Pong! ${new Date()} ${Date.now()}`)) -const handleUpdate = webhookCallback(bot, "std/http"); +const handleUpdate = webhookCallback(bot, 'std/http') serve(async (req) => { try { - const url = new URL(req.url); - if (url.searchParams.get('secret') !== Deno.env.get('FUNCTION_SECRET')) + const url = new URL(req.url) + if (url.searchParams.get('secret') !== Deno.env.get('FUNCTION_SECRET')) return new Response('not allowed', { status: 405 }) - return await handleUpdate(req); + return await handleUpdate(req) } catch (err) { - console.error(err); + console.error(err) } }) - -// To invoke: -// curl -i --location --request POST 'http://localhost:54321/functions/v1/' \ -// --header 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZS1kZW1vIiwicm9sZSI6ImFub24ifQ.625_WdcF3KHqz5amU0x2X5WWHP-OEs_4qj0ssLNHzTs' \ -// --header 'Content-Type: application/json' \ -// --data '{"name":"Functions"}' diff --git a/examples/edge-functions/supabase/functions/upstash-redis-counter/.env.example b/examples/edge-functions/supabase/functions/upstash-redis-counter/.env.example deleted file mode 100644 index d0785c19978..00000000000 --- a/examples/edge-functions/supabase/functions/upstash-redis-counter/.env.example +++ /dev/null @@ -1,2 +0,0 @@ -UPSTASH_REDIS_REST_URL= -UPSTASH_REDIS_REST_TOKEN= \ No newline at end of file diff --git a/examples/edge-functions/supabase/functions/upstash-redis-counter/README.md b/examples/edge-functions/supabase/functions/upstash-redis-counter/README.md index 3d33a9e7dd7..dd854b5a07b 100644 --- a/examples/edge-functions/supabase/functions/upstash-redis-counter/README.md +++ b/examples/edge-functions/supabase/functions/upstash-redis-counter/README.md @@ -9,7 +9,7 @@ Create a Redis database using the [Upstash Console](https://console.upstash.com/ Select the `Global` type to minimize the latency from all edge locations. Copy the `UPSTASH_REDIS_REST_URL` and `UPSTASH_REDIS_REST_TOKEN` to your .env file. You'll find them under **Details > REST API > .env**. ```bash -cp supabase/functions/upstash-redis-counter/.env.example supabase/functions/upstash-redis-counter/.env +cp supabase/.env.local.example supabase/.env.local ``` ## Run locally @@ -18,7 +18,7 @@ Make sure you have the latest version of the [Supabase CLI installed](https://su ```bash supabase start -supabase functions serve upstash-redis-counter --no-verify-jwt --env-file supabase/functions/upstash-redis-counter/.env +supabase functions serve --no-verify-jwt --env-file supabase/.env.local ``` Navigate to http://localhost:54321/functions/v1/upstash-redis-counter. @@ -27,5 +27,5 @@ Navigate to http://localhost:54321/functions/v1/upstash-redis-counter. ```bash supabase functions deploy upstash-redis-counter --no-verify-jwt -supabase secrets set --env-file supabase/functions/upstash-redis-counter/.env +supabase secrets set --env-file supabase/.env.local ``` diff --git a/examples/edge-functions/supabase/functions/upstash-redis-counter/index.ts b/examples/edge-functions/supabase/functions/upstash-redis-counter/index.ts index 911424209c9..bf630d0287f 100644 --- a/examples/edge-functions/supabase/functions/upstash-redis-counter/index.ts +++ b/examples/edge-functions/supabase/functions/upstash-redis-counter/index.ts @@ -2,8 +2,8 @@ // https://deno.land/manual/getting_started/setup_your_environment // This enables autocomplete, go to definition, etc. -import { serve } from 'https://deno.land/std@0.177.0/http/server.ts' -import { Redis } from 'https://deno.land/x/upstash_redis@v1.19.3/mod.ts' +import { serve } from 'std/server' +import { Redis } from 'upstash_redis' console.log(`Function "upstash-redis-counter" up and running!`)