Skip to content
HomePagesHomePages template kit

fillSpecFromSchema

Extract a section's published fill spec from its `defineSchema` declaration: one decision per slot carrying a colocated `fill:`, in slot-declaration order, each `id`/`produces` minted from the slot key, plus the schema's own `reads`.

Extract a section’s published fill spec from its defineSchema declaration: one decision per slot carrying a colocated fill:, in slot-declaration order, each id/produces minted from the slot key, plus the schema’s own reads. A section whose slots are all source-bound yields { reads, decisions: [] }.

A meta.display entry with a fill: origin adds the one decision that produces no slot — the section’s own display verdict.

Throws on a declaration no fill spec can express: a top-level slot declaring neither source: nor fill: (nothing would ever write it), a record list with row fills but no row origination (neither a source binding nor a chooseFrom), or a row field declaring a decision kind rows cannot take.

Import from @homepages/template-kit.

function fillSpecFromSchema(schema: SectionSchemaShape): FillSpecShape
Name Type Required Description
schema SectionSchemaShape required

{ reads: string[]; decisions: ({ id: string; type: "list-fill"; mode: "choose" | "extract" | "facts" | "pool" | "curate"; produces: string[]; count?: number | { min?: number | undefined; max?: number | undefined; } | undefined; order?: "walkthrough" | undefined; cap?: number | undefined; pick?: string | undefined; structureHint?: string | undefined; voice?: string | undefined; content?: string | undefined; iterate?: string | undefined; fields?: Record<string, Record<string, unknown> | { type: "list-fill"; count?: number | { min?: number | undefined; max?: number | undefined; } | undefined; cap?: number | undefined; pick?: string | undefined; structureHint?: string | undefined; voice?: string | undefined; content?: string | undefined; }> | undefined; } | { id: string; type: "image-assign"; pick: string; produces: string[]; } | { id: string; type: "video-assign"; pick: string; produces: string[]; } | { id: string; type: "tour-assign"; pick: string; produces: string[]; } | { id: string; type: "document-assign"; pick: string; produces: string[]; } | { id: string; type: "contact-assign"; pick: string; field: "name" | "title" | "org_name" | "email" | "phone" | "website" | "instagram" | "linkedin" | "x" | "facebook" | "headshot" | "logo_dark" | "logo_light"; produces: string[]; } | { id: string; type: "text-block"; structure: "single_sentence" | "paragraph" | "bullet_list"; voice: string; produces: string[]; cap?: number | undefined; perspective?: "first" | "second" | "third" | undefined; content?: string | undefined; } | { id: string; type: "display-select"; entries: ("visibility" | "variant")[]; produces: string[]; })[]; }