Skip to content

Commit

Permalink
[tcgc] fix wrong unexpected-pageable-operation-return-type because …
Browse files Browse the repository at this point in the history
…of nullable type (#1935)

when a method has several responses and only one of them has pageable
body. tcgc's method return type will be a wrapped nullable type which
real type is that response with body. so, when trying to find property,
we need to peel off the wrapped nullable.
  • Loading branch information
tadelesh authored Dec 2, 2024
1 parent 6b8e8da commit 674dd54
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 6 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
changeKind: fix
packages:
- "@azure-tools/typespec-client-generator-core"
---

fix wrong `unexpected-pageable-operation-return-type` because of nullable type
18 changes: 12 additions & 6 deletions packages/typespec-client-generator-core/src/package.ts
Original file line number Diff line number Diff line change
Expand Up @@ -140,11 +140,17 @@ function getSdkPagingServiceMethod<TServiceOperation extends SdkServiceOperation
getSdkBasicServiceMethod<TServiceOperation>(context, operation, client),
);

// nullable response type means the underlaying operation has multiple responses and only one of them is not empty, which is what we want
let responseType = basic.response.type;
if (responseType?.kind === "nullable") {
responseType = responseType.type;
}

// normal paging
if (isList(context.program, operation)) {
const pagingOperation = diagnostics.pipe(getPagingOperation(context.program, operation));

if (basic.response.type?.__raw?.kind !== "Model" || !pagingOperation) {
if (responseType?.__raw?.kind !== "Model" || !pagingOperation) {
diagnostics.add(
createDiagnostic({
code: "unexpected-pageable-operation-return-type",
Expand All @@ -163,18 +169,18 @@ function getSdkPagingServiceMethod<TServiceOperation extends SdkServiceOperation

basic.response.resultPath = getPropertyPathFromModel(
context,
basic.response.type?.__raw,
responseType?.__raw,
(p) => p === pagingOperation.output.pageItems.property,
);
const nextLinkPath = pagingOperation.output.nextLink
? getPropertyPathFromModel(
context,
basic.response.type?.__raw,
responseType?.__raw,
(p) => p === pagingOperation.output.nextLink!.property,
)
: undefined;

context.__pagedResultSet.add(basic.response.type);
context.__pagedResultSet.add(responseType);
// tcgc will let all paging method return a list of items
basic.response.type = diagnostics.pipe(
getClientTypeWithDiagnostics(context, pagingOperation?.output.pageItems.property.type),
Expand All @@ -190,7 +196,7 @@ function getSdkPagingServiceMethod<TServiceOperation extends SdkServiceOperation
// azure core paging
const pagedMetadata = getPagedResult(context.program, operation)!;

if (basic.response.type?.__raw?.kind !== "Model" || !pagedMetadata.itemsProperty) {
if (responseType?.__raw?.kind !== "Model" || !pagedMetadata.itemsProperty) {
diagnostics.add(
createDiagnostic({
code: "unexpected-pageable-operation-return-type",
Expand All @@ -207,7 +213,7 @@ function getSdkPagingServiceMethod<TServiceOperation extends SdkServiceOperation
});
}

context.__pagedResultSet.add(basic.response.type);
context.__pagedResultSet.add(responseType);

// tcgc will let all paging method return a list of items
basic.response.type = diagnostics.pipe(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,31 @@ describe("typespec-client-generator-core: paged operation", () => {
strictEqual(response.resultPath, "tests");
});

it("nullable paged result", async () => {
await runner.compileWithBuiltInService(`
@list
op test(): ListTestResult | NotFoundResponse;
model ListTestResult {
@pageItems
tests: Test[];
@TypeSpec.nextLink
next: string;
}
model Test {
id: string;
}
`);
const sdkPackage = runner.context.sdkPackage;
const method = getServiceMethodOfClient(sdkPackage);
strictEqual(method.name, "test");
strictEqual(method.kind, "paging");
strictEqual(method.nextLinkPath, "next");

const response = method.response;
strictEqual(response.kind, "method");
strictEqual(response.resultPath, "tests");
});

it("normal paged result with encoded name", async () => {
await runner.compileWithBuiltInService(`
@list
Expand Down

0 comments on commit 674dd54

Please sign in to comment.