Skip to content

Commit 9a680e6

Browse files
committed
Re-add functions to lite
1 parent cb3959d commit 9a680e6

File tree

1 file changed

+190
-0
lines changed

1 file changed

+190
-0
lines changed

pkg/templates/supabase_lite.go

Lines changed: 190 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1712,6 +1712,187 @@ alter function pg_catalog.lo_import(text, oid) owner to postgres;
17121712
},
17131713
},
17141714
},
1715+
{
1716+
ID: "service_functions",
1717+
Name: "Functions",
1718+
Type: schema.ServiceTypeDockerimage,
1719+
Builder: schema.ServiceBuilderDocker,
1720+
Image: utils.ToPtr("supabase/edge-runtime:v1.67.4"),
1721+
DependsOn: []string{"service_postgresql", "service_kong"},
1722+
Ports: []schema.PortSpec{
1723+
{
1724+
Port: 9000,
1725+
Protocol: utils.ToPtr(schema.ProtocolTCP),
1726+
},
1727+
},
1728+
RunCommand: utils.ToPtr("edge-runtime start --main-service /home/deno/functions/main"),
1729+
VariablesMounts: []*schema.VariableMount{
1730+
{
1731+
Name: "main_index_ts",
1732+
Path: "/home/deno/functions/main/index.ts",
1733+
},
1734+
{
1735+
Name: "hello_index_ts",
1736+
Path: "/home/deno/functions/hello/index.ts",
1737+
},
1738+
},
1739+
VariableReferences: []schema.TemplateVariableReference{
1740+
{
1741+
SourceID: "service_postgresql",
1742+
SourceName: "DATABASE_PASSWORD",
1743+
TargetName: "POSTGRES_PASSWORD",
1744+
},
1745+
{
1746+
SourceID: "service_kong",
1747+
SourceName: "JWT_SECRET",
1748+
TargetName: "JWT_SECRET",
1749+
},
1750+
{
1751+
SourceID: "service_kong",
1752+
SourceName: "SUPABASE_ANON_KEY",
1753+
TargetName: "SUPABASE_ANON_KEY",
1754+
},
1755+
{
1756+
SourceID: "service_kong",
1757+
SourceName: "SUPABASE_SERVICE_KEY",
1758+
TargetName: "SUPABASE_SERVICE_ROLE_KEY",
1759+
},
1760+
{
1761+
SourceID: "service_kong",
1762+
TargetName: "SUPABASE_URL",
1763+
IsHost: true,
1764+
},
1765+
{
1766+
SourceID: "service_postgresql",
1767+
SourceName: "DATABASE_PASSWORD",
1768+
TargetName: "SUPABASE_DB_URL",
1769+
AdditionalTemplateSources: []string{"DATABASE_HOST"},
1770+
TemplateString: "postgresql://postgres:${DATABASE_PASSWORD}@${DATABASE_HOST}:5432/postgres",
1771+
},
1772+
},
1773+
Variables: []schema.TemplateVariable{
1774+
{
1775+
Name: "VERIFY_JWT",
1776+
Value: "false",
1777+
},
1778+
{
1779+
Name: "main_index_ts",
1780+
Value: `import { serve } from 'https://deno.land/std@0.131.0/http/server.ts'
1781+
import * as jose from 'https://deno.land/x/jose@v4.14.4/index.ts'
1782+
1783+
console.log('main function started')
1784+
1785+
const JWT_SECRET = Deno.env.get('JWT_SECRET')
1786+
const VERIFY_JWT = Deno.env.get('VERIFY_JWT') === 'true'
1787+
1788+
function getAuthToken(req: Request) {
1789+
const authHeader = req.headers.get('authorization')
1790+
if (!authHeader) {
1791+
throw new Error('Missing authorization header')
1792+
}
1793+
const [bearer, token] = authHeader.split(' ')
1794+
if (bearer !== 'Bearer') {
1795+
throw new Error("Auth header is not 'Bearer {token}'")
1796+
}
1797+
return token
1798+
}
1799+
1800+
async function verifyJWT(jwt: string): Promise<boolean> {
1801+
const encoder = new TextEncoder()
1802+
const secretKey = encoder.encode(JWT_SECRET)
1803+
try {
1804+
await jose.jwtVerify(jwt, secretKey)
1805+
} catch (err) {
1806+
console.error(err)
1807+
return false
1808+
}
1809+
return true
1810+
}
1811+
1812+
serve(async (req: Request) => {
1813+
if (req.method !== 'OPTIONS' && VERIFY_JWT) {
1814+
try {
1815+
const token = getAuthToken(req)
1816+
const isValidJWT = await verifyJWT(token)
1817+
1818+
if (!isValidJWT) {
1819+
return new Response(JSON.stringify({ msg: 'Invalid JWT' }), {
1820+
status: 401,
1821+
headers: { 'Content-Type': 'application/json' },
1822+
})
1823+
}
1824+
} catch (e) {
1825+
console.error(e)
1826+
return new Response(JSON.stringify({ msg: e.toString() }), {
1827+
status: 401,
1828+
headers: { 'Content-Type': 'application/json' },
1829+
})
1830+
}
1831+
}
1832+
1833+
const url = new URL(req.url)
1834+
const { pathname } = url
1835+
const path_parts = pathname.split('/')
1836+
const service_name = path_parts[1]
1837+
1838+
if (!service_name || service_name === '') {
1839+
const error = { msg: 'missing function name in request' }
1840+
return new Response(JSON.stringify(error), {
1841+
status: 400,
1842+
headers: { 'Content-Type': 'application/json' },
1843+
})
1844+
}
1845+
1846+
const servicePath = "/home/deno/functions/" + service_name
1847+
console.error("serving the request with " + servicePath)
1848+
1849+
const memoryLimitMb = 150
1850+
const workerTimeoutMs = 1 * 60 * 1000
1851+
const noModuleCache = false
1852+
const importMapPath = null
1853+
const envVarsObj = Deno.env.toObject()
1854+
const envVars = Object.keys(envVarsObj).map((k) => [k, envVarsObj[k]])
1855+
1856+
try {
1857+
const worker = await EdgeRuntime.userWorkers.create({
1858+
servicePath,
1859+
memoryLimitMb,
1860+
workerTimeoutMs,
1861+
noModuleCache,
1862+
importMapPath,
1863+
envVars,
1864+
})
1865+
return await worker.fetch(req)
1866+
} catch (e) {
1867+
const error = { msg: e.toString() }
1868+
return new Response(JSON.stringify(error), {
1869+
status: 500,
1870+
headers: { 'Content-Type': 'application/json' },
1871+
})
1872+
}
1873+
})`,
1874+
},
1875+
{
1876+
Name: "hello_index_ts",
1877+
Value: `// Follow this setup guide to integrate the Deno language server with your editor:
1878+
// https://deno.land/manual/getting_started/setup_your_environment
1879+
// This enables autocomplete, go to definition, etc.
1880+
1881+
import { serve } from "https://deno.land/std@0.177.1/http/server.ts"
1882+
1883+
serve(async () => {
1884+
return new Response(
1885+
'"Hello from Edge Functions!"',
1886+
{ headers: { "Content-Type": "application/json" } },
1887+
)
1888+
})
1889+
1890+
// To invoke:
1891+
// curl 'http://localhost:<KONG_HTTP_PORT>/functions/v1/hello' \\
1892+
// --header 'Authorization: Bearer <anon/service_role API key>'`,
1893+
},
1894+
},
1895+
},
17151896
{
17161897
ID: "service_kong",
17171898
Name: "Kong",
@@ -1865,6 +2046,15 @@ services:
18652046
- /storage/v1/
18662047
plugins:
18672048
- name: cors
2049+
- name: functions-v1
2050+
url: http://${SERVICE_FUNCTIONS_KUBE_NAME}.${NAMESPACE}:9000/
2051+
routes:
2052+
- name: functions-v1-all
2053+
strip_path: true
2054+
paths:
2055+
- /functions/v1/
2056+
plugins:
2057+
- name: cors
18682058
- name: meta
18692059
url: http://${SERVICE_POSTGRES_META_KUBE_NAME}.${NAMESPACE}:8080/
18702060
routes:

0 commit comments

Comments
 (0)