Stone.jsDocs
Paradigm

Essentials

Incoming event

The IncomingEvent is the intention, the clean, normalised form of whatever cause arrived. Your handler reads everything it needs from it, and never touches a raw platform request. That is what keeps a handler portable across every context.

#One accessor for input

The principle

A handler that reaches into a platform request object is welded to that platform. A handler that reads named values from an intention is not. The event is that intention: a uniform surface over params, query and body.

In Stone.js

event.get(key, default?) reads a value from any source. The typed overload event.get<T>(key, default) states the shape you expect. event.has(key) tests presence.

app/Tasks.tsts
create (event: IncomingHttpEvent) {
  const title = event.get<string>('title')          // body or query or param
  const notify = event.get<boolean>('notify', false)
  if (!event.has('title')) throw new RuntimeError('title is required')
  return this.tasks.add(title, { notify })
}

#Nested keys

get reads dotted paths, so you reach into a nested body without unpacking it first. A default guards a missing branch, so deep access never throws on absence.

app/Tasks.tsts
event.get('user.name', 'Guest')          // nested body value, with a fallback
event.get<boolean>('permissions.admin', false)
event.get('payload.items.0.id')          // arrays index by number

#HTTP details

When you are on an HTTP context, the event exposes typed getters for the request's details. Reach for these when you genuinely need transport specifics; prefer get() for domain values.

MemberTypeDescription
event.bodyunknownThe parsed request body.
event.paramsRecord<string, string>Captured path parameters.
event.queryquery paramsThe parsed query string.
event.headersheadersRequest headers.
event.cookiescookiesParsed cookies (see Cookies).
event.uri / path / pathnamestringThe request URL and its parts.
event.methodHttpMethodThe HTTP verb.
event.getHeader(name, def?)(name) => stringA single request header.
event.getCookie(name, def?)(name) => valueA single cookie.
event.isSecure / isXhr / isAjaxbooleanCommon request predicates.
event.getFile(name)(name) => UploadedFileAn uploaded file, when the body is multipart.
event.clone()() => IncomingHttpEventA copy, for safe experimentation.

#Content negotiation

When a response should adapt to what the client accepts, ask the event. Each predicate reads the relevant Accept header for you.

app/Reports.tsts
if (event.acceptsTypes('json', 'html') === 'json') return data
return renderHtml(data)

const lang = event.acceptsLanguages('en', 'fr') ?? 'en'

#Files and uploads

app/Uploads.tsts
@Post('/import')
import (event: IncomingHttpEvent) {
  const file = event.getFile('csv')         // one UploadedFile
  const images = event.filterFiles(['photos'])  // several, by field
  return this.importer.run(file)
}

#Fingerprinting

event.fingerprint() returns a stable hash of the request's identifying traits, handy as a cache key or a rate-limit bucket without inventing your own scheme.


Stone.js

Your app exists in every runtime. Until you run it.

An open-source project by Stone Foundation
Created by Mr. Stone (Evens Pierre)