Optional_MongoDB ObjectId (undefined until saved).
OAuth access token. Plaintext in memory; encrypted at rest.
Created timestamp (set on construction).
Display name from Twitch.
OptionalemailEmail address (present when the user:read:email scope was granted).
Access-token expiry as epoch ms.
Twitch login (lowercased handle).
Raw Helix identity payload (for future use).
OAuth refresh token. Plaintext in memory; encrypted at rest.
Granted OAuth scopes.
Twitch user id (unique, stable identifier from Helix).
Last updated timestamp (set on every save).
StaticcollectionMongoDB collection name.
StaticfieldEncrypt the two bearer-token fields at rest. The marshaller's
toStored / fromStored run inside Document.toDocument /
fromDocument, so plaintext never reaches Mongo.
StaticpersistentPersistent fields for auto-sync.
Write back a refreshed token set and persist. This is the
RefreshingAuthProvider.onRefresh target: the relay calls it with
the rotated credentials, and save() → toDocument() re-encrypts
the two token fields automatically, so the rotated token never hits
Mongo in plaintext.
Delete this object from MongoDB.
Unlike the former Persistable.delete, there is no
StuffApi.destruct cascade — a Document is not registered, so there
is no runtime instance to unregister.
ProtectedfromLoad data from a MongoDB document into this object.
Symmetric to toDocument: marshallers transform their assigned
fields' raw values via fromStored before bracket-assign hits the
runtime setter.
ProtectedgetGet all persistent fields for this class (mixin + own declarations).
ProtectedgetWhether this profile currently holds a given OAuth scope. The relay's
outbound path reads hasScope('user:write:chat') to decide between a
send and a reject-and-point into the re-consent flow.
ProtectedpreloadPre-warm the marshaller cache for this instance's class via the async
resolver. Static counterpart Document.preloadFieldMarshallersFor is used
by the findById / find paths.
Save this object to MongoDB. Updates updatedAt automatically.
Pre-resolves any registered field marshallers via the async resolver
before the sync toDocument walk; the sync resolver lookup inside
toDocument then always hits a populated cache.
ProtectedtoConvert this object to a plain document for MongoDB.
Marshallers (declared via static fieldMarshallers on a mixin or
class) intercept their assigned fields: the runtime value-object
value is passed through marshaller.toStored before being written
into the doc. Fields without a marshaller pass through bracket-read
unchanged.
StaticfindFind documents matching a query. Same construction story as findById.
StaticfindFind a document by MongoDB _id. Returns null if not found.
Construction is a plain new this() — the returned instance is NOT
registered with StuffApi and is NOT proxy-wrapped. Two calls for the
same id return two distinct instances (value semantics).
StaticfindFind profile by Twitch user id. Convenience method for the common
query, mirroring GoogleProfile.findByGoogleId.
StaticpreloadStatic-context preload helper. Used by findById / find where
there's no instance to call preloadFieldMarshallers on yet, and
by Template._materialize for the same reason. Symmetric with the
protected instance method.
StaticsetWire the marshaller-resolution seam once at boot (and in tests).
Keeps Document free of a StuffApi import while still reaching
the Idea-rooted marshaller instances. sync mirrors
StuffApi.findByTemplatePath (returns the registered instance or
undefined); async mirrors StuffApi.singleton (resolves /
lazy-clones the instance, warming the cache sync then hits).
Twitch OAuth profile data (persistent, token-bearing). A Document — plain persisted state, NOT a Stuff.