Maanrifa Bacar Ali
06/09/2024, 9:37 PMJan
06/10/2024, 7:45 AMMaanrifa Bacar Ali
06/10/2024, 8:44 AMMaanrifa Bacar Ali
06/10/2024, 9:18 AMMaanrifa Bacar Ali
06/10/2024, 9:35 AMimport { hello } from './build/dist/js/productionLibrary/hello.mjs';
Deno.serve(async (req) => {
return await hello(req)
})
import_map.json (generated):
{
"imports": {
"format-util": "npm:format-util@^1.0.5",
"node-fetch": "npm:node-fetch@2.6.7",
"abort-controller": "npm:abort-controller@3.0.0",
"ws": "npm:ws@8.5.0",
"@js-joda/core": "npm:@js-joda/core@3.2.0"
}
}
hello.kt (note that the body is suspending):
@Serializable
data class RequestBody(
val name: String
)
@Serializable
data class ResponseBody(
val message: String?
)
@OptIn(ExperimentalJsExport::class)
@JsExport
fun hello(request: Request) = serve {
val requestBody = request.body<RequestBody>()
val client = io.github.jan.supabase.createSupabaseClient(
supabaseUrl = Deno.env[SupabaseSecrets.URL]!!,
supabaseKey = Deno.env[SupabaseSecrets.ANON_KEY]!!
) {
install(Auth) {
codeVerifierCache = MemoryCodeVerifierCache()
sessionManager = MemorySessionManager()
}
}
jsonResponse(
body = ResponseBody(
message = "Hello ${requestBody.name} from ${client.supabaseUrl}",
)
)
}
serve.kt (from a shared module between functions, using composite build):
@OptIn(DelicateCoroutinesApi::class)
fun serve(action: suspend CoroutineScope.() -> Response): Promise<Response> {
return GlobalScope
.async(
context = Dispatchers.Unconfined,
start = CoroutineStart.UNDISPATCHED,
block = action
)
.asPromise()
}
other things used (from different files in the same module as the serve function):
external interface Env {
operator fun get(key: String): String?
}
external object Deno {
val env: Env
}
object SupabaseSecrets {
const val URL = "SUPABASE_URL"
const val ANON_KEY = "SUPABASE_ANON_KEY"
const val SERVICE_ROLE_KEY = "SUPABASE_SERVICE_ROLE_KEY"
const val DB_URL = "SUPABASE_DB_URL"
}
// Gets the request body as instance of type T
suspend inline fun <reified T : Any> Request.body(): T {
return Json.decodeFromString<T>(text().await())
}
inline fun <reified T : Any> jsonResponse(
body: T,
init: ResponseInit = ResponseInit(
headers = Headers {
jsonContentType()
}
)
): Response = Response(
body = Json.encodeToString(body),
init = init
)
Maanrifa Bacar Ali
06/10/2024, 9:48 AMJan
06/10/2024, 9:56 AMMaanrifa Bacar Ali
06/10/2024, 11:06 AMThomas Valloo
06/11/2024, 2:10 PM@file:JsModule("./my-file.js")
import kotlin.js.Promise
@JsName("getFCMAccessToken")
external fun getFCMAccessToken(): Promise<String>
in src/jsMain/resources/my-file.js
import { JWT } from 'npm:google-auth-library@9'
import serviceAccount from '../service-account.json' with { type: 'json' }
//<https://supabase.com/docs/guides/functions/examples/push-notifications?queryGroups=platform&platform=fcm>
export function getFCMAccessToken() {
return new Promise((resolve, reject) => {
const jwtClient = new JWT({
email: serviceAccount.client_email,
key: serviceAccount.private_key,
scopes: ['<https://www.googleapis.com/auth/firebase.messaging>'],
})
jwtClient.authorize((err, tokens) => {
if (err) {
reject(err)
return
}
resolve(tokens.access_token)
})
})
}
And that way you can use it from Kotlin.Thomas Valloo
06/11/2024, 2:11 PMMaanrifa Bacar Ali
06/11/2024, 2:38 PMThomas Valloo
06/11/2024, 8:10 PMblakelee
06/13/2024, 7:25 PMMaanrifa Bacar Ali
06/13/2024, 10:40 PMblakelee
06/14/2024, 2:11 AMblakelee
06/21/2024, 1:29 AMMaanrifa Bacar Ali
06/22/2024, 12:36 AMMaanrifa Bacar Ali
06/27/2024, 4:36 PMblakelee
06/27/2024, 4:40 PMMaanrifa Bacar Ali
06/28/2024, 4:17 PMblakelee
06/28/2024, 6:29 PMMaanrifa Bacar Ali
06/28/2024, 9:52 PMThomas Valloo
07/02/2024, 1:53 PMThomas Valloo
07/02/2024, 1:54 PMconst supabaseClient = createClient(
Deno.env.get('SUPABASE_URL') ?? '',
Deno.env.get('SUPABASE_ANON_KEY') ?? '',
// Create client with Auth context of the user that called the function.
// This way your row-level-security (RLS) policies are applied.
{
global: {
headers: { Authorization: req.headers.get('Authorization')! },
},
}
)
Is there a way to do the same in kt ?Thomas Valloo
07/02/2024, 1:55 PMJan
07/02/2024, 2:21 PMsupabaseClient.auth.importAuthToken(tokenFromHeader)
2:
install(Postgrest) {
jwtToken = tokenFromHeader
}
The 1. approach will assure that all other plugins use this token. Also, you should probably always use AuthConfig#minimalSettings
when working with server-side code to avoid session saving somewhere you don't wantJan
07/02/2024, 2:28 PMThomas Valloo
07/02/2024, 2:30 PMThomas Valloo
07/02/2024, 3:36 PMsupabaseClient.auth.importAuthToken
works like a charm ❤️