import { ReactNode } from 'react'; import { Schema as Schema_2 } from 'effect'; /** * Compute every `derivedFrom` field from its source value. Returns a NEW * row — the input is not mutated. A caller-provided value for a derived * field is OVERWRITTEN (derived values are the content type's opinion, * mirroring the column `.computed()` semantics). Derivations run in * declaration order against the progressively-updated row, so a derived * field may source another, earlier-declared derived field. */ export declare const applyDerivations: (type: Pick, row: Readonly>) => Record; /** Everything the write pipeline can fail with on the typed channel. */ export declare type CmsWriteError = ContentValidationFailed | ContentNotFound | ContentIdConflict; /** * Auto-generated content form. Renders one labelled widget per field, * driven entirely by each field's `editorHint`. Stateless — the caller * owns `value` + `onChange`. */ export declare const ContentForm: (props: ContentFormProps) => ReactNode; export declare interface ContentFormProps { readonly contentType: ContentFormType; readonly value: ContentValue; readonly onChange: (next: ContentValue) => void; /** Override the widget for one or more editor hints (e.g. a TipTap richText). */ readonly widgets?: Partial>; } /** The content-type shape ContentForm reads (structural — avoids a value import). */ export declare interface ContentFormType { readonly fields: Readonly>; } /** * Raised by `saveDraft` when the caller supplies an explicit `id` that * already exists OUTSIDE the caller's scope (another tenant's row). * Refusing here keeps a caller-pinned id from ever updating — or, on a * store without DB-enforced PKs, overwriting — a foreign row. */ export declare class ContentIdConflict extends ContentIdConflict_base { } declare const ContentIdConflict_base: Schema_2.TaggedErrorClass; } & { contentType: typeof Schema_2.String; id: typeof Schema_2.String; }>; /** * Raised by `publish` / `unpublish` / `archive` when the row id doesn't * exist in the caller's scope. On a tenant-scoped request store this is * ALSO the cross-tenant answer: another tenant's row is indistinguishable * from a missing one (the scoped read never sees it). */ export declare class ContentNotFound extends ContentNotFound_base { } declare const ContentNotFound_base: Schema_2.TaggedErrorClass; } & { contentType: typeof Schema_2.String; id: typeof Schema_2.String; /** Which lifecycle table the id was looked up in. */ stage: Schema_2.Literal<["draft", "published"]>; }>; /** A registered content type. */ declare interface ContentType { readonly name: string; readonly displayName: string; readonly pluralName: string; readonly fields: Readonly>; readonly list?: ListConfig; readonly idPrefix?: string; /** Declared ISR revalidations fired on publish/unpublish — see * `ContentTypeSpec.revalidate`. */ readonly revalidate?: ContentTypeSpec['revalidate']; /** Field names whose value is computed-on-save (derivedFrom). */ readonly derivedFields: ReadonlyArray; /** Field names marked unique-per-tenant (composite `(tenantId, field)` UNIQUE). */ readonly uniqueFields: ReadonlyArray; } /** The user-authored spec passed to `defineContentType`. */ declare interface ContentTypeSpec { readonly name: string; readonly displayName: string; readonly pluralName: string; readonly fields: Readonly>; readonly list?: ListConfig; /** Override the TypeID prefix for awkward plurals / long names. */ readonly idPrefix?: string; /** * ISR routes to drop when content of this type is published or * unpublished — `publish()`/`unpublish()` call `revalidatePath` / * `revalidateTag` (from `@voltro/runtime`) for each entry after the * write commits, reaching every `voltro start` replica. * * You DON'T need this on postgres for the plain publish case: a route * declaring `cacheInvalidatesOn: ['_published']` is already dropped * by CDC when the published table changes. Declare routes here for the * cases CDC can't cover — non-postgres dialects, pattern purges of routes * whose loader reads this content indirectly, or tag fanout. */ readonly revalidate?: { /** Route patterns (`/blog/[slug]`) or concrete paths (`/pricing`). */ readonly paths?: ReadonlyArray; /** Tags matched against routes' `cacheInvalidatesOn` entries. */ readonly tags?: ReadonlyArray; }; } /** * Raised by `validateContent` / `saveDraft` when a row violates the * content type's field rules (pattern / maxLength / typed kinds / * literal sets / rich-text content policy). Carries EVERY violation, * per field, so an editor can annotate the whole form in one pass. */ export declare class ContentValidationFailed extends ContentValidationFailed_base { } declare const ContentValidationFailed_base: Schema_2.TaggedErrorClass; } & { contentType: typeof Schema_2.String; violations: Schema_2.Array$>; }>; export declare type ContentValue = Record; /** * Collect every save-time rule violation for `row` against `type` — * required presence, per-kind type checks, `maxLength`, `pattern`, * `Literal` value sets, and the rich-text content policy * (`allowImages` / `allowEmbeds: false` reject image/embed nodes or the * `` / `