From 50e4ce62d0934286c0288ba021e13649e6129e08 Mon Sep 17 00:00:00 2001 From: Joe Wu Date: Tue, 13 Jan 2026 10:53:23 -0800 Subject: [PATCH 1/5] Fix incorrect links for paginated trait in docgen --- .../smithy/docgen/DocSymbolProvider.java | 14 ++++-- .../generators/OperationGeneratorTest.java | 46 +++++++++++++++++++ .../generators/operation-generator.smithy | 23 ++++++++++ 3 files changed, 80 insertions(+), 3 deletions(-) diff --git a/smithy-docgen/src/main/java/software/amazon/smithy/docgen/DocSymbolProvider.java b/smithy-docgen/src/main/java/software/amazon/smithy/docgen/DocSymbolProvider.java index 2303faa76fc..00d5bc96784 100644 --- a/smithy-docgen/src/main/java/software/amazon/smithy/docgen/DocSymbolProvider.java +++ b/smithy-docgen/src/main/java/software/amazon/smithy/docgen/DocSymbolProvider.java @@ -209,6 +209,8 @@ public Symbol structureShape(StructureShape shape) { var operation = ioToOperation.get(shape.getId()); builder.definitionFile(getDefinitionFile(serviceShape, operation)); builder.putProperty(OPERATION_PROPERTY, operation); + // Input and output structures should use the operation as its link_id + builder.putProperty(LINK_ID_PROPERTY, getLinkId(getShapeName(serviceShape, operation))); } return builder.build(); } @@ -230,16 +232,22 @@ public Symbol unionShape(UnionShape shape) { @Override public Symbol memberShape(MemberShape shape) { - var builder = getSymbolBuilder(shape) - .definitionFile(getDefinitionFile(serviceShape, model.expectShape(shape.getId().withoutMember()))); + var builder = getSymbolBuilder(shape); - Optional containerLinkId = model.expectShape(shape.getContainer()) + ShapeId containerId = shape.getContainer(); + Optional containerLinkId = model.expectShape(containerId) .accept(this) .getProperty(LINK_ID_PROPERTY, String.class); if (containerLinkId.isPresent()) { var linkId = containerLinkId.get() + "-" + getLinkId(getShapeName(serviceShape, shape)); builder.putProperty(LINK_ID_PROPERTY, linkId); } + // Definition file of input / output structure members should be the operation file. + if (ioToOperation.containsKey(containerId)) { + builder.definitionFile(getDefinitionFile(serviceShape, ioToOperation.get(containerId))); + } else { + builder.definitionFile(getDefinitionFile(serviceShape, model.expectShape(shape.getId().withoutMember()))); + } return builder.build(); } diff --git a/smithy-docgen/src/test/java/software/amazon/smithy/docgen/generators/OperationGeneratorTest.java b/smithy-docgen/src/test/java/software/amazon/smithy/docgen/generators/OperationGeneratorTest.java index 351955b359f..f13c9d083c4 100644 --- a/smithy-docgen/src/test/java/software/amazon/smithy/docgen/generators/OperationGeneratorTest.java +++ b/smithy-docgen/src/test/java/software/amazon/smithy/docgen/generators/OperationGeneratorTest.java @@ -142,4 +142,50 @@ public void testGeneratesSnippetsFromDiscoveredConfig(@TempDir Path tempDir) { ``` :::""")); } + + @Test + public void testPaginatedOperation(@TempDir Path tempDir) { + MockManifest manifest = new MockManifest(); + FileManifest sharedManifest = FileManifest.create(tempDir); + ObjectNode settings = settings().toBuilder() + .withoutMember("snippetConfigs") + .build(); + sharedManifest.writeFile("snippets/snippets.json", IoUtils.readUtf8Url(SNIPPETS_FILE)); + execute(manifest, sharedManifest, settings); + var operationDocs = manifest.expectFileString("/content/operations/PaginatedOperation.md"); + System.out.println(operationDocs); + assertThat(operationDocs, + containsString( + """ + (paginatedoperation)= + # PaginatedOperation + + Placeholder documentation for `smithy.example#PaginatedOperation` + + :::{important} + This operation returns partial results in pages, whose maximum size may be + configured with [pageSize](./PaginatedOperation.md#paginatedoperation-pagesize). Each request may return an [output token](./PaginatedOperation.md#paginatedoperation-nexttoken) that may be used as an [input token](./PaginatedOperation.md#paginatedoperation-nexttoken) in subsequent requests to fetch the next page of results. If the operation does not return an [output token](./PaginatedOperation.md#paginatedoperation-nexttoken), that means that there are no more results. If the operation returns a repeated [output token](./PaginatedOperation.md#paginatedoperation-nexttoken), there MAY be more results later. + ::: + + (paginatedoperation-request-members)= + ## Request Members + + **nextToken (String)** + : Placeholder documentation for `smithy.example#PaginatedOperationInput$nextToken` + + **pageSize (Integer)** + : Placeholder documentation for `smithy.example#PaginatedOperationInput$pageSize` + + + (paginatedoperation-response-members)= + ## Response Members + + **items (List\\)** + : Placeholder documentation for `smithy.example#PaginatedOperationOutput$items` + + **nextToken (String)** + : Placeholder documentation for `smithy.example#PaginatedOperationOutput$nextToken` + """)); + + } } diff --git a/smithy-docgen/src/test/resources/software/amazon/smithy/docgen/generators/operation-generator.smithy b/smithy-docgen/src/test/resources/software/amazon/smithy/docgen/generators/operation-generator.smithy index 65c246279cd..9daf1756c69 100644 --- a/smithy-docgen/src/test/resources/software/amazon/smithy/docgen/generators/operation-generator.smithy +++ b/smithy-docgen/src/test/resources/software/amazon/smithy/docgen/generators/operation-generator.smithy @@ -6,6 +6,7 @@ service TestService { operations: [ NoSnippets BasicOperation + PaginatedOperation ] } @@ -83,3 +84,25 @@ operation NoSnippets { structure BasicError { message: String } + +@paginated(inputToken: "nextToken", outputToken: "nextToken", pageSize: "pageSize", items: "items") +operation PaginatedOperation { + input: PaginatedOperationInput + + output := { + items: Items + + nextToken: String + } +} + +@input +structure PaginatedOperationInput { + nextToken: String + + pageSize: Integer +} + +list Items { + member: String +} From 190e23071ae5e91fca35ff44df8dbb90f92e801d Mon Sep 17 00:00:00 2001 From: Joe Wu Date: Tue, 13 Jan 2026 11:20:28 -0800 Subject: [PATCH 2/5] Add changelog --- .../bugfix-68d2165529337bbb64a77fdf4adc1f2fd5685f65.json | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 .changes/next-release/bugfix-68d2165529337bbb64a77fdf4adc1f2fd5685f65.json diff --git a/.changes/next-release/bugfix-68d2165529337bbb64a77fdf4adc1f2fd5685f65.json b/.changes/next-release/bugfix-68d2165529337bbb64a77fdf4adc1f2fd5685f65.json new file mode 100644 index 00000000000..6aeb97f4cbb --- /dev/null +++ b/.changes/next-release/bugfix-68d2165529337bbb64a77fdf4adc1f2fd5685f65.json @@ -0,0 +1,7 @@ +{ + "type": "bugfix", + "description": "Fix incorrect links for operation input / output members in docgen", + "pull_requests": [ + "[#2922](https://github.com/smithy-lang/smithy/pull/2922)" + ] +} From 1f229244fe44048f66c08e5b8fbce5745fff0225 Mon Sep 17 00:00:00 2001 From: Joe Wu Date: Tue, 13 Jan 2026 11:21:15 -0800 Subject: [PATCH 3/5] Fix changelog bot script incomplete link --- .changes/smithy_changelog/amend.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.changes/smithy_changelog/amend.py b/.changes/smithy_changelog/amend.py index ef4d2afa882..b5fd7ede269 100644 --- a/.changes/smithy_changelog/amend.py +++ b/.changes/smithy_changelog/amend.py @@ -101,7 +101,7 @@ def amend( f'--type feature --description "{description}"\n```\n\n' "Make sure that the description is appropriate for a changelog entry and " "that the proper feature type is used. See [`./.changes/README`](" - f"{GITHUB_URL}/{repository}/tree/main/.changes/README) or run " + f"{GITHUB_URL}/{repository}/tree/main/.changes/README.md) or run " "`./.changes/new-change -h` for more information." ) post_comment( From 5d73494703c022bfbb318b4e13e7aa78d1fabcab Mon Sep 17 00:00:00 2001 From: Joe Wu Date: Tue, 13 Jan 2026 11:32:20 -0800 Subject: [PATCH 4/5] Update smithy-docgen/src/test/java/software/amazon/smithy/docgen/generators/OperationGeneratorTest.java Co-authored-by: Kevin Stich --- .../amazon/smithy/docgen/generators/OperationGeneratorTest.java | 1 - 1 file changed, 1 deletion(-) diff --git a/smithy-docgen/src/test/java/software/amazon/smithy/docgen/generators/OperationGeneratorTest.java b/smithy-docgen/src/test/java/software/amazon/smithy/docgen/generators/OperationGeneratorTest.java index f13c9d083c4..e552040612b 100644 --- a/smithy-docgen/src/test/java/software/amazon/smithy/docgen/generators/OperationGeneratorTest.java +++ b/smithy-docgen/src/test/java/software/amazon/smithy/docgen/generators/OperationGeneratorTest.java @@ -153,7 +153,6 @@ public void testPaginatedOperation(@TempDir Path tempDir) { sharedManifest.writeFile("snippets/snippets.json", IoUtils.readUtf8Url(SNIPPETS_FILE)); execute(manifest, sharedManifest, settings); var operationDocs = manifest.expectFileString("/content/operations/PaginatedOperation.md"); - System.out.println(operationDocs); assertThat(operationDocs, containsString( """ From e288f8107cd4f6584f72b568dd52d1bd86531f06 Mon Sep 17 00:00:00 2001 From: Joe Wu Date: Wed, 14 Jan 2026 10:47:48 -0800 Subject: [PATCH 5/5] Add suffix to link-id for io structures --- .../java/software/amazon/smithy/docgen/DocSymbolProvider.java | 3 ++- .../smithy/docgen/generators/OperationGeneratorTest.java | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/smithy-docgen/src/main/java/software/amazon/smithy/docgen/DocSymbolProvider.java b/smithy-docgen/src/main/java/software/amazon/smithy/docgen/DocSymbolProvider.java index 00d5bc96784..1a6ae8ef8d2 100644 --- a/smithy-docgen/src/main/java/software/amazon/smithy/docgen/DocSymbolProvider.java +++ b/smithy-docgen/src/main/java/software/amazon/smithy/docgen/DocSymbolProvider.java @@ -210,7 +210,8 @@ public Symbol structureShape(StructureShape shape) { builder.definitionFile(getDefinitionFile(serviceShape, operation)); builder.putProperty(OPERATION_PROPERTY, operation); // Input and output structures should use the operation as its link_id - builder.putProperty(LINK_ID_PROPERTY, getLinkId(getShapeName(serviceShape, operation))); + String suffix = operation.getInputShape().equals(shape.getId()) ? "-request-members" : "-response-members"; + builder.putProperty(LINK_ID_PROPERTY, getLinkId(getShapeName(serviceShape, operation)) + suffix); } return builder.build(); } diff --git a/smithy-docgen/src/test/java/software/amazon/smithy/docgen/generators/OperationGeneratorTest.java b/smithy-docgen/src/test/java/software/amazon/smithy/docgen/generators/OperationGeneratorTest.java index e552040612b..e17601fd4c2 100644 --- a/smithy-docgen/src/test/java/software/amazon/smithy/docgen/generators/OperationGeneratorTest.java +++ b/smithy-docgen/src/test/java/software/amazon/smithy/docgen/generators/OperationGeneratorTest.java @@ -163,7 +163,7 @@ public void testPaginatedOperation(@TempDir Path tempDir) { :::{important} This operation returns partial results in pages, whose maximum size may be - configured with [pageSize](./PaginatedOperation.md#paginatedoperation-pagesize). Each request may return an [output token](./PaginatedOperation.md#paginatedoperation-nexttoken) that may be used as an [input token](./PaginatedOperation.md#paginatedoperation-nexttoken) in subsequent requests to fetch the next page of results. If the operation does not return an [output token](./PaginatedOperation.md#paginatedoperation-nexttoken), that means that there are no more results. If the operation returns a repeated [output token](./PaginatedOperation.md#paginatedoperation-nexttoken), there MAY be more results later. + configured with [pageSize](./PaginatedOperation.md#paginatedoperation-request-members-pagesize). Each request may return an [output token](./PaginatedOperation.md#paginatedoperation-response-members-nexttoken) that may be used as an [input token](./PaginatedOperation.md#paginatedoperation-request-members-nexttoken) in subsequent requests to fetch the next page of results. If the operation does not return an [output token](./PaginatedOperation.md#paginatedoperation-response-members-nexttoken), that means that there are no more results. If the operation returns a repeated [output token](./PaginatedOperation.md#paginatedoperation-response-members-nexttoken), there MAY be more results later. ::: (paginatedoperation-request-members)=