Ambient types (/ambient)
A type-only module whose import side effect augments SvelteKit’s App.Locals with the four
fields the engine reads and writes on every admin request, and nothing else: a type a site
consumes directly, CairnEnv, Editor, and so on, belongs on Core or
SvelteKit instead, even one this augmentation’s own members reference, since
this module’s whole contract is its import side effect, not a name a site imports from it. A site
imports it once, in src/app.d.ts, instead of hand-writing the declare global block:
// src/app.d.ts
import '@glw907/cairn-cms/ambient';
The augmentation it applies:
declare global {
namespace App {
interface Locals {
cairnEditor?: Editor | null;
cairnBackend?: Backend;
cairnAuditSink?: AdminActionAuditSink;
cairnAccess?: AccessMap;
}
}
}
All four members share the flat cairn prefix rather than a nested locals.cairn.{} namespace:
a flat key costs a site one optional hop (event.locals.cairnEditor) instead of two, and a grep
for cairnEditor finds every engine read of the field in any repo, this one included, with no
namespace to peel back first.
Editor, Backend, AdminActionAuditSink, and AccessMap are exports of the same names:
Editor, Backend, and AccessMap from core, and AdminActionAuditSink from
sveltekit.
-
cairnEditoris the signed-in admin identity.createAuthGuardsets it on every/admin/**request; it’s optional because a request the guard hasn’t touched carries no editor at all, and a signed-in request holds theEditorwhile a signed-out one holdsnull.requireSession,requireOwner,requireEditor, andrequireAccess(all sveltekit exports) read it so a custom route rarely needs the raw field. -
cairnBackendis the per-request content-store channel. The dev-backend handle (@glw907/cairn-cms-dev) sets it so the engine resolves it ahead of the realgithubAppprovider (locals.cairnBackend ?? runtime.backend.connect(env)); a production request never sets it, and the real provider connects instead. -
cairnAuditSinkis the site-supplied persistence seamadminActionforwards every audit record through, and a site’s own domain code may also call it directly with its own events. A site that wants its own audit trail assigns it in a hooks handle; a site that never assigns it still logsadmin.action.auditedon everyctx.auditemit.createD1AuditSinkis the packaged implementation of this seam. -
cairnAccessis the site’s declared access map, attached bycreateAuthGuardalongsidecairnEditor. It’s internal, never serialized to a page payload, and exists sorequireAccessandcreateSectionActionneed no extra argument to reach it at the call site.
The subpath exports nothing at runtime (its JS module is empty), so the import is safe in a declaration file and free everywhere else.