diff --git a/classlib/Cmdlets/BaseCmdlet.cs b/classlib/Cmdlets/BaseCmdlet.cs new file mode 100644 index 0000000..83dc9d3 --- /dev/null +++ b/classlib/Cmdlets/BaseCmdlet.cs @@ -0,0 +1,114 @@ +namespace PS.IPAM.Cmdlets; + +using System; +using System.Collections; +using System.Collections.Generic; +using System.Management.Automation; +using PS.IPAM.Helpers; + +/// +/// Base class for all PS.IPAM cmdlets providing common functionality. +/// +public abstract class BaseCmdlet : PSCmdlet +{ + /// + /// Writes the result to the pipeline, handling both single objects and collections. + /// + /// The result to write to the pipeline. + protected void WriteResult(object? result) + { + if (result == null) + { + return; + } + + if (result is IEnumerable enumerable && result is not string) + { + foreach (var item in enumerable) + { + WriteObject(item); + } + } + else + { + WriteObject(result); + } + } + + /// + /// Converts custom fields from various formats to a dictionary. + /// + /// The custom fields object to convert. + /// A dictionary of custom field names and values. + protected static Dictionary ConvertCustomFields(object? customFields) + { + if (customFields == null) + { + return new Dictionary(); + } + + if (customFields is PSObject psobj) + { + var dict = new Dictionary(); + foreach (var prop in psobj.Properties) + { + dict[prop.Name] = prop.Value ?? string.Empty; + } + return dict; + } + + if (customFields is Dictionary dictObj) + { + return dictObj; + } + + if (customFields is IDictionary genericDict) + { + var result = new Dictionary(); + foreach (DictionaryEntry entry in genericDict) + { + result[entry.Key?.ToString() ?? string.Empty] = entry.Value ?? string.Empty; + } + return result; + } + + return new Dictionary(); + } + + /// + /// Executes an async operation synchronously and handles errors. + /// + /// The return type of the operation. + /// The async operation to execute. + /// The error ID for error reporting. + /// The result of the operation, or default if an error occurred. + protected T? ExecuteAsync(Func> operation, string errorId) + { + try + { + return operation().GetAwaiter().GetResult(); + } + catch (Exception ex) + { + WriteError(new ErrorRecord(ex, errorId, ErrorCategory.InvalidOperation, null)); + return default; + } + } + + /// + /// Executes an async operation synchronously and handles errors. + /// + /// The async operation to execute. + /// The error ID for error reporting. + protected void ExecuteAsync(Func operation, string errorId) + { + try + { + operation().GetAwaiter().GetResult(); + } + catch (Exception ex) + { + WriteError(new ErrorRecord(ex, errorId, ErrorCategory.InvalidOperation, null)); + } + } +} diff --git a/classlib/IsExternalInit.cs b/classlib/IsExternalInit.cs new file mode 100644 index 0000000..85ba17f --- /dev/null +++ b/classlib/IsExternalInit.cs @@ -0,0 +1,23 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +// This file provides the IsExternalInit type required for using C# 9 records +// in projects targeting .NET Standard 2.1 or earlier. + +#if !NET5_0_OR_GREATER + +namespace System.Runtime.CompilerServices +{ + using System.ComponentModel; + + /// + /// Reserved to be used by the compiler for tracking metadata. + /// This class should not be used by developers in source code. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + internal static class IsExternalInit + { + } +} + +#endif diff --git a/classlib/enum/SessionStatus.cs b/classlib/enum/SessionStatus.cs new file mode 100644 index 0000000..0c9c73c --- /dev/null +++ b/classlib/enum/SessionStatus.cs @@ -0,0 +1,22 @@ +namespace PS.IPAM; + +/// +/// Represents the current status of an API session. +/// +public enum SessionStatus +{ + /// + /// No session exists or no token is available. + /// + NoSession, + + /// + /// The session token has expired. + /// + Expired, + + /// + /// The session is valid and ready for use. + /// + Valid +}