web
web is the second argument of a module’s default export. With it, a module adds to the app what a tool cannot: routes on the server, a browser module, and commands for the message box. Adding to the app tells you how the parts work together.
Register routes, the browser module, and commands while the module loads. After that, these calls throw. What you register goes when this version of the module goes: an edit replaces it, or the owner turns the module off.
The types are Web and the types that it uses, in types/pocket.d.ts.
About the module
Section titled “About the module”readonly api: number;The version of the extension API. API versions tells you when it changes.
module
Section titled “module”readonly module: string;The module’s name: the name of its file without .ts. The routes of server-status.ts are under /api/x/server-status/.
Registering
Section titled “Registering”route(method: WebMethod, path: string, handle: WebHandler, options?: { access?: WebAccess }): void;Adds a route at /api/x/<module>/<path>. handle answers its requests.
methodis aWebMethod.pathis relative to the module’s routes:"status", or"items/:id". A part written:namematches any one part of the address. Names gives the characters that a part can have.- When paths overlap, the most specific path answers, whatever the order of registration. From the left, a fixed part comes before a
:namepart:items/newcomes beforeitems/:id. accesssays who can use the route. The default is"owner". SeeWebAccess.- A method and a path of the same shape can have only one route.
Routes tells you about the checks that come before a handler, errors, and what to check in a handler.
client
Section titled “client”client(entry: string, options?: { access?: WebAccess }): void;Sets the module’s browser module. A module has one browser module at most.
entryis the name of a file or folder immediately beside the module. It must not be a link. Names gives the characters that it can have.- A
.jsor.mjsfile is served alone. - A folder must have an
index.js, which loads first and can import the other files of the folder. accesssays whose tabs load it. The default is"owner". SeeWebAccess.
Browser modules tells you which files a folder serves, and when tabs load a new version.
command
Section titled “command”command(name: string, command: Command): void;Adds the command /name to the message box, for the people who can run it. The command runs on the server, and it does not ask Pi.
- Names gives the rules for
name. - Command context gives the fields of
commandand what its handler gets and returns. - Slash commands tells you who can run a command, how a run is kept, and how a person stops it.
Sending and answering
Section titled “Sending and answering”send(event: string, data?: unknown, options?: { to?: string }): void;Sends an event to the browser module. There, pocket.on(event, run) gets it.
datais a value that JSON can hold.- Without
to, the event goes to the tabs of all the people that the browser module’saccesslets in. Withto, it goes only to the tabs of the person with that id. - Send events only after the module has loaded, and only from a module that has a browser module. Other events go nowhere.
sendnever throws, because modules call it mostly from timers. When it cannot send an event, it writes the reason to the server’s log, one time for each kind of mistake in a version.
Events tells you about the limits, and about tabs that fall behind.
error(status: number, message: string): Error;Makes an error for a route or a command handler to throw: throw web.error(404, "No such item"). The person who asked gets status and message as they are. status is from 400 to 599.
Do not put text in message that this person must not see. Any other error that a handler throws gives a status of 500, and only the owner sees its words.
onDispose
Section titled “onDispose”onDispose(dispose: () => unknown): void;Runs dispose when this version of the module goes: an edit replaces it, the owner turns it off, or the server stops. Stop timers and close connections there. dispose can return a promise. Cleanups tells you how long a stopping server waits for it.
Requests
Section titled “Requests”WebHandler
Section titled “WebHandler”type WebHandler = (request: WebRequest) => unknown;Answers the requests of a route. The value that it returns goes back as JSON, and undefined goes back as {}. It can be async.
WebRequest
Section titled “WebRequest”interface WebRequest { readonly method: WebMethod; readonly params: Readonly<Record<string, string>>; readonly query: URLSearchParams; readonly body: Readonly<Record<string, unknown>>; readonly user: Person; readonly signal: AbortSignal;}What a handler gets.
method: the request’s method.params: the values of the path’s:nameparts, by name. They are text from outside: check a value before you make a file path from it.query: the query string.pocket.api("usage?days=7")sendsdays.body: the JSON object that the browser sent. It is empty for GET and DELETE.user: the person who asked, as{ id, name, role }.signal: it aborts when the browser stops waiting for the answer. Give it to the work that the handler waits for.
WebMethod
Section titled “WebMethod”type WebMethod = "GET" | "POST" | "PUT" | "PATCH" | "DELETE";The methods that a route can have.
Access
Section titled “Access”WebAccess
Section titled “WebAccess”type WebAccess = "owner" | "steer" | "view";Who can use a route, or whose tabs load a browser module.
"owner", the default: the owner alone."steer": the owner, and guests who can steer all sessions."view": the owner, guests, and viewers who can see all sessions.
A person invited to one session never can, because these parts belong to the whole app. Each route has its own access, so a browser module for everyone can call a route for the owner alone.
access is the same for all methods. A POST route with "view" lets viewers change something through it, though they cannot steer a session. Give "owner" or "steer" to a route that changes things.
To a person that its access does not let in, a route is not there. The person gets the same 404 as for a path that the module does not have. Thus another route whose path matches can answer the person. Give the same access to routes whose paths overlap, or check user.role in the handler.
These pages describe Pi Pocket 0.14.0. Your copy has the pages of its own version in its docs/ folder.