Skip to content

Commit 78f0e06

Browse files
committed
Adding support for optional parameters when resolving dynamic schemas.
1 parent bee6dce commit 78f0e06

2 files changed

Lines changed: 11 additions & 37 deletions

File tree

src/libraries/Microsoft.PowerFx.Connectors/ConnectorFunction.cs

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1449,23 +1449,25 @@ private FormulaValue[] GetArguments(ConnectorDynamicApi dynamicApi, NamedValue[]
14491449

14501450
ConnectorFunction functionToBeCalled = EnsureConnectorFunction(dynamicApi, GlobalContext.FunctionList).ConnectorFunction;
14511451

1452-
foreach (ConnectorParameter connectorParameter in functionToBeCalled.RequiredParameters)
1452+
var parameters = functionToBeCalled.RequiredParameters.Union(functionToBeCalled.OptionalParameters);
1453+
1454+
foreach (ConnectorParameter connectorParameter in parameters)
14531455
{
1454-
string requiredParameterName = connectorParameter.Name;
1456+
string parameterName = connectorParameter.Name;
14551457

1456-
// TODO: properly implement the ability to reference child properties instead of simplistic check "GetLastPart(kvp.Key) == requiredParameterName"
1458+
// TODO: properly implement the ability to reference child properties instead of simplistic check "GetLastPart(kvp.Key) == parameterName"
14571459
// doc: https://learn.microsoft.com/en-us/connectors/custom-connectors/openapi-extensions
14581460
// e.g. make this example working:
14591461
// "destinationInputParam1/property1": {
14601462
// "parameterReference": "sourceInputParam1/property1"
14611463
// }
1462-
if (dynamicApi.ParameterMap.FirstOrDefault(kvp => kvp.Value is StaticConnectorExtensionValue && GetLastPart(kvp.Key) == requiredParameterName).Value is StaticConnectorExtensionValue sValue)
1464+
if (dynamicApi.ParameterMap.FirstOrDefault(kvp => kvp.Value is StaticConnectorExtensionValue && GetLastPart(kvp.Key) == parameterName).Value is StaticConnectorExtensionValue sValue)
14631465
{
14641466
arguments.Add(sValue.Value);
14651467
continue;
14661468
}
14671469

1468-
KeyValuePair<string, IConnectorExtensionValue> dValue = dynamicApi.ParameterMap.FirstOrDefault(kvp => kvp.Value is DynamicConnectorExtensionValue dv && GetLastPart(kvp.Key) == requiredParameterName);
1470+
KeyValuePair<string, IConnectorExtensionValue> dValue = dynamicApi.ParameterMap.FirstOrDefault(kvp => kvp.Value is DynamicConnectorExtensionValue dv && GetLastPart(kvp.Key) == parameterName);
14691471
string[] referenceList = ((DynamicConnectorExtensionValue)dValue.Value).Reference.Split('/');
14701472

14711473
var parameterToUse = knownParameters.FirstOrDefault(nv => nv.Name == referenceList.First())?.Value;

src/libraries/Microsoft.PowerFx.Connectors/Execution/HttpFunctionInvoker.cs

Lines changed: 4 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -209,7 +209,6 @@ public async Task<HttpRequestMessage> BuildRequest(IReadOnlyList<FormulaValue> a
209209
public Dictionary<string, FormulaValue> ConvertToNamedParameters(IReadOnlyList<FormulaValue> args)
210210
{
211211
// First N are required params.
212-
// Last param is a record with each field being an optional.
213212
// Parameter names are case sensitive.
214213

215214
Dictionary<string, FormulaValue> map = new ();
@@ -225,11 +224,12 @@ public Dictionary<string, FormulaValue> ConvertToNamedParameters(IReadOnlyList<F
225224
{
226225
map[param.Name] = param.DefaultValue;
227226
}
227+
228+
var parameters = _function.RequiredParameters.Union(_function.OptionalParameters).ToArray();
228229

229-
// Required parameters are always first
230-
for (int i = 0; i < _function.RequiredParameters.Length; i++)
230+
for (var i = 0; i < args.Count; i++)
231231
{
232-
string parameterName = _function.RequiredParameters[i].Name;
232+
string parameterName = parameters[i].Name;
233233
FormulaValue paramValue = args[i];
234234

235235
// Objects are always flattenned
@@ -254,34 +254,6 @@ public Dictionary<string, FormulaValue> ConvertToNamedParameters(IReadOnlyList<F
254254
}
255255
}
256256

257-
// Optional parameters are next and stored in a Record
258-
if (_function.OptionalParameters.Length > 0 && args.Count > _function.RequiredParameters.Length)
259-
{
260-
FormulaValue optionalArg = args[args.Count - 1];
261-
262-
// Objects are always flattenned
263-
if (optionalArg is RecordValue record)
264-
{
265-
foreach (NamedValue field in record.Fields)
266-
{
267-
if (map.ContainsKey(field.Name))
268-
{
269-
// if optional parameters are defined and a default value is already present
270-
map[field.Name] = field.Value;
271-
}
272-
else
273-
{
274-
map.Add(field.Name, field.Value);
275-
}
276-
}
277-
}
278-
else
279-
{
280-
// Type check should have caught this.
281-
throw new PowerFxConnectorException($"Optional arguments must be the last argument and a record");
282-
}
283-
}
284-
285257
return map;
286258
}
287259

0 commit comments

Comments
 (0)