Skip to content
This repository was archived by the owner on Jul 6, 2026. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
175d4c4
try spread
weidongxu-microsoft Jun 17, 2024
44bb63e
re-generate test code
actions-user Jun 17, 2024
8385a32
Merge branch 'main' into tsp_model-spread
weidongxu-microsoft Jun 24, 2024
5101c47
remove getEffectiveSchemaType from request body
weidongxu-microsoft Jun 24, 2024
fd0a56c
update test
weidongxu-microsoft Jun 24, 2024
16ab150
re-generate test code
actions-user Jun 24, 2024
a01611a
Merge branch 'main' into tsp_model-spread
weidongxu-microsoft Jun 25, 2024
a1eaf87
test with unreleased lib
weidongxu-microsoft Jul 2, 2024
ca059b5
Merge branch 'main' into tsp_model-spread
weidongxu-microsoft Jul 2, 2024
d4dfddc
remove tsp
weidongxu-microsoft Jul 2, 2024
14cf584
locate the test lib
weidongxu-microsoft Jul 2, 2024
d77c38b
force
weidongxu-microsoft Jul 2, 2024
20aaee5
fix wire name on header/query/path
weidongxu-microsoft Jul 2, 2024
50b90dc
re-generate test code
actions-user Jul 2, 2024
c6f8735
Merge branch 'main' into tsp_model-spread
weidongxu-microsoft Jul 3, 2024
bde16d8
re-generate test code
actions-user Jul 3, 2024
9474b90
update test
weidongxu-microsoft Jul 3, 2024
74a8748
Merge branch 'main' into tsp_model-spread
weidongxu-microsoft Jul 8, 2024
5caaeae
use tcgc 0.44.0-dev.19
weidongxu-microsoft Jul 8, 2024
63e1a5c
temporary remove typespec-autorest
weidongxu-microsoft Jul 8, 2024
3ef6725
tcgc 0.43.2
weidongxu-microsoft Jul 9, 2024
aacc6cd
Merge branch 'main' into tsp_model-spread
weidongxu-microsoft Jul 9, 2024
a9afb7b
re-generate test code
actions-user Jul 9, 2024
73ecf5f
update test
weidongxu-microsoft Jul 9, 2024
b5483ad
doc
weidongxu-microsoft Jul 10, 2024
0cb0d48
comment
weidongxu-microsoft Jul 10, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions typespec-extension/changelog.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
# Release History

## 0.18.0 (2024-07-10)

Compatible with compiler 0.57.

### Breaking Changes

- Request body without `@body` or `@bodyRoot`: the properties of the request body is flattened into method signature.

## 0.17.1 (2024-07-03)

Compatible with compiler 0.57.
Expand Down
881 changes: 306 additions & 575 deletions typespec-extension/package-lock.json

Large diffs are not rendered by default.

28 changes: 14 additions & 14 deletions typespec-extension/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@azure-tools/typespec-java",
"version": "0.17.1",
"version": "0.18.0",
"description": "TypeSpec library for emitting Java client from the TypeSpec REST protocol binding",
"keywords": [
"TypeSpec"
Expand Down Expand Up @@ -49,7 +49,7 @@
"@azure-tools/typespec-azure-resource-manager": ">=0.43.0 <1.0.0",
"@azure-tools/typespec-autorest": ">=0.43.0 <1.0.0",
"@azure-tools/typespec-azure-rulesets": ">=0.43.0 <1.0.0",
"@azure-tools/typespec-client-generator-core": ">=0.43.1 <1.0.0",
"@azure-tools/typespec-client-generator-core": ">=0.43.2 <1.0.0",
"@typespec/compiler": ">=0.57.0 <1.0.0",
"@typespec/http": ">=0.57.0 <1.0.0",
"@typespec/openapi": ">=0.57.0 <1.0.0",
Expand All @@ -67,25 +67,25 @@
"@azure-tools/typespec-azure-resource-manager": "0.43.0",
"@azure-tools/typespec-autorest": "0.43.0",
"@azure-tools/typespec-azure-rulesets": "0.43.0",
"@azure-tools/typespec-client-generator-core": "0.43.1",
"@azure-tools/typespec-client-generator-core": "0.43.2",
"@types/js-yaml": "~4.0.9",
"@types/lodash": "~4.17.1",
"@types/mocha": "~10.0.6",
"@types/node": "~20.12.10",
"@typescript-eslint/eslint-plugin": "~7.8.0",
"@typescript-eslint/parser": "~7.8.0",
"@types/lodash": "~4.17.6",
"@types/mocha": "~10.0.7",
"@types/node": "~20.14.10",
"@typescript-eslint/eslint-plugin": "~7.16.0",
"@typescript-eslint/parser": "~7.16.0",
"@typespec/compiler": "0.57.0",
"@typespec/http": "0.57.0",
"@typespec/openapi": "0.57.0",
"@typespec/rest": "0.57.0",
"@typespec/versioning": "0.57.0",
"@typespec/xml": "0.57.0",
"c8": "~9.1.0",
"c8": "~10.1.2",
"eslint": "~8.57.0",
"eslint-plugin-deprecation": "~2.0.0",
"mocha": "~10.4.0",
"prettier": "~3.2.5",
"rimraf": "~5.0.5",
"typescript": "~5.4.5"
"eslint-plugin-deprecation": "~3.0.0",
"mocha": "~10.6.0",
"prettier": "~3.3.2",
"rimraf": "~6.0.0",
"typescript": "~5.5.3"
}
}
12 changes: 8 additions & 4 deletions typespec-extension/src/code-model-builder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -801,7 +801,7 @@ export class CodeModelBuilder {
this.processParameterBody(codeModelOperation, op, op.parameters.body.property);
}
} else if (op.parameters.body.type) {
let bodyType = this.getEffectiveSchemaType(op.parameters.body.type);
let bodyType = op.parameters.body.type;

if (bodyType.kind === "Model") {
// try use resource type as round-trip model
Expand Down Expand Up @@ -1345,7 +1345,11 @@ export class CodeModelBuilder {
schema = this.processSchemaFromSdkType(sdkType, body.name);
}

const isAnonymousModel = sdkType.kind === "model" && sdkType.isGeneratedName === true;
// Explicit body parameter @body or @bodyRoot would result to body.kind === "ModelProperty"
// Implicit body parameter would result to body.kind === "Model"
// see https://typespec.io/docs/libraries/http/cheat-sheet#data-types
const bodyParameterFlatten = sdkType.kind === "model" && body.kind === "Model" && !this.isArm();

const parameterName = body.kind === "Model" ? (sdkType.kind === "model" ? sdkType.name : "") : this.getName(body);
const parameter = new Parameter(parameterName, this.getDoc(body), schema, {
summary: this.getSummary(body),
Expand All @@ -1371,8 +1375,8 @@ export class CodeModelBuilder {
this.trackSchemaUsage(schema, { serializationFormats: [KnownMediaType.Multipart] });
}

if (schema instanceof ObjectSchema && isAnonymousModel) {
// anonymous model
if (schema instanceof ObjectSchema && bodyParameterFlatten) {
// flatten body parameter

// name the schema for documentation
schema.language.default.name = pascalCase(op.language.default.name) + "Request";
Expand Down
8 changes: 4 additions & 4 deletions typespec-tests/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,12 @@
},
"dependencies": {
"@azure-tools/cadl-ranch-specs": "0.34.3",
"@azure-tools/typespec-java": "file:/../typespec-extension/azure-tools-typespec-java-0.17.1.tgz"
"@azure-tools/typespec-java": "file:/../typespec-extension/azure-tools-typespec-java-0.18.0.tgz"
},
"devDependencies": {
"@typespec/prettier-plugin-typespec": "~0.57.0",
"prettier-plugin-organize-imports": "3.2.4",
"prettier": "~3.2.5"
"prettier-plugin-organize-imports": "4.0.0",
"prettier": "~3.3.2"
},
"overrides": {
"@typespec/compiler": ">=0.57.0 <1.0.0",
Expand All @@ -25,7 +25,7 @@
"@typespec/openapi": ">=0.57.0 <1.0.0",
"@typespec/xml": ">=0.57.0 <1.0.0",
"@azure-tools/typespec-azure-core": ">=0.43.0 <1.0.0",
"@azure-tools/typespec-client-generator-core": ">=0.43.1 <1.0.0",
"@azure-tools/typespec-client-generator-core": "0.43.2",
"@azure-tools/typespec-azure-resource-manager": ">=0.43.0 <1.0.0",
"@azure-tools/typespec-autorest": ">=0.43.0 <1.0.0"
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
import com.azure.core.http.rest.Response;
import com.azure.core.util.BinaryData;
import com.azure.core.util.FluxUtil;
import com.client.naming.implementation.ModelsImpl;
import com.client.naming.implementation.ClientModelsImpl;
import com.client.naming.models.ClientModel;
import com.client.naming.models.JavaModel;
import reactor.core.publisher.Mono;
Expand All @@ -25,17 +25,17 @@
* Initializes a new instance of the asynchronous NamingClient type.
*/
@ServiceClient(builder = NamingClientBuilder.class, isAsync = true)
public final class ModelAsyncClient {
public final class ClientModelAsyncClient {
@Generated
private final ModelsImpl serviceClient;
private final ClientModelsImpl serviceClient;

/**
* Initializes an instance of ModelAsyncClient class.
* Initializes an instance of ClientModelAsyncClient class.
*
* @param serviceClient the service client implementation.
*/
@Generated
ModelAsyncClient(ModelsImpl serviceClient) {
ClientModelAsyncClient(ClientModelsImpl serviceClient) {
this.serviceClient = serviceClient;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,25 +15,25 @@
import com.azure.core.http.rest.RequestOptions;
import com.azure.core.http.rest.Response;
import com.azure.core.util.BinaryData;
import com.client.naming.implementation.ModelsImpl;
import com.client.naming.implementation.ClientModelsImpl;
import com.client.naming.models.ClientModel;
import com.client.naming.models.JavaModel;

/**
* Initializes a new instance of the synchronous NamingClient type.
*/
@ServiceClient(builder = NamingClientBuilder.class)
public final class ModelClient {
public final class ClientModelClient {
@Generated
Comment thread
haolingdong-msft marked this conversation as resolved.
private final ModelsImpl serviceClient;
private final ClientModelsImpl serviceClient;

/**
* Initializes an instance of ModelClient class.
* Initializes an instance of ClientModelClient class.
*
* @param serviceClient the service client implementation.
*/
@Generated
ModelClient(ModelsImpl serviceClient) {
ClientModelClient(ClientModelsImpl serviceClient) {
this.serviceClient = serviceClient;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,10 @@
@ServiceClientBuilder(
serviceClients = {
NamingClient.class,
ModelClient.class,
ClientModelClient.class,
UnionEnumClient.class,
NamingAsyncClient.class,
ModelAsyncClient.class,
ClientModelAsyncClient.class,
UnionEnumAsyncClient.class })
public final class NamingClientBuilder
implements HttpTrait<NamingClientBuilder>, ConfigurationTrait<NamingClientBuilder> {
Expand Down Expand Up @@ -262,13 +262,13 @@ public NamingAsyncClient buildAsyncClient() {
}

/**
* Builds an instance of ModelAsyncClient class.
* Builds an instance of ClientModelAsyncClient class.
*
* @return an instance of ModelAsyncClient.
* @return an instance of ClientModelAsyncClient.
*/
@Generated
public ModelAsyncClient buildModelAsyncClient() {
return new ModelAsyncClient(buildInnerClient().getModels());
public ClientModelAsyncClient buildClientModelAsyncClient() {
return new ClientModelAsyncClient(buildInnerClient().getClientModels());
}

/**
Expand All @@ -292,13 +292,13 @@ public NamingClient buildClient() {
}

/**
* Builds an instance of ModelClient class.
* Builds an instance of ClientModelClient class.
*
* @return an instance of ModelClient.
* @return an instance of ClientModelClient.
*/
@Generated
public ModelClient buildModelClient() {
return new ModelClient(buildInnerClient().getModels());
public ClientModelClient buildClientModelClient() {
return new ClientModelClient(buildInnerClient().getClientModels());
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,36 +26,37 @@
import reactor.core.publisher.Mono;

/**
* An instance of this class provides access to all the operations defined in Models.
* An instance of this class provides access to all the operations defined in ClientModels.
*/
public final class ModelsImpl {
public final class ClientModelsImpl {
/**
* The proxy service used to perform REST calls.
*/
private final ModelsService service;
private final ClientModelsService service;

/**
* The service client containing this operation class.
*/
private final NamingClientImpl client;

/**
* Initializes an instance of ModelsImpl.
* Initializes an instance of ClientModelsImpl.
*
* @param client the instance of the service client containing this operation class.
*/
ModelsImpl(NamingClientImpl client) {
this.service = RestProxy.create(ModelsService.class, client.getHttpPipeline(), client.getSerializerAdapter());
ClientModelsImpl(NamingClientImpl client) {
this.service
= RestProxy.create(ClientModelsService.class, client.getHttpPipeline(), client.getSerializerAdapter());
this.client = client;
}

/**
* The interface defining all the services for NamingClientModels to be used by the proxy service to perform REST
* calls.
* The interface defining all the services for NamingClientClientModels to be used by the proxy service to perform
* REST calls.
*/
@Host("http://localhost:3000")
@ServiceInterface(name = "NamingClientModels")
public interface ModelsService {
@ServiceInterface(name = "NamingClientClientMo")
public interface ClientModelsService {
@Post("/client/naming/model/client")
@ExpectedResponses({ 204 })
@UnexpectedResponseExceptionType(value = ClientAuthenticationException.class, code = { 401 })
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,17 +71,17 @@ public SerializerAdapter getSerializerAdapter() {
}

/**
* The ModelsImpl object to access its operations.
* The ClientModelsImpl object to access its operations.
*/
private final ModelsImpl models;
private final ClientModelsImpl clientModels;

/**
* Gets the ModelsImpl object to access its operations.
* Gets the ClientModelsImpl object to access its operations.
*
* @return the ModelsImpl object.
* @return the ClientModelsImpl object.
*/
public ModelsImpl getModels() {
return this.models;
public ClientModelsImpl getClientModels() {
return this.clientModels;
}

/**
Expand Down Expand Up @@ -124,7 +124,7 @@ public NamingClientImpl(HttpPipeline httpPipeline) {
public NamingClientImpl(HttpPipeline httpPipeline, SerializerAdapter serializerAdapter) {
this.httpPipeline = httpPipeline;
this.serializerAdapter = serializerAdapter;
this.models = new ModelsImpl(this);
this.clientModels = new ClientModelsImpl(this);
this.unionEnums = new UnionEnumsImpl(this);
this.service = RestProxy.create(NamingClientService.class, this.httpPipeline, this.getSerializerAdapter());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import com.azure.core.util.BinaryData;
import com.azure.core.util.FluxUtil;
import com.parameters.bodyoptionality.implementation.BodyOptionalityClientImpl;
import com.parameters.bodyoptionality.implementation.models.RequiredImplicitRequest;
import com.parameters.bodyoptionality.models.BodyModel;
import reactor.core.publisher.Mono;

Expand Down Expand Up @@ -72,7 +73,7 @@ public Mono<Response<Void>> requiredExplicitWithResponse(BinaryData body, Reques
* }
* }</pre>
*
* @param bodyModel The bodyModel parameter.
* @param requiredImplicitRequest The requiredImplicitRequest parameter.
* @param requestOptions The options to configure the HTTP request before HTTP client sends it.
* @throws HttpResponseException thrown if the request is rejected by server.
* @throws ClientAuthenticationException thrown if the request is rejected by server on status code 401.
Expand All @@ -82,8 +83,9 @@ public Mono<Response<Void>> requiredExplicitWithResponse(BinaryData body, Reques
*/
@Generated
@ServiceMethod(returns = ReturnType.SINGLE)
public Mono<Response<Void>> requiredImplicitWithResponse(BinaryData bodyModel, RequestOptions requestOptions) {
return this.serviceClient.requiredImplicitWithResponseAsync(bodyModel, requestOptions);
public Mono<Response<Void>> requiredImplicitWithResponse(BinaryData requiredImplicitRequest,
RequestOptions requestOptions) {
return this.serviceClient.requiredImplicitWithResponseAsync(requiredImplicitRequest, requestOptions);
}

/**
Expand All @@ -109,7 +111,7 @@ public Mono<Void> requiredExplicit(BodyModel body) {
/**
* The requiredImplicit operation.
*
* @param bodyModel The bodyModel parameter.
* @param name The name parameter.
* @throws IllegalArgumentException thrown if parameters fail the validation.
* @throws HttpResponseException thrown if the request is rejected by server.
* @throws ClientAuthenticationException thrown if the request is rejected by server on status code 401.
Expand All @@ -120,9 +122,11 @@ public Mono<Void> requiredExplicit(BodyModel body) {
*/
@Generated
@ServiceMethod(returns = ReturnType.SINGLE)
public Mono<Void> requiredImplicit(BodyModel bodyModel) {
public Mono<Void> requiredImplicit(String name) {
// Generated convenience method for requiredImplicitWithResponse
RequestOptions requestOptions = new RequestOptions();
return requiredImplicitWithResponse(BinaryData.fromObject(bodyModel), requestOptions).flatMap(FluxUtil::toMono);
RequiredImplicitRequest requiredImplicitRequestObj = new RequiredImplicitRequest(name);
BinaryData requiredImplicitRequest = BinaryData.fromObject(requiredImplicitRequestObj);
return requiredImplicitWithResponse(requiredImplicitRequest, requestOptions).flatMap(FluxUtil::toMono);
}
}
Loading