Skip to content

Commit cf74918

Browse files
authored
Fix inconsistent parameter name normalization for reserved keywords in spread body operations (#3679)
* fix * update * update * update ut * update ut * update ut
1 parent 7e85b02 commit cf74918

2 files changed

Lines changed: 129 additions & 3 deletions

File tree

packages/typespec-ts/src/modular/helpers/operationHelpers.ts

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1941,9 +1941,13 @@ export function getPropertyFullName(
19411941
property: SdkHttpParameter | SdkModelPropertyType,
19421942
propertyPath?: string
19431943
) {
1944-
const normalizedPropertyName = normalizeModelPropertyName(context, property)
1945-
.replace(/^"/g, "")
1946-
.replace(/"$/g, "");
1944+
const normalizedPropertyName =
1945+
propertyPath === ""
1946+
? normalizeName(property.name, NameType.Parameter, true)
1947+
: normalizeModelPropertyName(context, property)
1948+
.replace(/^"/g, "")
1949+
.replace(/"$/g, "");
1950+
19471951
let fullName = normalizedPropertyName;
19481952
if (propertyPath === "" && property.optional) {
19491953
fullName = `options?.${normalizedPropertyName}`;
Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
# should generate parameter name normalization for reserved keywords in spread body operations
2+
3+
## Typespec
4+
5+
```tsp
6+
import "@typespec/http";
7+
import "@typespec/rest";
8+
import "@typespec/versioning";
9+
import "@azure-tools/typespec-azure-core";
10+
import "@azure-tools/typespec-azure-resource-manager";
11+
import "@azure-tools/typespec-client-generator-core";
12+
13+
using TypeSpec.Http;
14+
using TypeSpec.Rest;
15+
using TypeSpec.Versioning;
16+
using Azure.Core;
17+
using Azure.ResourceManager;
18+
using Azure.ClientGenerator.Core;
19+
20+
/** Microsoft.Contoso Resource Provider management API. */
21+
@armProviderNamespace
22+
@service(#{
23+
title: "Microsoft.Contoso management service",
24+
})
25+
namespace Microsoft.Contoso;
26+
27+
model ResourceNameAvailabilityRequest {
28+
name: string;
29+
type: string;
30+
}
31+
32+
@summary("Check if a resource name is available.")
33+
@autoRoute
34+
@action("checknameavailability")
35+
op checkNameAvailability is ArmProviderActionSync<
36+
Request = ResourceNameAvailabilityRequest,
37+
Response = void,
38+
Scope = SubscriptionActionScope
39+
>;
40+
41+
op checkNameAvailabilityCustomized(
42+
...Azure.ResourceManager.CommonTypes.ApiVersionParameter,
43+
...Azure.ResourceManager.CommonTypes.SubscriptionIdParameter,
44+
...Azure.ResourceManager.Legacy.Provider,
45+
46+
name: string,
47+
type: string,
48+
): void;
49+
50+
@@override(checkNameAvailability,checkNameAvailabilityCustomized);
51+
```
52+
53+
This is the tspconfig.yaml.
54+
55+
```yaml
56+
withRawContent: true
57+
```
58+
59+
## Operations
60+
61+
```ts operations
62+
import { ContosoContext as Client } from "./index.js";
63+
import { errorResponseDeserializer } from "../models/models.js";
64+
import { expandUrlTemplate } from "../static-helpers/urlTemplate.js";
65+
import { CheckNameAvailabilityOptionalParams } from "./options.js";
66+
import {
67+
StreamableMethod,
68+
PathUncheckedResponse,
69+
createRestError,
70+
operationOptionsToRequestParameters,
71+
} from "@azure-rest/core-client";
72+
73+
export function _checkNameAvailabilitySend(
74+
context: Client,
75+
apiVersion: string,
76+
name: string,
77+
typeParam: string,
78+
options: CheckNameAvailabilityOptionalParams = { requestOptions: {} },
79+
): StreamableMethod {
80+
const path = expandUrlTemplate(
81+
"/subscriptions/{subscriptionId}/providers/Microsoft.ThisWillBeReplaced/checknameavailability{?api%2Dversion}",
82+
{
83+
subscriptionId: context.subscriptionId,
84+
"api%2Dversion": apiVersion,
85+
},
86+
{
87+
allowReserved: options?.requestOptions?.skipUrlEncoding,
88+
},
89+
);
90+
return context
91+
.path(path)
92+
.post({
93+
...operationOptionsToRequestParameters(options),
94+
contentType: "application/json",
95+
body: { name: name, type: typeParam },
96+
});
97+
}
98+
99+
export async function _checkNameAvailabilityDeserialize(
100+
result: PathUncheckedResponse,
101+
): Promise<void> {
102+
const expectedStatuses = ["204"];
103+
if (!expectedStatuses.includes(result.status)) {
104+
const error = createRestError(result);
105+
error.details = errorResponseDeserializer(result.body);
106+
throw error;
107+
}
108+
109+
return;
110+
}
111+
112+
export async function checkNameAvailability(
113+
context: Client,
114+
apiVersion: string,
115+
name: string,
116+
typeParam: string,
117+
options: CheckNameAvailabilityOptionalParams = { requestOptions: {} },
118+
): Promise<void> {
119+
const result = await _checkNameAvailabilitySend(context, apiVersion, name, typeParam, options);
120+
return _checkNameAvailabilityDeserialize(result);
121+
}
122+
```

0 commit comments

Comments
 (0)