/*! Pixonaut SDK type declarations. Licensed under the MIT licence: see LICENSE-TYPES. */ import { paths } from './schema.js'; /** What `POST /v1/proofs` answers with its 201, as the API's reference * declares it. Derived rather than restated, so a field the route adds or * renames reaches every caller of `approve()` without a hand edit. */ export declare type ApproveResult = paths["/v1/proofs"]["post"]["responses"][201]["content"]["application/json"]; /** Derive the customer form schema from the artwork's groups. A template is * ONE artwork (ADR 018), so each of its groups becomes one step. */ export declare function buildFormSchema(template: FormSchemaSource): FormSchema_2; /** * The default picker: a labelled `` back, so a programmatic pick can move it */ mirror?: (el: MockupMirror) => void): HTMLElement; /** A template color: RGB, CMYK, or a spot color with an RGB/CMYK fallback. */ declare interface ColorValue { rgb?: [number, number, number]; cmyk?: [number, number, number, number]; spot?: { fallback: ColorValue; }; } /** What `commit()` resolves: the committed design's id. */ export declare type CommitResult = paths["/v1/designs"]["post"]["responses"][201]["content"]["application/json"]; /** A correction link's token (#1084), which a store's server hands out for * one design (`POST /v1/designs/{id}/correction-links`) for a short while. * It reaches that design and nothing else the tenant holds, from the * store's own pages. */ declare interface CorrectionLinkCredential { correctionLink: string; publishableKey?: never; shareLink?: never; studioSession?: never; } /** Mounted by a store on a design its customer made, to correct it: the * correction link and the design's id. The design opens as it is now, at the * size it was bought at, so there is no size menu and no placement to name. * `approve()` resolves a proof of the correction and writes nothing; the * store's server makes it the design's next revision with * `PATCH /v1/designs/{id}` and the proof's token. `commit()` is refused. */ declare type CorrectionLinkMount = MountOptionsBase & CorrectionLinkCredential & { /** The design's id. */ design: string; templateId?: never; template?: never; printSizes?: never; selectedPrintSizeIndex?: never; blankId?: never; placementId?: never; }; export declare const DEFAULT_MESSAGES: SdkMessages; export declare interface DesignerState { templateId: string; values: Record>; /** The print size the customer chose, when the host offers a size menu * (ADR 051). It is NOT in `values` — that is keyed by layer id and reaches a * Rust model with `deny_unknown_fields` — so without it here a host * persisting `onChange` state would lose the size and have no way to * restore it. Absent when there is no menu, or when the selected entry is * one the rule refuses. */ printSize?: { widthMm: number; heightMm: number; }; /** The step the form shows, when it lays out as steps (ADR 196). Absent on * a page, so a page's state is what it always was. */ step?: FormStepPosition; } /** Constraints attached to a form field / editable layer prop. */ declare interface FieldConstraints { maxLines?: number; maxLength?: number; min?: number; max?: number; step?: number; oneOf?: string[]; /** image `src` only: may the customer upload their own file? Independent of * `oneOf`, which lists the presets offered (ADR 016). */ allowUpload?: boolean; /** The offered palette: its NAME in the resolved document a canvas or the * SDK draws, its id only in an authored one (#525). */ palette?: string; /** A colour of the customer's own is offered, alone or beside `palette` * (ADR 114, ADR 180). */ anyColor?: true; options?: Array; [key: string]: unknown; } /** `field`'s heading: its authored label, or the message for its prop while * the label is blank or the prop's own key. A prop the form has no word for * keeps the label it came with. */ export declare function fieldLabel(field: Pick, msg: (key: FieldWordKey) => string): string; /** A message that names an unlabelled field. */ export declare type FieldWordKey = (typeof WORD_KEY_BY_PROP)[keyof typeof WORD_KEY_BY_PROP]; /** What a host styles in fill mode. The defaults leave the stage and the form * unpainted and give the form the width it asks for embedded. */ export declare const FILL_PROPERTIES: { /** The stage behind the preview. */ readonly stageBackground: { readonly name: "--pixonaut-stage-background"; readonly fallback: "transparent"; }; /** Space kept clear around the preview on a desktop's stage, as CSS * `padding`: a host that draws something of its own over the stage * reserves its room here, so the preview is fitted beside it rather than * under it. A phone's stage is a band above the form, padded by * `PHONE_STAGE_PADDING`. */ readonly stagePadding: { readonly name: "--pixonaut-stage-padding"; readonly fallback: "24px"; }; /** The form column's width beside the stage. */ readonly formWidth: { readonly name: "--pixonaut-form-width"; readonly fallback: "260px"; }; /** The form column's background. */ readonly formBackground: { readonly name: "--pixonaut-form-background"; readonly fallback: "transparent"; }; }; /** A custom property a host may set on its element, and the value used when * it sets none. */ export declare interface FillProperty { name: `--pixonaut-${string}`; fallback: string; } /** One face of a family: the weight it draws and its TTF's sha256. */ declare interface FontFaceRef { weight: number; hash: string; } /** Families by name, each with its faces: what a document is resolved * against (the tenant's rows, or a version's snapshot) and what the core * reads under `fonts`. */ declare type FontSource = Readonly>; /** Every widget hint a field can carry: the host renders one control per * type. A consumer that draws each (the builder's "renders as" preview) keys * a record on `FormFieldType`, so a type added here fails to compile there * until it is drawn. */ declare const FORM_FIELD_TYPES: readonly ["text", "select", "number", "color", "image", "percent", "crop"]; /** How the customer form lays out its steps (ADR 196): every step on one * page, or one step at a time. * * A template's author may choose one as `form.layout`, and the form schema * carries that choice as `layout` so a headless host sees it too. The SDK's * mount option `layout` outranks it, and with neither the form is a page — * which is what every embed showed before the choice existed. * * A zero-dependency leaf for `artwork-step-label.ts`'s reason: the SDK reads * it, and importing zod would pull it into the widget. */ declare const FORM_LAYOUTS: readonly ["page", "steps"]; /** replace {name} tokens with vars[name]; unknown tokens are left as-is */ export declare function formatMessage(template: string, vars?: Record): string; /** A generated form field descriptor. `layerId` is the write key the widget * sets values through, and what distinguishes two member layers that expose * the same prop. * * An `image` field's `prop` also says how a chosen picture is written: * `pictureValueOf(prop, id)` (`asset-ids.ts`) — the bare id for an image's * `src` and the artwork's `imageAssetId`, `{imageAssetId}` for a shape's * picture `fill` — and its `default` is the prop's value in that same * spelling, read back with `pictureIdOf`. * * Generic in the constraints type, which is not ceremony: this package cannot * import canvas-kit's `FieldConstraints` (that is the dependency cycle), but * the SDK's field renderers read `oneOf`, `maxLines`, `min`, `max`, `step`, * `maxLength` and `palette` off it by name. A bare `Record` * would make every one of those `unknown`. So the api takes the default and * the SDK re-exports this instantiated with its own constraint type — one * declaration, two typings, no cycle. */ declare interface FormField> { layerId: string; prop: string; type: FormFieldType; label: string; /** The author's help text, shown under the control as text (ADR 192); * absent when they wrote none. */ description?: string; /** What the control offers. A `fontWeight` field's values are numbers, and * its `faces` maps each font the customer may pick to the weights it * offers (see `offeredWeightConstraints`). */ constraints: C; default: unknown; /** The fit the customer must have chosen for this field to apply — a * crop's `cover`, a tile size's `tile` — on a site whose fit the customer * chooses (#805). A form shows the field only while the site's fit is * that one. Absent where the fit is the author's alone, so the field * always applies. */ requiresFit?: PictureFitValue; } /** A generated form field descriptor. */ declare type FormField_2 = FormField; declare type FormFieldType = (typeof FORM_FIELD_TYPES)[number]; declare type FormLayout = (typeof FORM_LAYOUTS)[number]; /** The generated form: its steps, and its author's layout when they chose * one (ADR 196). */ declare type FormSchema = FormSchema_2; /** The customer form: its steps, and the layout its author chose, when they * chose one (ADR 196). `layout` is absent rather than defaulted, so a * template that never chose serves the schema it always did. */ declare interface FormSchema_2> { steps: FormStep[]; layout?: FormLayout; } /** A group of layers forming one customer-facing form step. `layerIds` is * optional for the same reason `layers` is below: the SDK derives from an * integrator's in-memory template that no schema gates, and a group missing * its members should yield a step with no fields rather than throw "not * iterable" out of the widget's mount. */ declare interface FormSchemaGroup { id: string; label: string; order: number; layerIds?: string[]; } /** What the derivation reads off a layer — deliberately narrower than any * caller's model. The api passes its `ValidatedDoc`, the SDK a canvas-kit * `LayerSpec`, and this package can see neither (canvas-kit depends on it, * not the reverse). Declaring what is actually read means a change to either * caller's model that breaks the derivation fails at the call site — which * only holds if both call sites assign WITHOUT a cast, so the shapes here are * the widest the derivation can honestly accept rather than the narrowest * that would typecheck against one caller. * * `transform` maps to `unknown` rather than to an axis type, and the body * narrows before reading. That is not laziness: canvas-kit's `LayerTransform` * declares `[key: string]: unknown` (it holds `xMm`/`yMm`/`rotationDeg` * numbers and a `value` object beside the four axis flags), and an index * signature of `unknown` is assignable to no narrower one. Any tighter * declaration here would force the SDK's call site to cast — and a cast is * exactly what this type exists to avoid, since it would swallow the next * change to either caller's model instead of failing on it. */ declare interface FormSchemaLayer { id: string; type?: string; props?: Record; /** Beside `props` rather than in it, because it belongs to no one layer * kind (#427); read through `LAYER_LEVEL_PROPS`. */ opacity?: FormSchemaProp; transform?: Record; /** `false` for a guide layer, which offers nothing (ADR 183). */ print?: boolean; /** `true` for a locked layer, which offers no transform axis and no crop * (ADR 184). */ locked?: boolean; } /** What the derivation reads off one editable prop. Mirrors the api's * `LayerProp` and canvas-kit's, both of which satisfy it structurally. */ declare interface FormSchemaProp { editable?: boolean; label?: string; /** Help text for the customer (ADR 192). `unknown`, because the SDK derives * from an in-memory template no schema gates: only text is carried. */ description?: unknown; constraints?: Record; value?: unknown; [key: string]: unknown; } /** The minimum an artwork must expose to derive a form from it. `layers` is * optional because the api's `ValidatedDoc` declares it so, and the body * already guards it — encoding the optionality in the body while denying it * in the signature is what would force a cast. */ declare interface FormSchemaSource { layers?: FormSchemaLayer[]; groups?: FormSchemaGroup[]; /** The artwork's own background (ADR 038): its colour, or its picture — * both props a customer may be offered. Typed the same way * `FormSchemaLayer.props` is, and for the same reason: both callers must be * able to assign their own document WITHOUT a cast, or this type stops * catching the day their model drifts from what the derivation reads. */ background?: { /** The discriminant a TEMPLATE carries since ADR 046. Optional because a * RESOLVED document reaches this type too and deliberately has none — it * freezes into the design's revisions (`design_revisions.doc_json`) and * must keep parsing as approved. The index signature below swallowed this * field when it arrived, which is exactly the drift the comment above * promises this type catches, so it is named explicitly rather than left * to the catch-all. */ kind?: "color" | "image"; color?: FormSchemaProp; /** The image arm's picture: a prop on a template, offered as an image * layer's `src` is; a bare id on a resolved document, which offers * nothing. `unknown`, and narrowed in the body, because the api's * `ValidatedDoc` spans both. */ imageAssetId?: unknown; /** The image arm's crop (ADR 181): a prop on a template; on a resolved * document a bare crop, which offers nothing. `unknown` for the reason * `imageAssetId` is. */ crop?: unknown; [key: string]: unknown; }; /** The artwork's die-cut (#183, ADR 047), the artwork's second editable * value. Its `constraints.oneOf` is the offered set, as shape ids. */ shape?: FormSchemaProp; /** How the author laid the form out (ADR 196). `unknown` inside, because * the SDK derives from an in-memory template no schema gates: a value that * is not a layout is not carried. */ form?: { layout?: unknown; }; /** The families a resolved document may draw, with their faces (ADR 219 * §6). `unknown`, as the SDK's in-memory template is ungated: anything * but a map of families offers none. */ fonts?: unknown; } /** A generated form step, derived from one of the artwork's groups. No step * carries a surface id: the surface it once named is gone, and a two-sided * product is now two templates (ADR 018). */ declare interface FormStep> { index: number; groupId: string; label: string; layerIds: string[]; fields: FormField[]; /** The members a customer may place: one entry per layer with at least one * editable axis, in `layerIds` order. */ transforms: FormStepTransform[]; } /** One step a form laid out as steps shows: its group, and the name its * heading shows. */ export declare interface FormStepName { groupId: string; label: string; } /** Where a form laid out as steps stands: the step it shows, as an index * into the steps it shows (a step that offers nothing is not one of them), * how many those are, the shown step's group, and every shown step in * order, so a host can draw its own stepper beside the form's. */ export declare interface FormStepPosition { index: number; count: number; groupId: string; steps: FormStepName[]; } /** One member layer's editable transform axes, as its step offers them. * * Per layer rather than merged across the group, because an axis moves the * layer it belongs to and a merged record cannot say which layer that is * (#390). * * The SDK reads an entry only for its existence and its `layerId`: whether a * place control exists and which layer it selects. The controls themselves * are drawn from the layer's own spec (`panel.ts`, the canvas gestures), and * named by the `translate` axis's `label` when the author gave one. The * axes in `transform`, each with the author's `label` and `description` * (ADR 192), are for headless hosts that render their own controls. */ declare interface FormStepTransform { layerId: string; transform: Record; } /** A group of layers forming one customer-facing form step. */ declare interface GroupSpec { id: string; label: string; order: number; layerIds: string[]; } /** An improvement that came back. */ export declare interface Improved { /** The improved picture's asset id. */ assetId: string; /** Whether it was put on the site: false when the site no longer held the * upload it improves, because the customer chose another picture while * it ran. The improved picture is then left unused. */ applied: boolean; } /** The nine points a layer is anchored by. The name means BOTH reference * points at once: the layer's own `top-right` sits against the reference's * `top-right`, coinciding at offset `0,0` (ADR 024). */ declare type LayerAnchor = "top-left" | "top-center" | "top-right" | "center-left" | "center" | "center-right" | "bottom-left" | "bottom-center" | "bottom-right"; /** An editable property descriptor on a layer (label/constraints/value). */ declare interface LayerProp { editable?: boolean; label?: string; constraints?: FieldConstraints; value?: unknown; [key: string]: unknown; } /** A single layer of a template/resolved doc (ADR 018: one artwork). * * The placement fields are DECLARED rather than left to the index signature * below, and that is not tidiness. They used to be `sizeMm`, and when ADR 024 * replaced it this interface still typechecked clean against a percentage * layer — the index signature admitted the new fields and the old ones read as * `unknown` rather than as missing, so `spec.sizeMm.w` compiled and threw at * runtime, and `spec?.sizeMm ?? {w:0,h:0}` silently rendered a zero-size * layer. Declaring them is what makes the next such change a compile error. * * A RESOLVED doc carries `sizeMm` and flat transform millimetres instead. That * half is `ResolvedLayerSpec` below rather than more optional fields here: * one interface describing both shapes is what let `spec.sizeMm.w` compile * against a percentage layer in the first place, and widening this one to * cover the resolved doc too would rebuild exactly that hazard. */ declare interface LayerSpec { id: string; type?: string; z?: number; transform: LayerTransform; /** One of the nine anchors (`ANCHORS` in `@pixonaut/schema/src/layer-box`). * Typed as the union rather than `string` so a misspelling is caught here * and not by a fallback at render. */ anchor: LayerAnchor; /** Another layer's id, when the layer is anchored to that layer's declared * box rather than to the plate. A MISSING target falls back to the plate at * render rather than failing (ADR 024). */ anchorTo?: string; /** Fractions of the reference, always measured toward its centre. */ offsetFrac: { x: number; y: number; }; /** The layer's box, as fractions of the reference's width and height. */ wFrac: number; hFrac: number; props?: Record; /** resolved-doc only: the image layer's asset id (ADR 016). */ kind?: { src?: unknown; }; /** The layer's own backdrop (ADR 033), a sibling of `props`. Declared rather * than left to the index signature for the reason the header gives: nothing * here reads it — `buildGestureDoc`'s `structuredClone` carries it through * untouched, which is what ADR 033 relies on — but an undeclared field is * exactly the state `sizeMm` was in when it read as `unknown` instead of as * missing. `unknown` rather than the schema's `LayerMat`: that union lives * in the zod schema module, and importing it would land zod in the SDK's * browser bundle for a field this package never inspects — the same reason * the imports in `doc/index.ts` reach for zod-free leaf modules by path. */ mat?: unknown; /** The layer's opacity (#427), a sibling of `props` like `mat`: a prop an * author may offer, which the customer form reads beside `props`. */ opacity?: LayerProp; [key: string]: unknown; } /** A layer transform. Template layers carry the current values under `value` * plus per-axis editability flags; a resolved (author) doc carries the flat * numeric fields directly. Both shapes flow through here. * * `value` no longer carries a position: a layer is placed by `anchor` + * `offsetFrac` on the LAYER (ADR 024), and rotation stays here because a layer * is anchored by its unrotated box. The flat `xMm`/`yMm` below survive because * they are the RESOLVED doc's, which is millimetres and stays so. */ declare interface LayerTransform { value: { rotationDeg: number; scale: number; }; translate?: TransformAxis; rotate?: TransformAxis; scale?: TransformAxis; resize?: TransformAxis; xMm?: number; yMm?: number; rotationDeg?: number; [key: string]: unknown; } /** * The consumer's menu with the rule's verdict attached to each entry. * * MARKS, never filters. A size the consumer put in its own menu that comes * back `wrong_ratio` is a misconfiguration on their side — they have paired an * artwork with a size it cannot print at — and silently dropping the option * means they never find out. This is the stance the validation endpoint * already takes by answering `200 {legal: false, reason}` rather than a 4xx. * * Order and labels are passed through untouched, for the reason on * {@link PrintSizeOption}. */ export declare function markPrintSizes(template: SizeConstrainedTemplate, options: readonly PrintSizeOption[], selectedIndex: number): PrintSizeChoice[]; /** One entry with its selection state. There is no `MockupChoice` carrying a * verdict, for the reason in the module header. */ export declare interface MockupChoiceEntry extends MockupOption { selected: boolean; } /** Message keys this control renders, so the host's overrides reach it. One * key where the size picker needs three: nothing here is ever refused, so * there is no suffix vocabulary to translate. */ declare type MockupMessages = (key: "mockup.legend") => string; /** The live `