Guard / foldkit-guard
Agents
An agent should not be offered, or attempt, what the server would refuse.
foldkit-guard/agent reads may from the row the Model holds, for a
foldkit-agent capability's authorize and available:
ts
import { Agent } from 'foldkit-agent'
import { GuardAgent } from 'foldkit-guard/agent'
const TodoAgent = Agent.forApplication(App).withPrincipal(G.Principal)
// The Todo an id names, read through `Row` from the client's Model.
const todo = Remote.select(Remote.at(Data, App.model.remote), Row)
TodoAgent.expose(Message, {
RequestedArchive: {
description: 'Archive a todo',
authorize: GuardAgent.authorize(Archive.key, ({ input, model }) => todo(input.id).read(model)),
available: GuardAgent.available(Archive.key, model => todo(model.selected).read(model)),
},
})App and Message are the client application's: its Model holds Remote's
store at remote and the selected todo's id at selected, and Message
has a RequestedArchive with the todo's id.
Rowselectsmay. A row not read yet, or whose read failed, refuses: there is no answer to go on. One being read again answers as it last did. A refusal its rule explained is the agent's error message.availableis for a capability over a row the Model alone names (the one selected): a visitor is then not offered it at all.withPrincipal(G.Principal)makes the agent's principal the server's type.- It is the agent's gate, not the check: the Message's mutation is checked on the server, under the same principal.