Skip to content

Commit

Permalink
Backmerge/release/november 2024 2024 12 10 (#1969)
Browse files Browse the repository at this point in the history
Co-authored-by: iscai-msft <[email protected]>
Co-authored-by: iscai-msft <[email protected]>
  • Loading branch information
3 people authored Dec 10, 2024
1 parent cff495c commit 2b3cfb5
Show file tree
Hide file tree
Showing 6 changed files with 181 additions and 12 deletions.
9 changes: 0 additions & 9 deletions .chronus/changes/remove-lro-workaround-2024-10-19-9-4-1.md

This file was deleted.

14 changes: 14 additions & 0 deletions packages/typespec-client-generator-core/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,19 @@
# Change Log - @azure-tools/typespec-client-generator-core

## 0.48.6

### Bug Fixes

- [#1966](https://github.com/Azure/typespec-azure/pull/1966) Allow for responses without bodies to be errors, depending on presence of `@error` decorator


## 0.48.5

### Breaking Changes

- [#1957](https://github.com/Azure/typespec-azure/pull/1957) Introduce new usage: `LroInitial`, `LroPolling`, `LroFinalEnvelope`. Usage and access now properly propagate on polling model, final result and final envelop result of `lroMetadata`.


## 0.48.4

### Bug Fixes
Expand Down
2 changes: 1 addition & 1 deletion packages/typespec-client-generator-core/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@azure-tools/typespec-client-generator-core",
"version": "0.48.4",
"version": "0.48.6",
"author": "Microsoft Corporation",
"description": "TypeSpec Data Plane Generation library",
"homepage": "https://azure.github.io/typespec-azure",
Expand Down
8 changes: 6 additions & 2 deletions packages/typespec-client-generator-core/src/http.ts
Original file line number Diff line number Diff line change
Expand Up @@ -433,7 +433,6 @@ function getSdkHttpResponseAndExceptions(
let body: Type | undefined;
let type: SdkType | undefined;
let contentTypes: string[] = [];

for (const innerResponse of response.responses) {
const defaultContentType = innerResponse.body?.contentTypes.includes("application/json")
? "application/json"
Expand Down Expand Up @@ -494,7 +493,12 @@ function getSdkHttpResponseAndExceptions(
),
description: response.description,
};
if (response.statusCodes === "*" || (body && isErrorModel(context.program, body))) {

if (
response.statusCodes === "*" ||
isErrorModel(context.program, response.type) ||
(body && isErrorModel(context.program, body))
) {
exceptions.push({
...sdkResponse,
kind: "http",
Expand Down
140 changes: 140 additions & 0 deletions packages/typespec-client-generator-core/test/methods/lro.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -546,6 +546,146 @@ describe("typespec-client-generator-core: long running operation metadata", () =
"polling model should not be input",
);
});

it("LRO final envelope result correctly marked when only used in ignored polling operation", async () => {
const runnerWithCore = await createSdkTestRunner({
librariesToAdd: [AzureCoreTestLibrary],
autoUsings: ["Azure.Core", "Azure.Core.Traits"],
emitterName: "@azure-tools/typespec-java",
});
await runnerWithCore.compileWithCustomization(
`
@useDependency(Versions.v1_0_Preview_2)
@server("http://localhost:3000", "endpoint")
@service()
namespace DocumentIntelligence;
@lroStatus
@doc("Operation status.")
union DocumentIntelligenceOperationStatus {
string,
@doc("The operation has not started yet.")
notStarted: "notStarted",
@doc("The operation is in progress.")
running: "running",
@doc("The operation has failed.")
@lroFailed
failed: "failed",
@doc("The operation has succeeded.")
@lroSucceeded
succeeded: "succeeded",
@doc("The operation has been canceled.")
@lroCanceled
canceled: "canceled",
@doc("The operation has been skipped.")
@lroCanceled
skipped: "skipped",
}
#suppress "@azure-tools/typespec-azure-core/long-running-polling-operation-required" "This is a template"
op DocumentIntelligenceLongRunningOperation<
TParams extends TypeSpec.Reflection.Model,
TResponse extends TypeSpec.Reflection.Model
> is Foundations.Operation<
{
...TParams,
@doc("Unique document model name.")
@path
@pattern("^[a-zA-Z0-9][a-zA-Z0-9._~-]{1,63}$")
@maxLength(64)
modelId: string;
},
AcceptedResponse &
Foundations.RetryAfterHeader & {
@pollingLocation
@header("Operation-Location")
operationLocation: ResourceLocation<TResponse>;
},
{},
{}
>;
op DocumentIntelligenceOperation<
TParams extends TypeSpec.Reflection.Model,
TResponse extends TypeSpec.Reflection.Model & Foundations.RetryAfterHeader
> is Foundations.Operation<
TParams,
TResponse,
{},
{}
>;
@doc("Document analysis result.")
model AnalyzeResult {
@doc("API version used to produce this result.")
apiVersion: string;
@doc("Document model ID used to produce this result.")
@pattern("^[a-zA-Z0-9][a-zA-Z0-9._~-]{1,63}$")
modelId: string;
}
@doc("Status and result of the analyze operation.")
model AnalyzeOperation {
@doc("Operation status. notStarted, running, succeeded, or failed")
status: DocumentIntelligenceOperationStatus;
@doc("Date and time (UTC) when the analyze operation was submitted.")
createdDateTime: utcDateTime;
@doc("Date and time (UTC) when the status was last updated.")
lastUpdatedDateTime: utcDateTime;
@doc("Encountered error during document analysis.")
error?: {};
@lroResult
@doc("Document analysis result.")
analyzeResult?: AnalyzeResult;
}
#suppress "@azure-tools/typespec-azure-core/use-standard-operations" "Doesn't fit standard ops"
@doc("Analyzes document with document model.")
@post
@pollingOperation(getAnalyzeResult)
@sharedRoute
@route("/documentModels/{modelId}:analyze")
op analyzeDocument is DocumentIntelligenceLongRunningOperation<
{
@doc("Input content type.")
@header
contentType: "application/json";
@doc("Analyze request parameters.")
@bodyRoot
@clientName("body", "python")
analyzeRequest?: {};
},
AnalyzeOperation
>;
#suppress "@azure-tools/typespec-azure-core/use-standard-operations" "Doesn't fit standard ops"
@doc("Gets the result of document analysis.")
@route("/documentModels/{modelId}/analyzeResults/{resultId}")
@get
op getAnalyzeResult is DocumentIntelligenceOperation<
{
@doc("Unique document model name.")
@path
@pattern("^[a-zA-Z0-9][a-zA-Z0-9._~-]{1,63}$")
@maxLength(64)
modelId: string;
@doc("Analyze operation result ID.")
@path
resultId: uuid;
},
AnalyzeOperation
>;
`,
`
namespace ClientCustomizations;
@client({
name: "DocumentIntelligenceClient",
service: DocumentIntelligence,
})
interface DocumentIntelligenceClient {
analyzeDocument is DocumentIntelligence.analyzeDocument;
}
`,
);
const models = runnerWithCore.context.sdkPackage.models;
strictEqual(models.length, 4);
const analyzeOperationModel = models.find((m) => m.name === "AnalyzeOperation");
ok(analyzeOperationModel);
strictEqual(analyzeOperationModel.usage, UsageFlags.LroFinalEnvelope | UsageFlags.LroPolling);
});
});

describe("Arm LRO templates", () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,26 @@ describe("typespec-client-generator-core: responses", () => {
strictEqual(method.response.resultPath, undefined);
});

it("basic returning compiler NotFoundResponse error", async () => {
await runner.compileWithBuiltInService(
`
@error
model NotFoundErrorResponse is NotFoundResponse;
@get op get(): void | NotFoundErrorResponse;
`,
);
const sdkPackage = runner.context.sdkPackage;
const client = sdkPackage.clients[0];
const getMethod = client.methods[0];
strictEqual(getMethod.kind, "basic");
const operation = getMethod.operation;
strictEqual(operation.responses.length, 1);
strictEqual(operation.responses[0].statusCodes, 204);
strictEqual(operation.exceptions.length, 1);
const exception = operation.exceptions[0];
strictEqual(exception.statusCodes, 404);
});

it("basic returning model", async () => {
await runner.compileWithBuiltInService(
`
Expand Down

0 comments on commit 2b3cfb5

Please sign in to comment.