Saxonberg Server API
    Preparing search index...
    Index

    Constructors

    Methods

    • Generate ancestor paths, nearest first: /a/b/c['/a/b', '/a']. Root / excluded. Re-exported from Template.ancestorPaths for symmetry with the validators that use it.

      Parameters

      • path: string

      Returns string[]

    • Re-hydrate a live Stuff host's in-memory state from its current Template doc. Operates on the existing instance; preserves identity / stuffId / wired Interactives. Phase 1 setters overwrite field values; Phase 2 appliers re-fire (e.g. applyContainer moves the host via compare-and-move).

      v1 coordination: developer/admin operation; does NOT synchronize against multiplexed observers.

      Throws on missing templatePath, missing Template doc, or hydration failure.

      Parameters

      Returns Promise<void>

    • Upsert a Template at path. Looks up an existing Template at the same path (so the underlying upsert reuses its _id), populates the four fields, and saves through Document.save(). The folder/leaf invariant fires through DomainHook against the PM chokepoint — direct template.save() is equivalent.

      Records one append-only AuthoringEvent for path after the save commits — the authorship ledger the producer stock reads. The author is derived from the dispatched execution context, not a parameter (so it can't be spoofed); an unattributable context (programmatic / system save) records nothing. This is the single chokepoint both the in-world authoring verbs and the REST CMS funnel through, so it is the one centralized writer of provenance. See ProvenanceApi.

      Parameters

      • path: string
      • classPath: string
      • data: Record<string, unknown>
      • OptionalhydratorClassPath: string

      Returns Promise<string>

      The saved Template's MongoDB _id.

    • Snapshot a live Stuff host's persistentFields chain back to its backing Template doc's data block. Walks the composed mixin chain via MixinApi.getAllPersistentFields(stuff.constructor); marshals values per MixinApi.getAllFieldMarshallers; derives data.container from the live container ref when the host is Containable; merges over the existing tpl.data (preserves non-mixin-managed keys).

      Pure capture-state: does NOT call tpl.save(). Returns the mutated Template; the caller decides when to commit. Separating capture from commit lets callers inspect, batch, or short- circuit before persisting. Default usage:

      const tpl = await TemplateApi.snapshotToTemplate(host);
      await tpl.save();
      

      Keyed on stuff.getTemplatePath() — the runtime stamp every Stuff carries post-clone — NOT on any class-specific helper. The method is class-shape-agnostic.

      Synchronous-prefix-before-first-await ordering. The persistentFields walk and the container ref read run synchronously, BEFORE Template.findByPath yields. This is load-bearing for onDestruct-driven fire-and-forget saves: they capture pre-cleanup field values even though the MongoDB write itself is async.

      Concurrent calls produce equivalent full-state snapshots — no in-process coordination. MongoDB's replaceOne resolves ordering as last-write-wins.

      Throws when the host has no templatePath stamp, when no Template exists at the resolved path, or when a marshalled field references an unregistered marshaller.

      Parameters

      Returns Promise<Template>

    • Validate a candidate delete against the folder/leaf invariant: a Zone template cannot be deleted while descendants still reference it as a folder.

      Used by DomainHook.aroundDelete. Looks up the doc by _id to discover its path and class — the delete primitive only carries an id.

      Parameters

      • id: string

      Returns Promise<void>

    • Validate a candidate domain-template doc against the folder/leaf invariant. Used by DomainHook.aroundSave.

      Rejects:

      1. Path doesn't start with /.
      2. Doc shape isn't a template (missing path or class).
      3. Leaf save with existing children — "Cannot save leaf template at P; child templates already exist beneath it."
      4. Any save under a non-Zone ancestor — "Ancestor A is a leaf template, not a zone folder."

      Zone classification uses the runtime class field via ZoneApi.isFolderClass — a Zone subclass extends Zone, regardless of whether anyone registered it in a central allow-list. hydratorClass is orthogonal to zonehood.

      Parameters

      • doc: Record<string, unknown>

      Returns Promise<void>

    • Reject saving a domain-collection Template under an engine- reserved template-path prefix (see ReservedTemplatePrefixes in lib/paths.ts). /obj/api/ is owned by the surface-architecture logic singletons (StuffApi.singletonSync); a Template authored there would be mis-returned by the singleton lookup as the wrong-class logic instance, so the namespace must stay DB-free.

      Used by DomainHook.aroundSave alongside validateFolderLeafSave and validateSingletonContainerTarget.

      Parameters

      • doc: Record<string, unknown>

      Returns Promise<void>

    • Validate a candidate domain-template doc's data.container against the singleton-target constraint:

      • Skip when data.container is absent or non-string.
      • Resolve the source class; throw if it doesn't compose ContainableMixin (a non-Containable declaring container is a config bug; Phase 2 would fail loudly at hydrate time, but template-save is the earlier surface).
      • Resolve the target template at the declared path; throw if it doesn't exist.
      • Resolve the target's backing class; throw if the class does NOT compose SingletonMixin.

      Used by DomainHook.aroundSave alongside validateFolderLeafSave. Per declarative-content-slate § container: on Template — singleton-target constraint.

      Parameters

      • doc: Record<string, unknown>

      Returns Promise<void>