getContext()

Environment: Server.

getContext() enables telefunctions to access contextual information.

// TodoList.telefunc.ts
// Environment: Server

import { getContext } from 'telefunc'

export async function onLoad() {
  const context = getContext()
  const { user } = context
  const todoItems = await Todo.findMany({ select: 'text', authorId: user.id })
  return {
    todoItems,
    userName: user.name
  }
}

It's most commonly used for implementing permissions, see Guides > Permissions.

Provide

Before we can use getContext(), we need to provide the contex` object to Telefunc's Server Middleware:

// server.js

import { telefunc } from 'telefunc'

// Server (Express.js/Fastify/Koa/Hapi/...)
app.all('/_telefunc', async (req, res) => {
  // Authentication middlewares (e.g. Passport.js or Grant) usually provide information
  // about the logged-in user on the `req` object.
  const user = req.user
  // Or when using a third-party authentication provider (e.g. Auth0):
  const user = await authProviderApi.getUser(req.headers)

  const httpResponse = await telefunc({
    // We provide the context object here
    context: {
      user
    },
    url: req.url,
    method: req.method,
    body: req.body,
  })

  const { body, statusCode, contentType } = httpResponse
  res.status(statusCode).type(contentType).send(body)
})

Access

If you get this error:

[telefunc][Wrong Usage][getContext()] Cannot access context object, see https://telefunc.com/getContext#access

Then this means called getContext() after an await operator:

// TodoList.telefunc.js

export async function myTelefunction() {
  await someting()
  // ❌ Bad: we should call getContext() before `await something()`
  const context = getContext()
}

Make sure to call getContext() before any await operator:

// TodoList.telefunc.js

export async function myTelefunction() {
  // ✅ Good: we call getContext() before `await`
  const context = getContext()
  await someting()
}

TypeScript

We can use Telefunc.Context to globally set the type of const context = getContext():

// TelefuncContext.d.ts

import 'telefunc'
import type { User } from './User.ts'

declare module 'telefunc' {
  namespace Telefunc {
    interface Context {
      user: null | User
    }
  }
}
// User.ts

export type User = { id: number }
// *.telefunc.ts

import { getContext } from 'telefunc'

export async function someTelefunction() {
  // TypeScript knows that `user.id` is a `number`
  const { user } = getContext()
}

We can also directly set const context = getContext<MyContext>():

// *.telefunc.ts

import { getContext } from 'telefunc'

type Context = {
  userId: number
}

export async function someTelefunction() {
  // TypeScript knows that `userId` is a `number`
  const { userId } = getContext<Context>()
}