Skip to content

Commit dce3aac

Browse files
dmealingclaude
andcommitted
refactor(codegen-ts): share pageNodeByName between Payload + field-href links
Extracts the resolve-object-by-name-with-package-less-fallback used by both the Payload cross-link and the layout-aware field-href into one local helper, so the two state the fallback identically (the consistency the field-href fix relies on). Behavior-preserving: flat-layout default path byte-identical, no golden churn. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1 parent ce92754 commit dce3aac

1 file changed

Lines changed: 19 additions & 16 deletions

File tree

server/typescript/packages/codegen-ts/src/generators/template-doc-builder.ts

Lines changed: 19 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,16 @@ function templateDescription(t: MetaData): string | undefined {
9090
return typeof v === "string" && v.length > 0 ? v : undefined;
9191
}
9292

93+
/** Page-placement node for a metadata object resolved by short name, with the
94+
* SAME package-less fallback the Payload cross-link and field hrefs share: when
95+
* the object can't be resolved off the root, fall back to a root-level node so a
96+
* link is still emitted. Keeps every inbound href routing through the one
97+
* `docPageHref(layout, …)` placement. */
98+
function pageNodeByName(root: MetaRoot | undefined, name: string): DocPageNode {
99+
const obj = root?.findObject(name);
100+
return obj !== undefined ? docPageNode(obj) : { name };
101+
}
102+
93103
/** Build the TemplateDocData for one `template.output` node. */
94104
export function buildTemplateDocData(
95105
template: MetaData,
@@ -140,13 +150,12 @@ export function buildTemplateDocData(
140150

141151
// Cross-link to the payload entity's page. The href is derived from the SAME
142152
// page-placement function used to write that entity page, so it resolves in
143-
// BOTH layouts. Resolve the payload's package from the root (by short name)
144-
// so package layout can fold the correct relative path; fall back to a
145-
// package-less node (root-level) when it can't be resolved.
146-
const payloadObj = root?.findObject(payloadName);
147-
const payloadTarget: DocPageNode =
148-
payloadObj !== undefined ? docPageNode(payloadObj) : { name: payloadName };
149-
const payloadLink = docPageHref(layout, docPageNode(template), payloadTarget);
153+
// BOTH layouts (package layout folds the correct relative path).
154+
const payloadLink = docPageHref(
155+
layout,
156+
docPageNode(template),
157+
pageNodeByName(root, payloadName),
158+
);
150159

151160
const data: TemplateDocData = {
152161
generatedMarker: `<!-- ${GENERATED_HEADER} — DO NOT EDIT. -->`,
@@ -232,15 +241,9 @@ function buildTemplateSourceSection(args: BuildSectionArgs): string | undefined
232241

233242
// Layout-aware field href: route through the SAME docPageHref the Payload
234243
// cross-link uses, so the link lands on the owner VO's REAL page in BOTH
235-
// layouts (flat → `./Owner.md`, package → `../<pkg>/Owner.md`). Resolve the
236-
// owner's package off the root (by short name); fall back to a package-less
237-
// node when it can't be resolved — mirroring the Payload link's fallback.
238-
const fieldHref = (owner: string, name: string): string => {
239-
const ownerObj = root.findObject(owner);
240-
const toNode: DocPageNode =
241-
ownerObj !== undefined ? docPageNode(ownerObj) : { name: owner };
242-
return `${docPageHref(layout, fromNode, toNode)}#${fieldAnchorSlug(name)}`;
243-
};
244+
// layouts (flat → `./Owner.md`, package → `../<pkg>/Owner.md`).
245+
const fieldHref = (owner: string, name: string): string =>
246+
`${docPageHref(layout, fromNode, pageNodeByName(root, owner))}#${fieldAnchorSlug(name)}`;
244247

245248
const resolvePartialHref = makePartialHrefResolver(root, layout, fromNode);
246249
const isMultipart = refs.length > 1 || refs.some((r) => r.label !== undefined);

0 commit comments

Comments
 (0)