/** * D365FO File Creator Tool * Creates physical XML files in the AOT package structure */ import { XmlTemplateGenerator } from '../xml/xmlTemplateGenerator.js'; import type { CallToolRequest } from '@modelcontextprotocol/sdk/types.js'; /** * The `d365fo_file(action="modify", …, operations:[…])` call that carries the * SAME entries the refused create was carrying. * * A create that lands on an existing object used to answer with three generic * retry options ("pass overwrite=true", "use modify", "pick another name"), and * the one the caller actually wants — apply these exact fields/indexes/values to * the object that is already there — was none of them. Naming `modify` without * its operations buys a discovery round trip: the caller must go and look the * per-operation parameter names up (they are NOT the create spelling: an EDT is * `fieldType` here, an index's fields are objects, …) before it can retry. So * the translation is done here, where both spellings are already known, and the * answer is one copy-paste rather than one more call. * * Method sources are named but not re-emitted: the caller is holding the X++ it * just passed, and inlining it again would put the whole class into a response * that is then re-billed on every later request in the session. */ export declare function renderEquivalentModifyCall(objectType: string, objectName: string, args: { properties?: Record; sourceCode?: string; }): string; /** * Normalize the flexible field specs accepted by the tool / XML generators * (`{ name, edt?, type?, fieldType?, extendedDataType?, enumType?, mandatory?, label? }`) * into the key shape the C# bridge's WriteFieldParam actually deserializes. * * The bridge only reads JSON keys `type` and `edt` (`[JsonPropertyName]`), not * `fieldType`/`extendedDataType` — accept either input spelling and always emit * the bridge's keys. `type` may arrive as a base-type keyword ("Integer") or a * full i:type ("AxTableFieldInt"); the latter is stripped back to the keyword * the bridge's CreateTableField switch understands. */ export declare function normalizeFieldSpecsForBridge(fields: Record[]): Record[]; export declare function normalizeIndexSpecsForBridge(indexes: Record[]): Record[]; /** * The XML template generator moved to ../xml/xmlTemplateGenerator.ts when the * generate/create fork was unified — see that file for the divergences it fixed. * Re-exported here because the create tool has always been its published home. */ export { XmlTemplateGenerator }; /** * Resolve the `values` / `enumValues` alias ONCE, before anything routes on it. * * `values` is a legacy spelling the bridge create path has always accepted * (`props.enumValues ?? props.values` → bridgeParams.values), but the TypeScript * XML generator reads `properties.enumValues` and nothing else. Two writers * disagreeing about the same payload is only harmless while both of them run; * they don't. An enum passed `values: [None=0, A=1]` routes AWAY from the bridge * (the resolved mode forbids explicit elements — see * enumModeForbidsExplicitValues below) and lands on the generator, which finds no * `enumValues`, writes ``, and reports a clean ✅ for an enum with no * values at all. * * So normalise here, at the top of the handler, where every later reader — routing * predicate, bridge params, generator — sees the same list. Mutates in place: `args` * is this call's own parsed object. */ export declare function normalizeEnumValuesAlias(objectType: string, properties: Record | undefined): void; /** * The caller's X++ as this server actually wrote it. * * Every create path renames a class/interface whose declared name differs from * the resolved object name, and that rename is usually what makes the name * legal. Linting the caller's own text instead reports the pre-rename name — * a naming violation against a name already fixed on disk. * * Delegates to the helper the writers use, so the two cannot drift. Source with * no class/interface header is returned untouched. */ export declare function sourceAsWritten(sourceCode: string | undefined, finalObjectName: string): string | undefined; /** * Create D365FO file handler function */ /** * What the caller needs to chain further work onto a create: the name the object * ACTUALLY got, after prefix/casing normalization, and where it was written. * * An out-parameter because neither alternative is sound. Parsing it back out of * the response text is brittle, and a module-level "last created" would be wrong * under two concurrent creates. Both fields are set at the point create computes * them, so every later return path carries them regardless of which one fires — * and a caller that finds them missing must NOT guess (see d365foFile.ts). */ export interface CreateOutcome { finalObjectName?: string; filePath?: string; } export declare function handleCreateD365File(request: CallToolRequest, context?: { bridge?: import('../../bridge/bridgeClient.js').BridgeClient; symbolIndex?: import('../../metadata/symbolIndex.js').XppSymbolIndex; }, outcome?: CreateOutcome): Promise<{ content: Array<{ type: string; text: string; }>; isError?: boolean; }>; //# sourceMappingURL=createD365File.d.ts.map