/** * Property modifications a form extension applies to a control of its BASE form. * * This is the other half of "customise a base form from an extension". Adding a * NEW control is formExtensionControlXml.ts; CHANGING a property of a control the * base form already defines is here, and it is a different collection entirely: * * * MyForm.Extension * … * ← this one * * ButtonGroup ← the BASE form's control * * * Visible * No * * * * * … ← new controls (the other module) * * * Why it exists: `modify-property` on a form extension used to hand every request * to the generic property writer, which appends to the extension's own ROOT * . So "hide control X" wrote a FORM-level Visible=No — * it hid the whole form — and reported success. A request naming a dotted path * (`HeaderNoteId.Visible`) fared worse: the root writer took the last segment or * wrote the dotted string verbatim as a property name that is not a member of * AxFormExtension at all, again under a ✅. Found by eval case * L2-form-control-removal-lifecycle, whose refusal message recommends exactly * this remedy — the tool advised something it could not do. * * Every shape decision below is measured against the shipped AOT * (ApplicationSuite + ApplicationFoundation + ApplicationPlatform, 416 * AxFormExtension files, 83 of them carrying a non-empty * with 1102 property modifications between them): * * - **Placement.** is immediately followed by * in 83 of 83 files, and by nothing else, ever. That is the anchor. Without a * sibling there is no evidence to place it from, so this declines * rather than guessing — the same rule createControlsCollection follows. * - **One envelope per control.** Zero of the 83 files repeat an * , so a second property on the same control * joins the existing envelope's instead of opening a * second envelope. * - **Not just Visible.** The 1102 modifications name Visible (1093), Enabled * (3), CountryRegionCodes (2), Caption (2), HelpText (1) and Label (1), so the * property name stays a parameter. * - **`xmlns=""`** sits on in every shipped file. * * Pure and side-effect-free: the file I/O stays in the caller. Indentation is * derived from the collection actually found rather than hard-coded — a fixed tab * depth is the tell that a writer assumed one nesting level. */ export type ControlModificationOutcome = { ok: true; xml: string; /** False when the file already carried exactly this value — nothing was written. */ changed: boolean; /** Human-readable account of what happened, for the tool reply. */ detail: string; } | { ok: false; reason: string; }; /** * Set `propertyName` = `propertyValue` on the BASE-form control `controlName`, * creating , the control's envelope and the property entry * as needed. Idempotent: re-issuing the same call reports `changed: false`. * * Returns `{ ok: false }` — never a partial write — when the document is not a * parseable AxFormExtension, or when is absent AND there * is no sibling to anchor it against. */ export declare function upsertFormExtensionControlProperty(xml: string, controlName: string, propertyName: string, propertyValue: string): ControlModificationOutcome; /** * Split a `modify-property` request into control + property when the caller * targeted a base-form control. * * Two spellings reach the tool, and BOTH used to be mis-served: an explicit * `controlName` was silently dropped (the operation never read it), and a dotted * `propertyPath` was truncated to its last segment or written verbatim as a * property name. Returns null when the request is for the extension's own * property, which still belongs to the generic writer. */ export declare function resolveControlPropertyTarget(propertyPath: string, controlName?: string): { controlName: string; propertyName: string; } | null; //# sourceMappingURL=formExtensionControlModifications.d.ts.map