import { createClient } from "https://esm.sh/@supabase/supabase-js@2"; interface StraetoVariables { [key: string]: number | string; } interface StraetoQuery { operationName: string; variables: StraetoVariables; extensions: StraetoQueryExtensions; } interface StraetoQueryExtensions { persistedQuery: StraetoPersistedQuery; } interface StraetoPersistedQuery { version: number; sha256Hash: string; } interface StraetoBusStop { id: number; name: string; lat: number; lon: number; type: number; rotation: number; code: string | null; isTerminal: boolean; routes: Array; alerts: Array; __typename: string; } interface DbBusStop { id: number; stop_name: string; coords: string; // TODO better geometry type representation type: number; rotation: number; code: string | null; is_terminal: boolean; routes: Array; } function toDbBusStop(straetoStop: StraetoBusStop): DbBusStop { return { id: straetoStop.id, code: straetoStop.code, stop_name: straetoStop.name, coords: `POINT(${straetoStop.lat} ${straetoStop.lon})`, type: straetoStop.type, rotation: straetoStop.rotation, is_terminal: straetoStop.isTerminal, routes: straetoStop.routes, }; } function toQuerystring(obj: StraetoQuery) { return Object.keys(obj).map(function (variableName) { const variableValue = obj[variableName as keyof typeof obj]; if (typeof variableValue == "object") { return encodeURIComponent(variableName) + "=" + encodeURIComponent(JSON.stringify(variableValue)); } else { return encodeURIComponent(variableName) + "=" + encodeURIComponent(variableValue); } }).join("&"); } const graphqlParams: StraetoQuery = { operationName: "Stops", variables: {}, extensions: { persistedQuery: { version: 1, sha256Hash: "6303de055cc42db47a4e1f1cc941b8c86d11c147903bed231e6d4bddcf0e1312", }, }, }; async function getStops(): Promise> { const apiUrl = `https://straeto.is/graphql?${toQuerystring(graphqlParams)}`; const opts = { method: "GET", headers: { "Content-Type": "application/json", }, }; const resp = await fetch(apiUrl, opts); const body = await resp.json(); return body.data.GtfsStops.results; } Deno.serve(async (req) => { const busStops = await getStops(); const authHeader = req.headers.get("Authorization")!; const supabaseClient = createClient( Deno.env.get("SUPABASE_URL") ?? "", Deno.env.get("SUPABASE_ANON_KEY") ?? "", { global: { headers: { Authorization: authHeader } } }, ); console.log("inserting", busStops.length, "rows"); const toInsert = busStops.map(toDbBusStop); const insert = await supabaseClient.from("bus_stops") .upsert(toInsert, { ignoreDuplicates: true }); console.log(insert.statusText, insert.error?.code, insert.error?.message); console.log("rows inserted", insert.count); // const { name } = await req.json() // const data = { // message: `Hello ${name}!`, // } return new Response( JSON.stringify({ "status": insert.statusText, "inserted": toInsert.length, "error": insert.error, }), { 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 'http://127.0.0.1:54321/functions/v1/download-bus-stops' \ --header 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZS1kZW1vIiwicm9sZSI6ImFub24iLCJleHAiOjE5ODM4MTI5OTZ9.CRXP1A7WOeoJeXxjNni43kdQwgnWNReilDMblYTn_I0' \ --header 'Content-Type: application/json' \ --data '{"name":"Functions"}' */