Files
tibi-svelte-starter/.agents/skills/tibi-hook-authoring/SKILL.md

2.6 KiB

name, description
name description
tibi-hook-authoring Write and debug server-side hooks for tibi-server (goja Go JS runtime). Covers IIFE structure, HookResponse/HookException types, context.filter Go-object quirk, single-item vs list retrieval, and MongoDB filter patterns. Use when creating or modifying files in api/hooks/.

tibi-hook-authoring

Hook file structure

Wrap every hook in an IIFE:

;(function () {
    /** @type {HookResponse} */
    const response = { status: 200 }

    // ... hook logic ...

    return response
})()

Always return a HookResponse or throw a HookException.

Type safety

  • Use inline JSDoc type casting: /** @type {TypeName} */ (value).
  • Reference typed collection entries from types/global.d.ts.
  • Avoid @ts-ignore; use proper casting instead.
  • Use const and let instead of var — the goja runtime supports them.

context.filter — Go object quirk

context.filter is a Go object, not a regular JS object. Even when empty, it is truthy.

Always check with Object.keys():

const requestedFilter =
    context.filter &&
    typeof context.filter === "object" &&
    !Array.isArray(context.filter) &&
    Object.keys(context.filter).length > 0
        ? context.filter
        : null

Never use context.filter || null — it is always truthy and produces an empty filter inside $and, which crashes the Go server.

Single-item vs. list retrieval

For GET /:collection/:id, the Go server sets _id automatically from the URL parameter.

GET read hooks should not set their own _id filter for req.param("id"). Only add authorization filters (e.g. { userId: userId }).

HookResponse fields (GET hooks)

Field Purpose
filter MongoDB filter (list retrieval, or restrict single-item)
selector MongoDB projection ({ field: 0 } exclude, { field: 1 } include)
offset Pagination offset
limit Pagination limit
sort Sort specification
pipelineMod Function to manipulate the aggregation pipeline

context.data for write hooks

  • context.data can be an array for bulk operations — always guard with !Array.isArray(context.data).
  • For POST hooks, context.data.id may contain the new entry ID.
  • For PUT/PATCH, req.param("id") gives the entry ID.