diff --git a/resend-dotnet.sln b/resend-dotnet.sln
index 5e0551a..bc51def 100644
--- a/resend-dotnet.sln
+++ b/resend-dotnet.sln
@@ -60,6 +60,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RenderLiquid", "examples\Re
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WebControllerApi", "examples\WebControllerApi\WebControllerApi.csproj", "{64049053-1C1E-43D6-A23B-5A609354934B}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Resend.DocsCheck", "tools\Resend.DocsCheck\Resend.DocsCheck.csproj", "{ED268270-FD7F-4111-8B54-020C81F8D683}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -130,6 +132,10 @@ Global
{64049053-1C1E-43D6-A23B-5A609354934B}.Debug|Any CPU.Build.0 = Debug|Any CPU
{64049053-1C1E-43D6-A23B-5A609354934B}.Release|Any CPU.ActiveCfg = Release|Any CPU
{64049053-1C1E-43D6-A23B-5A609354934B}.Release|Any CPU.Build.0 = Release|Any CPU
+ {ED268270-FD7F-4111-8B54-020C81F8D683}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {ED268270-FD7F-4111-8B54-020C81F8D683}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {ED268270-FD7F-4111-8B54-020C81F8D683}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {ED268270-FD7F-4111-8B54-020C81F8D683}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -151,6 +157,7 @@ Global
{C33A6269-8657-4487-8CDD-588210E20B65} = {121B647E-18F4-41CB-AC00-49D5F06D5320}
{FD4407E3-551D-48F8-9FFB-63E409F4C4BB} = {121B647E-18F4-41CB-AC00-49D5F06D5320}
{64049053-1C1E-43D6-A23B-5A609354934B} = {121B647E-18F4-41CB-AC00-49D5F06D5320}
+ {ED268270-FD7F-4111-8B54-020C81F8D683} = {CAC9B80A-B362-4135-AC30-8013D0DB6124}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {15EEB6F3-A067-45F5-987C-824BD8FDEAF9}
diff --git a/src/Resend.Webhooks/WebApplicationExtensions.cs b/src/Resend.Webhooks/WebApplicationExtensions.cs
index 0c2072b..7efbec2 100644
--- a/src/Resend.Webhooks/WebApplicationExtensions.cs
+++ b/src/Resend.Webhooks/WebApplicationExtensions.cs
@@ -1,6 +1,4 @@
-using Microsoft.AspNetCore.Http;
-using Microsoft.AspNetCore.Mvc;
-using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.DependencyInjection;
using Resend.Webhooks;
namespace Microsoft.AspNetCore.Builder;
@@ -12,6 +10,7 @@ public static class WebApplicationExtensions
///
///
///
+ ///
///
public static IServiceCollection AddResendWebhooks( this IServiceCollection services, Action? configureOptions = null )
{
diff --git a/src/Resend/IResend.cs b/src/Resend/IResend.cs
index 970f200..32d28e1 100644
--- a/src/Resend/IResend.cs
+++ b/src/Resend/IResend.cs
@@ -110,7 +110,7 @@ public interface IResend
/// Domain.
///
///
- Task> DomainAddAsync( string domainName, DeliveryRegion? region, CancellationToken cancellationToken = default );
+ Task> DomainAddAsync( string domainName, DeliveryRegion? region = null, CancellationToken cancellationToken = default );
///
diff --git a/src/Resend/ResendClient.cs b/src/Resend/ResendClient.cs
index 4ff375d..f0ecd70 100644
--- a/src/Resend/ResendClient.cs
+++ b/src/Resend/ResendClient.cs
@@ -113,7 +113,7 @@ public ResendClient( IOptions options, HttpClient httpClien
///
- public async Task> DomainAddAsync( string domainName, DeliveryRegion? region, CancellationToken cancellationToken = default )
+ public async Task> DomainAddAsync( string domainName, DeliveryRegion? region = null, CancellationToken cancellationToken = default )
{
var path = $"/domains";
var req = new HttpRequestMessage( HttpMethod.Post, path );
@@ -653,4 +653,42 @@ private ResendRateLimit FromHeaders( HttpResponseHeaders headers )
return (T) Convert.ChangeType( v, typeof( T ) );
}
+
+
+ ///
+ /// Creates an instance of Resend client with the given client
+ /// options.
+ ///
+ /// Resend client options.
+ /// Instance of Resend client.
+ ///
+ /// Utility method for examples/one-off apps. For most use-cases it is
+ /// preferable to use dependency injection to configure/inject `IResend`
+ /// instances.
+ ///
+ public static IResend Create( ResendClientOptions options )
+ {
+ var opt = Options.Create( options );
+
+ return new ResendClient( opt, new HttpClient() );
+ }
+
+
+ ///
+ /// Creates an instance of Resend with the given API token.
+ ///
+ /// API token
+ /// Instance of Resend client.
+ ///
+ /// Utility method for examples/one-off apps. For most use-cases it is
+ /// preferable to use dependency injection to configure/inject `IResend`
+ /// instances.
+ ///
+ public static IResend Create( string apiToken )
+ {
+ var opt = new ResendClientOptions();
+ opt.ApiToken = apiToken;
+
+ return Create( opt );
+ }
}
diff --git a/tools/Resend.DocsCheck/Program.cs b/tools/Resend.DocsCheck/Program.cs
new file mode 100644
index 0000000..f9039e7
--- /dev/null
+++ b/tools/Resend.DocsCheck/Program.cs
@@ -0,0 +1,211 @@
+using McMaster.Extensions.CommandLineUtils;
+using Microsoft.CodeAnalysis;
+using Microsoft.CodeAnalysis.CSharp;
+using Microsoft.CodeAnalysis.Emit;
+using Microsoft.Extensions.DependencyInjection;
+using System.ComponentModel.DataAnnotations;
+using System.Reflection;
+using System.Text;
+
+namespace Resend.DocsCheck;
+
+///
+public class Program
+{
+ ///
+ public static int Main( string[] args )
+ {
+ /*
+ *
+ */
+ var app = new CommandLineApplication();
+
+ var svc = new ServiceCollection();
+
+ var sp = svc.BuildServiceProvider();
+
+
+ /*
+ *
+ */
+ try
+ {
+ app.Conventions
+ .UseDefaultConventions()
+ .UseConstructorInjection( sp );
+ }
+ catch ( Exception ex )
+ {
+ Console.WriteLine( "ftl: unhandled exception during setup" );
+ Console.WriteLine( ex.ToString() );
+
+ return 2;
+ }
+
+
+ /*
+ *
+ */
+ try
+ {
+ return app.Execute( args );
+ }
+ catch ( UnrecognizedCommandParsingException ex )
+ {
+ Console.WriteLine( "err: " + ex.Message );
+
+ return 2;
+ }
+ catch ( Exception ex )
+ {
+ Console.WriteLine( "ftl: unhandled exception during execution" );
+ Console.WriteLine( ex.ToString() );
+
+ return 2;
+ }
+ }
+
+
+ ///
+ [Option( "-r|--root", Description = "" )]
+ [DirectoryExists]
+ [Required]
+ public string? RootFolder { get; set; }
+
+
+ ///
+ public async Task OnExecute()
+ {
+ var dir = new DirectoryInfo( this.RootFolder! );
+
+ foreach ( var f in dir.GetFiles( "*.mdx", SearchOption.AllDirectories ) )
+ {
+ await FileCheck( dir, f );
+ }
+
+ return 0;
+ }
+
+
+ ///
+ private async Task FileCheck( DirectoryInfo root, FileInfo f )
+ {
+ var rel = GetRelativePath( root, f );
+ var mdx = await File.ReadAllTextAsync( f.FullName );
+
+
+ /*
+ *
+ */
+ var startIx = mdx.IndexOf( "```csharp" );
+
+ if ( startIx < 0 )
+ return;
+
+ var endIx = mdx.IndexOf( "```", startIx + 4 );
+
+
+ var fragment = mdx.Substring( startIx, endIx - startIx + 3 );
+
+
+ /*
+ *
+ */
+ var lines = fragment.Split( "\n" );
+
+ var sb = new StringBuilder();
+ sb.AppendLine( "using System;" );
+ sb.AppendLine( "using System.Threading.Tasks;" );
+
+ foreach ( var l in lines )
+ if ( l.StartsWith( "using " ) == true )
+ sb.AppendLine( l );
+
+ sb.AppendLine();
+ sb.AppendLine( "public class Program {" );
+ sb.AppendLine( "public static async Task Main( string[] args ) {" );
+
+ foreach ( var l in lines.Skip( 1 ).Take( lines.Count() - 2 ) )
+ {
+ if ( l.StartsWith( "using " ) == true )
+ continue;
+
+ sb.AppendLine( l );
+ }
+
+ sb.AppendLine( "return 0; } }" );
+
+ var csharp = sb.ToString();
+
+
+ /*
+ *
+ */
+ SyntaxTree syntaxTree = CSharpSyntaxTree.ParseText( csharp );
+
+ var assemblyName = Path.GetRandomFileName();
+ var references = new MetadataReference[]
+ {
+ MetadataReference.CreateFromFile( typeof( Object ).Assembly.Location ),
+ MetadataReference.CreateFromFile( Assembly.Load( "System.Console" ).Location ),
+ MetadataReference.CreateFromFile( Assembly.Load( "System.Runtime" ).Location ),
+ MetadataReference.CreateFromFile( Assembly.Load( "System.Collections" ).Location ),
+ MetadataReference.CreateFromFile( typeof( List<> ).Assembly.Location ),
+ MetadataReference.CreateFromFile( typeof( IResend ).Assembly.Location ),
+ };
+
+ CSharpCompilation compilation = CSharpCompilation.Create(
+ assemblyName,
+ syntaxTrees: new[] { syntaxTree },
+ references: references,
+ options: new CSharpCompilationOptions( OutputKind.DynamicallyLinkedLibrary ) );
+
+ using ( var ms = new MemoryStream() )
+ {
+ EmitResult result = compilation.Emit( ms );
+
+ if ( result.Success == false )
+ {
+ // handle exceptions
+ IEnumerable failures = result.Diagnostics.Where( diagnostic =>
+ diagnostic.IsWarningAsError ||
+ diagnostic.Severity == DiagnosticSeverity.Error );
+
+ var fg = Console.ForegroundColor;
+ Console.ForegroundColor = ConsoleColor.Red;
+ Console.Write( "err" );
+ Console.ForegroundColor = fg;
+
+ Console.Write( " " );
+ Console.WriteLine( rel );
+
+ foreach ( Diagnostic diagnostic in failures )
+ {
+ Console.Error.WriteLine( "{0}: {1}", diagnostic.Id, diagnostic.GetMessage() );
+ }
+ }
+ else
+ {
+ var fg = Console.ForegroundColor;
+ Console.ForegroundColor = ConsoleColor.Green;
+ Console.Write( "aok" );
+ Console.ForegroundColor = fg;
+
+ Console.Write( " " );
+ Console.WriteLine( rel );
+ }
+ }
+ }
+
+
+ ///
+ private static string GetRelativePath( DirectoryInfo directoryInfo, FileInfo fileInfo )
+ {
+ Uri directoryUri = new Uri( directoryInfo.FullName + Path.DirectorySeparatorChar );
+ Uri fileUri = new Uri( fileInfo.FullName );
+ Uri relativeUri = directoryUri.MakeRelativeUri( fileUri );
+ string relativePath = Uri.UnescapeDataString( relativeUri.ToString() );
+
+ return relativePath.Replace( '/', Path.DirectorySeparatorChar );
+ }
+}
\ No newline at end of file
diff --git a/tools/Resend.DocsCheck/Resend.DocsCheck.csproj b/tools/Resend.DocsCheck/Resend.DocsCheck.csproj
new file mode 100644
index 0000000..af4c46d
--- /dev/null
+++ b/tools/Resend.DocsCheck/Resend.DocsCheck.csproj
@@ -0,0 +1,20 @@
+
+
+
+ Exe
+ net8.0
+ enable
+ enable
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/tools/Resend.DocsCheck/api-check.cmd b/tools/Resend.DocsCheck/api-check.cmd
new file mode 100644
index 0000000..271d148
--- /dev/null
+++ b/tools/Resend.DocsCheck/api-check.cmd
@@ -0,0 +1 @@
+dotnet run -- --root=..\..\..\resend-docs\api-reference
\ No newline at end of file
diff --git a/tools/Resend.DocsCheck/api-check.sh b/tools/Resend.DocsCheck/api-check.sh
new file mode 100644
index 0000000..8aae991
--- /dev/null
+++ b/tools/Resend.DocsCheck/api-check.sh
@@ -0,0 +1 @@
+dotnet run -- --root=../../../resend-docs/api-reference