Skip to content

Optimize config, entrypoint, and Deno configurations #3431

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 4 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Empty file.
6 changes: 6 additions & 0 deletions deno.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"imports": {
"std/": "https://deno.land/[email protected]/",
"@supabase/supabase-js": "https://deno.land/x/[email protected]/mod.ts"
}
}
File renamed without changes.
5 changes: 5 additions & 0 deletions internal/functions/migrations/templates/config.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
[functions.check-email-existence]
enabled = true
verify_jwt = false # Public endpoint
import_map = "supabase/functions/check-email-existence/deno.json"
entrypoint = "supabase/functions/check-email-existence/index.ts"
5 changes: 5 additions & 0 deletions internal/functions/migrations/templates/deno.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"imports": {
"@supabase/supabase-js": "https://esm.sh/@supabase/supabase-js@2"
}
}
84 changes: 84 additions & 0 deletions internal/functions/migrations/templates/index.ts
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If I understand correctly, you want to make the default template created by functions new more useful? If so, we should introduce a new flag instead of modifying the default behaviour. For eg.

supabase functions new --with-template fetch-user

Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
// // Follow this setup guide to integrate the Deno language server with your editor:
// // https://deno.land/manual/getting_started/setup_your_environment
// // This enables autocomplete, go to definition, etc.

// // Setup type definitions for built-in Supabase Runtime APIs

// import "jsr:@supabase/functions-js/edge-runtime.d.ts"

// // console.log("Hello from Functions!")

// // Deno.serve(async (req) => {
// // const { name } = await req.json()
// // const data = {
// // message: `Hello ${name}!`,
// // }

// // return new Response(
// // JSON.stringify(data),
// // { headers: { "Content-Type": "application/json" } },
// // )
// // })

// /* To invoke locally:

// 1. Run `supabase start` (see: https://supabase.com/docs/reference/cli/supabase-start)
// 2. Make an HTTP request:

// curl -i --location --request POST '{{ .URL }}' \
// --header 'Authorization: Bearer {{ .Token }}' \
// --header 'Content-Type: application/json' \
// --data '{"name":"Functions"}'

// */





import { createClient } from "https://esm.sh/@supabase/supabase-js@2";
const supabase = createClient(
Deno.env.get("SUPABASE_URL")!,
Deno.env.get("SUPABASE_SERVICE_ROLE_KEY")!,
{ auth: { persistSession: false } }
);

// HTTP handler
Deno.serve(async (req) => {
// 1. Reject non-POST requests
if (req.method !== "POST") {
return new Response(JSON.stringify({ error: "Method Not Allowed" }), {
status: 405,
headers: { "Content-Type": "application/json" }
});
}

try {
// 2. Parse and validate email
const { email } = await req.json();
if (!email || typeof email !== "string") {
return new Response(
JSON.stringify({ error: "Valid email required" }),
{ status: 400, headers: { "Content-Type": "application/json" } }
);
}

// 3. Check user existence
const { data, error } = await supabase.auth.admin.getUserByEmail(email);
if (error) throw error;

// 4. Return boolean response
return new Response(
JSON.stringify({ exists: !!data.user }),
{ headers: { "Content-Type": "application/json" } }
);

} catch (err) {
// 5. Handle errors gracefully
console.error(`Error checking email: ${err.message}`);
return new Response(
JSON.stringify({ error: "Internal server error" }),
{ status: 500, headers: { "Content-Type": "application/json" } }
);
}
});
11 changes: 0 additions & 11 deletions internal/functions/new/templates/config.toml

This file was deleted.

3 changes: 0 additions & 3 deletions internal/functions/new/templates/deno.json

This file was deleted.

68 changes: 44 additions & 24 deletions internal/functions/new/templates/index.ts
Original file line number Diff line number Diff line change
@@ -1,32 +1,52 @@
// Follow this setup guide to integrate the Deno language server with your editor:
// https://deno.land/manual/getting_started/setup_your_environment
// This enables autocomplete, go to definition, etc.

// Setup type definitions for built-in Supabase Runtime APIs
import "jsr:@supabase/functions-js/edge-runtime.d.ts"
// index.ts
// import { serve } from "https://deno.land/[email protected]/http/server.ts";

console.log("Hello from Functions!")
// serve((_req) => {
// return new Response("User existence check function is working!", {
// headers: { "Content-Type": "text/plain" },
// });
// });

Deno.serve(async (req) => {
const { name } = await req.json()
const data = {
message: `Hello ${name}!`,
}

return new Response(
JSON.stringify(data),
{ headers: { "Content-Type": "application/json" } },
)
})

/* To invoke locally:
// index.ts
// import { serve } from 'https://deno.land/std/http/server.ts'

// serve((_req) => {
// return new Response("Hello from check-user-existence function!");
// })



1. Run `supabase start` (see: https://supabase.com/docs/reference/cli/supabase-start)
2. Make an HTTP request:
// Setup type definitions for built-in Supabase Runtime APIs
import "jsr:@supabase/functions-js/edge-runtime.d.ts";

import { serve } from 'std/server';
import { createClient } from '@supabase/supabase-js';

const supabaseUrl = Deno.env.get('SUPABASE_URL')!;
const supabaseServiceKey = Deno.env.get('SERVICE_ROLE_KEY')!;

curl -i --location --request POST '{{ .URL }}' \
--header 'Authorization: Bearer {{ .Token }}' \
--header 'Content-Type: application/json' \
--data '{"name":"Functions"}'
const supabaseClient = createClient(supabaseUrl, supabaseServiceKey, {
auth: {
persistSession: false,
},
});

*/
serve(async (req: Request) => {
if (req.method !== 'POST') {
return new Response('Method Not Allowed', { status: 405 });
}
try {
const { email }: { email?: string } = await req.json();
if (!email) {
return new Response(JSON.stringify({ error: 'Email is required' }), { status: 400, headers: { 'Content-Type': 'application/json' } });
}
const { data, error } = await supabaseClient.auth.admin.getUserByEmail(email);
const exists = data !== null;
return new Response(JSON.stringify({ exists }), { headers: { 'Content-Type': 'application/json' } });
} catch (error) {
return new Response(JSON.stringify({ error: 'Internal Server Error' }), { status: 500, headers: { 'Content-Type': 'application/json' } });
}
});
5 changes: 3 additions & 2 deletions pkg/function/testdata/nested/deno.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
{
"imports": {
"module": "jsr:@supabase/functions-js/edge-runtime.d.ts"
"std/": "[https://deno.land/[email protected]/](https://deno.land/[email protected]/)",
"@supabase/supabase-js": "[https://esm.supabase.com/supabase-js@2](https://esm.supabase.com/supabase-js@2)"
}
}
}
32 changes: 31 additions & 1 deletion pkg/function/testdata/nested/index.ts
Original file line number Diff line number Diff line change
@@ -1 +1,31 @@
import "module";
// Setup type definitions for built-in Supabase Runtime APIs
import "jsr:@supabase/functions-js/edge-runtime.d.ts";

import { serve } from 'std/server';
import { createClient } from '@supabase/supabase-js';

const supabaseUrl = Deno.env.get('SUPABASE_URL')!;
const supabaseServiceKey = Deno.env.get('SERVICE_ROLE_KEY')!;

const supabaseClient = createClient(supabaseUrl, supabaseServiceKey, {
auth: {
persistSession: false,
},
});

serve(async (req: Request) => {
if (req.method !== 'POST') {
return new Response('Method Not Allowed', { status: 405 });
}
try {
const { email }: { email?: string } = await req.json();
if (!email) {
return new Response(JSON.stringify({ error: 'Email is required' }), { status: 400, headers: { 'Content-Type': 'application/json' } });
}
const { data, error } = await supabaseClient.auth.admin.getUserByEmail(email);
const exists = data !== null;
return new Response(JSON.stringify({ exists }), { headers: { 'Content-Type': 'application/json' } });
} catch (error) {
return new Response(JSON.stringify({ error: 'Internal Server Error' }), { status: 500, headers: { 'Content-Type': 'application/json' } });
}
});
11 changes: 11 additions & 0 deletions pkg/function/testdata/nested/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"compilerOptions": {
"allowJs": true,
"lib": ["esnext"],
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true,
"moduleResolution": "node"
}
}
11 changes: 11 additions & 0 deletions tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"compilerOptions": {
"allowJs": true,
"lib": ["esnext"],
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true,
"moduleResolution": "node"
}
}
Loading