Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
b4f5cd7
minor: added long path support to prerequisite
radhgupta Oct 22, 2025
ccef568
Merge branch 'main' of https://github.com/microsoft/typespec
radhgupta Oct 23, 2025
3486047
Merge branch 'main' of https://github.com/microsoft/typespec
radhgupta Oct 31, 2025
25e823a
Merge branch 'main' of https://github.com/microsoft/typespec
radhgupta Nov 4, 2025
7958158
Merge branch 'main' of https://github.com/microsoft/typespec
radhgupta Nov 13, 2025
5227fce
Merge branch 'main' of https://github.com/microsoft/typespec
radhgupta Nov 13, 2025
175f199
Merge remote-tracking branch 'upstream/main'
radhgupta Nov 14, 2025
b39a7f4
Merge branch 'main' of https://github.com/microsoft/typespec
radhgupta Dec 1, 2025
699978e
Merge branch 'main' of https://github.com/microsoft/typespec
radhgupta Dec 15, 2025
d0909f3
Merge remote-tracking branch 'upstream/main'
radhgupta Jan 6, 2026
17ae707
Merge remote-tracking branch 'upstream/main'
radhgupta Jan 7, 2026
339819f
Merge remote-tracking branch 'upstream/main'
radhgupta Jan 13, 2026
9cb6c4c
Merge remote-tracking branch 'upstream/main'
radhgupta Jan 21, 2026
23227a6
merge
radhgupta Jan 22, 2026
11bd3b3
Merge remote-tracking branch 'upstream/main'
radhgupta Jan 28, 2026
e305a5e
reinject api-version parameter
radhgupta Jan 28, 2026
eef648e
api version reinjection
radhgupta Jan 28, 2026
be9b781
api version reinjection
radhgupta Jan 28, 2026
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
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ public class RestClientProvider : TypeProvider
private const string RepeatabilityRequestIdHeader = "Repeatability-Request-ID";
private const string RepeatabilityFirstSentHeader = "Repeatability-First-Sent";
private const string MaxPageSizeParameterName = "maxpagesize";
private const string ApiVersionParameterName = "api-version";

private static readonly Dictionary<string, ParameterProvider> _knownSpecialHeaderParams = new(StringComparer.OrdinalIgnoreCase)
{
Expand Down Expand Up @@ -306,6 +307,17 @@ private Dictionary<string, ParameterProvider> GetReinjectedParametersMap(
}
}

// Add API version parameters that need to be preserved across pagination requests
var apiVersionParam = operation.Parameters.FirstOrDefault(p => p.IsApiVersion);
if (apiVersionParam != null && !reinjectedParamsMap.ContainsKey(apiVersionParam.Name))
{
var createdParam = ScmCodeModelGenerator.Instance.TypeFactory.CreateParameter(apiVersionParam);
if (createdParam != null && paramMap.TryGetValue(createdParam.Name, out var paramInSignature))
{
reinjectedParamsMap[apiVersionParam.Name] = paramInSignature;
}
}

return reinjectedParamsMap;
}

Expand Down Expand Up @@ -452,7 +464,7 @@ private List<MethodBodyStatement> AppendQueryParameters(ScopedApi uri, InputOper

// Determine if we should update existing parameters or always append
bool shouldUpdateExisting = isNextLinkRequest &&
ShouldSkipReinjectedParameter(inputQueryParameter.SerializedName) &&
ShouldUpdateReinjectedParameter(inputQueryParameter.SerializedName) &&
paramType?.IsCollection != true;

MethodBodyStatement statement = shouldUpdateExisting
Expand Down Expand Up @@ -843,9 +855,10 @@ private static bool TryGetSpecialHeaderParam(InputParameter inputParameter, [Not
return false;
}

private static bool ShouldSkipReinjectedParameter(string parameterName)
private static bool ShouldUpdateReinjectedParameter(string parameterName)
{
return parameterName.Equals(MaxPageSizeParameterName, StringComparison.OrdinalIgnoreCase);
return parameterName.Equals(MaxPageSizeParameterName, StringComparison.OrdinalIgnoreCase) ||
parameterName.Equals(ApiVersionParameterName, StringComparison.OrdinalIgnoreCase);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what if the serialized name is apiversion ?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch - I think this check should be based on the Identity of the parameter rather than the name for both maxpagesize and apiVersion. We have logic to determine these parameters so we can reuse that.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@radhgupta - could we please open a follow item for this?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, fixing it right away

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@radhgupta - this isn't super urgent. We weren't updating the query parameter before, so if anything, this is just a gap in this functionality that was missed and should probably address 😃

// In the future, we can extend this to check multiple parameters
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1374,5 +1374,63 @@ private static IEnumerable<TestCaseData> ValidateApiVersionPathParameterTestCase
],
parameters: [endpointParameter, enumApiVersionParameter]));
}

[Test]
public void TestApiVersionParameterReinjectedInCreateNextRequestMethod()
{
// Create API version parameter marked with IsApiVersion = true
var apiVersionParam = InputFactory.QueryParameter("apiVersion", InputPrimitiveType.String,
isRequired: true, serializedName: "api-version", isApiVersion: true);
var pageSizeParam = InputFactory.QueryParameter("maxpagesize", InputPrimitiveType.Int32,
isRequired: false, serializedName: "maxpagesize");

List<InputParameter> parameters =
[
apiVersionParam,
pageSizeParam,
];

List<InputMethodParameter> methodParameters =
[
InputFactory.MethodParameter("apiVersion", InputPrimitiveType.String, isRequired: true,
location: InputRequestLocation.Query, serializedName: "api-version"),
InputFactory.MethodParameter("maxpagesize", InputPrimitiveType.Int32, isRequired: false,
location: InputRequestLocation.Query, serializedName: "maxpagesize"),
];

var inputModel = InputFactory.Model("Item", properties:
[
InputFactory.Property("id", InputPrimitiveType.String, isRequired: true),
]);

var pagingMetadata = InputFactory.NextLinkPagingMetadata(["value"], ["nextLink"],
InputResponseLocation.Body, reinjectedParameters: []);

var response = InputFactory.OperationResponse(
[200],
InputFactory.Model(
"PagedItems",
properties: [
InputFactory.Property("value", InputFactory.Array(inputModel)),
InputFactory.Property("nextLink", InputPrimitiveType.Url)
]));

var operation = InputFactory.Operation("listItems", responses: [response], parameters: parameters);
var inputServiceMethod = InputFactory.PagingServiceMethod(
"listItems",
operation,
pagingMetadata: pagingMetadata,
parameters: methodParameters);

var client = InputFactory.Client("TestClient", methods: [inputServiceMethod]);
var clientProvider = new ClientProvider(client);
var restClientProvider = new MockClientProvider(client, clientProvider);

var writer = new TypeProviderWriter(restClientProvider);
var file = writer.Write();

Assert.That(file.Content, Contains.Substring("api-version"));
Assert.That(file.Content, Contains.Substring("maxpagesize"));
}
}
}