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 context object to Telefunc's Server Middleware:

// server.js
 
// Server (Express.js/Fastify/...)
 
import { telefunc } from 'telefunc'
 
// Telefunc middleware
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 that getContext() was called after an await operator:

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

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

// TodoList.telefunc.js
 
export async function myTelefunction() {
  // ✅ Good: we call getContext() before `await`
  const context = getContext()
  await something()
}

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>()
}