import { ReceiptFailure } from '../types/receipt.js'; import { SDHighlightColor } from '../types/sd-props.js'; import { StylesParagraphPatch, StylesRunPatch, StylesStateMap } from './apply.js'; /** * Run properties of a named style. * * A superset of {@link StylesRunPatch}: the four properties Word forbids in * `w:docDefaults` and allows on a `w:style` are reachable here and nowhere * else. `rtl` in particular is the property that makes a run right-to-left, so * without it no right-to-left style could be authored through this API. */ export interface StyleRunPatch extends StylesRunPatch { /** `w:cs` — treat the run as complex-script. */ cs?: boolean; /** `w:rtl` — right-to-left run. */ rtl?: boolean; /** `w:oMath` — the run is part of an equation. */ oMath?: boolean; /** `w:highlight` — one of the closed `ST_HighlightColor` tokens. */ highlight?: SDHighlightColor; } /** What to do when a style with this `id`, or this `name`, already exists. */ export type StyleConflictPolicy = 'fail' | 'replace'; interface StylesCreateCommon { /** `w:styleId`. Named `id` to match {@link StyleCatalogItem.id} on read. */ id: string; /** `w:name`. */ name: string; /** `w:basedOn`. `null` states "based on nothing" explicitly. */ basedOn?: string | null; /** `w:aliases`, one entry per alias. */ aliases?: string[]; /** `w:uiPriority`. Named `priority` to match the catalogue on read. */ priority?: number | null; /** `w:qFormat` — offer the style in Word's quick gallery. */ qFormat?: boolean; /** `w:hidden`. */ hidden?: boolean; /** `w:semiHidden`. */ semiHidden?: boolean; /** `w:unhideWhenUsed`. */ unhideWhenUsed?: boolean; /** `w:locked`. */ locked?: boolean; /** * `w:customStyle`. Defaults to `true`, which is what a style authored * through this API is. Setting it `false` on a style whose name is not a * built-in makes Word treat the name as one and re-label or hide the style. */ custom?: boolean; /** Defaults to `'fail'`. */ conflictPolicy?: StyleConflictPolicy; } export interface StylesCreateParagraphInput extends StylesCreateCommon { type: 'paragraph'; /** `w:next`. May name the style being created. */ next?: string | null; /** `w:style/w:pPr`. */ paragraph?: StylesParagraphPatch; /** `w:style/w:rPr`. */ run?: StyleRunPatch; } export interface StylesCreateCharacterInput extends StylesCreateCommon { type: 'character'; /** A character style has no following-paragraph style. */ next?: never; /** A character style has no paragraph properties. */ paragraph?: never; /** `w:style/w:rPr`. */ run?: StyleRunPatch; } export type StylesCreateInput = StylesCreateParagraphInput | StylesCreateCharacterInput; export interface StylesCreateOptions { dryRun?: boolean; expectedRevision?: string; } export interface NormalizedStylesCreateOptions { dryRun: boolean; expectedRevision: string | undefined; } export interface StylesCreateResolution { scope: 'style'; id: string; type: 'paragraph' | 'character'; xmlPart: string; /** * Literal, not `string`: `styles.apply` pins its two paths in the published * schema and exports them as constants for the adapter to bind to. Without * the narrowing an adapter could report the more specific * `w:styles/w:style[@w:styleId='X']`, type-check, and then fail the schema. */ xmlPath: typeof STYLE_XML_PATH; } /** The `w:style` element path. Predicate-free, like `XML_PATH_BY_CHANNEL`. */ export declare const STYLE_XML_PATH = "w:styles/w:style"; /** * Per-channel state, unlike {@link StylesApplyReceipt}'s flat map. * * `styles.apply` can be flat because `resolution.channel` says which channel * the map describes. One `w:style` carries both at once, and `snapToGrid`, * `shading` and `borders` exist on both — `borders` with genuinely different * shapes (`w:bdr`, one border, against `w:pBdr`, six edges). Folded together * they would be indistinguishable. */ export interface StyleChannelState { paragraph: StylesStateMap | null; run: StylesStateMap | null; } export interface StylesCreateReceiptSuccess { success: true; /** `false` when the definition already matched the input. */ changed: boolean; /** * `false` when an existing style was redefined under `conflictPolicy: * 'replace'`. `created: true` implies `changed: true`. Under `dryRun` it * describes what the call would have done. * * `ReceiptSuccess.inserted` / `updated` are deliberately not used: they take * `EntityAddress`, and a style definition is not addressable as a document * entity. */ created: boolean; resolution: StylesCreateResolution; dryRun: boolean; /** `null` when the style did not exist. */ before: StyleChannelState | null; after: StyleChannelState; } export interface StylesCreateReceiptFailure { success: false; failure: ReceiptFailure; } export type StylesCreateReceipt = StylesCreateReceiptSuccess | StylesCreateReceiptFailure; export interface StylesCreateAdapter { create(input: StylesCreateInput, options: NormalizedStylesCreateOptions): StylesCreateReceipt; } export interface StylesCreateApi { create(input: StylesCreateInput, options?: StylesCreateOptions): StylesCreateReceipt; } /** * Validates the shape of `styles.create` input. * * Deliberately shallow on identifiers: `id` is checked for "non-empty string" * and nothing more, exactly as `styles.paragraph.setStyleRef` checks the same * field. `w:styleId` is an `ST_String`, real documents carry ids with spaces, * and a stricter rule here would mean `setStyleRef` could apply a style that * `styles.create` cannot express. */ export declare function validateStylesCreateInput(input: unknown): asserts input is StylesCreateInput; export declare function validateStylesCreateOptions(options: unknown): void; /** * Executes `styles.create` using the provided adapter. * * Fails closed when the host engine has no `create` hook, the same way * `executeStylesGetCatalog` does for its optional catalogue hook — input is * validated first, so a malformed call is reported as malformed rather than as * an unavailable capability. */ export declare function executeStylesCreate(adapter: Partial | null | undefined, input: StylesCreateInput, options?: StylesCreateOptions): StylesCreateReceipt; export {};