Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[sdk/dotnet/nodejs] Add InvokeSingle variants to dotnet and nodejs SDKs #11564

Merged
merged 1 commit into from Dec 7, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
@@ -0,0 +1,4 @@
changes:
- type: feat
scope: sdk/dotnet,nodejs
description: Add InvokeSingle variants to dotnet and nodejs SDKs
29 changes: 29 additions & 0 deletions sdk/dotnet/Pulumi/Deployment/DeploymentInstance.cs
Expand Up @@ -50,6 +50,22 @@ internal DeploymentInstance(IDeployment deployment)
public Output<T> Invoke<T>(string token, InvokeArgs args, InvokeOptions? options = null)
=> _deployment.Invoke<T>(token, args, options);

/// <summary>
/// Dynamically invokes the function '<paramref name="token"/>', which is offered by a
/// provider plugin.
/// <para/>
/// The result of <see cref="InvokeSingle"/> will be a <see cref="Output"/> resolved to the
/// result value of the provider plugin.
/// <para/>
/// Similar to the earlier <see cref="InvokeSingleAsync"/>, but supports passing input values
/// and returns an Output value.
/// <para/>
/// The <paramref name="args"/> inputs can be a bag of computed values(including, `T`s,
/// <see cref="Task{TResult}"/>s, <see cref="Output{T}"/>s etc.).
/// </summary>
public Output<T> InvokeSingle<T>(string token, InvokeArgs args, InvokeOptions? options = null)
=> _deployment.InvokeSingle<T>(token, args, options);

/// <summary>
/// Dynamically invokes the function '<paramref name="token"/>', which is offered by a
/// provider plugin.
Expand All @@ -63,6 +79,19 @@ public Output<T> Invoke<T>(string token, InvokeArgs args, InvokeOptions? options
public Task<T> InvokeAsync<T>(string token, InvokeArgs args, InvokeOptions? options = null)
=> _deployment.InvokeAsync<T>(token, args, options);

/// <summary>
/// Dynamically invokes the function '<paramref name="token"/>', which is offered by a
/// provider plugin.
/// <para/>
/// The result of <see cref="InvokeSingleAsync"/> will be a <see cref="Task"/> resolved to the
/// result value of the provider plugin which is expected to be a dictionary with single value.
/// <para/>
/// The <paramref name="args"/> inputs can be a bag of computed values(including, `T`s,
/// <see cref="Task{TResult}"/>s, <see cref="Output{T}"/>s etc.).
/// </summary>
public Task<T> InvokeSingleAsync<T>(string token, InvokeArgs args, InvokeOptions? options = null)
=> _deployment.InvokeSingleAsync<T>(token, args, options);

/// <summary>
/// Same as <see cref="InvokeAsync{T}(string, InvokeArgs, InvokeOptions)"/>, however the
/// return value is ignored.
Expand Down
13 changes: 13 additions & 0 deletions sdk/dotnet/Pulumi/Deployment/Deployment_Invoke.cs
@@ -1,6 +1,7 @@
// Copyright 2016-2021, Pulumi Corporation

using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Linq;
using System.Threading.Tasks;
Expand All @@ -18,9 +19,21 @@ Task IDeployment.InvokeAsync(string token, InvokeArgs args, InvokeOptions? optio
Task<T> IDeployment.InvokeAsync<T>(string token, InvokeArgs args, InvokeOptions? options)
=> InvokeAsync<T>(token, args, options, convertResult: true);

async Task<T> IDeployment.InvokeSingleAsync<T>(string token, InvokeArgs args, InvokeOptions? options)
{
var outputs = await InvokeAsync<Dictionary<string, T>>(token, args, options, convertResult: true);
return outputs.Values.First();
}

Output<T> IDeployment.Invoke<T>(string token, InvokeArgs args, InvokeOptions? options)
=> new Output<T>(RawInvoke<T>(token, args, options));

Output<T> IDeployment.InvokeSingle<T>(string token, InvokeArgs args, InvokeOptions? options)
{
var outputResult = new Output<Dictionary<string, T>>(RawInvoke<Dictionary<string, T>>(token, args, options));
return outputResult.Apply(outputs => outputs.Values.First());
}

private async Task<OutputData<T>> RawInvoke<T>(string token, InvokeArgs args, InvokeOptions? options)
{
// This method backs all `Fn.Invoke()` calls that generate
Expand Down
24 changes: 24 additions & 0 deletions sdk/dotnet/Pulumi/Deployment/IDeployment.cs
Expand Up @@ -38,6 +38,18 @@ internal interface IDeployment
/// </summary>
Task<T> InvokeAsync<T>(string token, InvokeArgs args, InvokeOptions? options = null);

/// <summary>
/// Dynamically invokes the function '<paramref name="token"/>', which is offered by a
/// provider plugin.
/// <para/>
/// The result of <see cref="InvokeSingleAsync"/> will be a <see cref="Task"/> resolved to the
/// result value of the provider plugin that returns a bag of properties with a single value that is returned.
/// <para/>
/// The <paramref name="args"/> inputs can be a bag of computed values(including, `T`s,
/// <see cref="Task{TResult}"/>s, <see cref="Output{T}"/>s etc.).
/// </summary>
Task<T> InvokeSingleAsync<T>(string token, InvokeArgs args, InvokeOptions? options = null);

/// <summary>
/// Dynamically invokes the function '<paramref name="token"/>', which is offered by a
/// provider plugin.
Expand All @@ -50,6 +62,18 @@ internal interface IDeployment
/// </summary>
Output<T> Invoke<T>(string token, InvokeArgs args, InvokeOptions? options = null);

/// <summary>
/// Dynamically invokes the function '<paramref name="token"/>', which is offered by a
/// provider plugin.
/// <para/>
/// The result of <see cref="InvokeSingle"/> will be a <see cref="Output"/> resolved to the
/// result value of the provider plugin that returns a bag of properties with a single value that is returned.
/// <para/>
/// The <paramref name="args"/> inputs can be a bag of computed values(including, `T`s,
/// <see cref="Task{TResult}"/>s, <see cref="Output{T}"/>s etc.).
/// </summary>
Output<T> InvokeSingle<T>(string token, InvokeArgs args, InvokeOptions? options = null);

/// <summary>
/// Same as <see cref="InvokeAsync{T}(string, InvokeArgs, InvokeOptions)"/>, however the
/// return value is ignored.
Expand Down
4 changes: 3 additions & 1 deletion sdk/dotnet/Pulumi/PublicAPI.Shipped.txt
Expand Up @@ -91,6 +91,7 @@ Pulumi.DeploymentInstance.Call(string token, Pulumi.CallArgs args, Pulumi.Resour
Pulumi.DeploymentInstance.Call<T>(string token, Pulumi.CallArgs args, Pulumi.Resource self = null, Pulumi.CallOptions options = null) -> Pulumi.Output<T>
Pulumi.DeploymentInstance.InvokeAsync(string token, Pulumi.InvokeArgs args, Pulumi.InvokeOptions options = null) -> System.Threading.Tasks.Task
Pulumi.DeploymentInstance.InvokeAsync<T>(string token, Pulumi.InvokeArgs args, Pulumi.InvokeOptions options = null) -> System.Threading.Tasks.Task<T>
Pulumi.DeploymentInstance.InvokeSingleAsync<T>(string token, Pulumi.InvokeArgs args, Pulumi.InvokeOptions options = null) -> System.Threading.Tasks.Task<T>
Pulumi.DeploymentInstance.IsDryRun.get -> bool
Pulumi.DeploymentInstance.ProjectName.get -> string
Pulumi.DeploymentInstance.StackName.get -> string
Expand Down Expand Up @@ -395,4 +396,5 @@ static Pulumi.Urn.Create(Pulumi.Input<string> name, Pulumi.Input<string> type, P
static readonly Pulumi.CallArgs.Empty -> Pulumi.CallArgs
static readonly Pulumi.InvokeArgs.Empty -> Pulumi.InvokeArgs
static readonly Pulumi.ResourceArgs.Empty -> Pulumi.ResourceArgs
Pulumi.DeploymentInstance.Invoke<T>(string token, Pulumi.InvokeArgs args, Pulumi.InvokeOptions options = null) -> Pulumi.Output<T>
Pulumi.DeploymentInstance.Invoke<T>(string token, Pulumi.InvokeArgs args, Pulumi.InvokeOptions options = null) -> Pulumi.Output<T>
Pulumi.DeploymentInstance.InvokeSingle<T>(string token, Pulumi.InvokeArgs args, Pulumi.InvokeOptions options = null) -> Pulumi.Output<T>
13 changes: 13 additions & 0 deletions sdk/nodejs/runtime/invoke.ts
Expand Up @@ -74,6 +74,19 @@ export function invoke(tok: string, props: Inputs, opts: InvokeOptions = {}): Pr
return invokeAsync(tok, props, opts);
}

/*
* `invokeSingle` dynamically invokes the function, `tok`, which is offered by a provider plugin.
* Similar to `invoke`, but returns a single value instead of an object with a single key.
*/
export function invokeSingle(tok: string, props: Inputs, opts: InvokeOptions = {}): Promise<any> {
return invokeAsync(tok, props, opts).then(outputs => {
// assume outputs have a single key
const keys = Object.keys(outputs);
// return the first key's value from the outputs
return outputs[keys[0]];
});
}

export async function streamInvoke(
tok: string,
props: Inputs,
Expand Down