BaseApiBuilder.psm1

#Region './prefix.ps1' -1

Add-Type -AssemblyName System.Web
Add-Type -AssemblyName System.Net.Http
#EndRegion './prefix.ps1' 3
#Region './Private/Invoke-BuildCondition.ps1' -1

<#
.SYNOPSIS
    Constructs a conditional string for querying based on specified field and details.

.DESCRIPTION
    The Invoke-BuildCondition function generates a query condition string dynamically based on the input field and details provided.
    It constructs the condition by iterating over each operation in the details hashtable and formatting it into a string
    that can be used in a query statement.

.PARAMETER field
    The field name which the conditions will be applied to.

.PARAMETER details
    A hashtable where keys are the operation (like '=', '<', '>', 'LIKE', etc.) and values are the conditions to be applied.
    These values can be a single value or an array of values for the specified operation.

.EXAMPLE
    $details = @{
        '=' = 'Windows'
        '!=' = 'Linux'
    }
    $condition = Invoke-BuildCondition -field 'OS' -details $details
    # Output: (OS = 'Windows' or OS != 'Linux')

.EXAMPLE
    $details = @{
        'LIKE' = @('Windows%', 'Linux%')
    }
    $condition = Invoke-BuildCondition -field 'OS' -details $details
    # Output: (OS LIKE 'Windows%' or OS LIKE 'Linux%')

.NOTES
    Ensure that the values in the details parameter are correct and that any strings that need to be escaped
    are handled prior to calling this function, using the 'Escape-FilterValue' function to avoid query errors.

.INPUTS
    String, Hashtable

.OUTPUTS
    String

.LINK
    Invoke-EscapeFilterValue
#>


function Invoke-BuildCondition([string]$field, [hashtable]$details)
{
    $condition = ""
    foreach ($op in $details.Keys)
    {
        $values = $details[$op]
        if ($values -isnot [array])
        {
            $values = @($values)  # Ensure $values is always an array
        }
        $subConditions = @($values | ForEach-Object {
                $value = Invoke-EscapeFilterValue $_
                "$field $op '$value'"
            })
        if ($subConditions.Count -gt 1)
        {
            $conditionPart = '(' + ($subConditions -join ' or ') + ')'
        }
        else
        {
            $conditionPart = $subConditions[0]
        }
        $condition += "$conditionPart and "
    }
    return $condition.TrimEnd(' and ')
}
#EndRegion './Private/Invoke-BuildCondition.ps1' 72
#Region './Private/Invoke-EscapeFilterValue.ps1' -1

<#
.SYNOPSIS
    Escapes special characters in a string for use in filter queries.

.DESCRIPTION
    The Invoke-EscapeFilterValue function escapes characters that have special significance
    in query languages, such as backslashes (\), asterisks (*), and double quotes (").
    This is necessary to prevent these characters from being processed as control characters
    in queries, ensuring the string is treated as literal text.

.PARAMETER value
    The string value that needs escaping.

.EXAMPLE
    $escapedValue = Invoke-EscapeFilterValue -value 'C:\Temp\*file*.txt'
    # Output: 'C:\\Temp\\*file*\\.txt'

.EXAMPLE
    $userInput = '"SELECT * FROM users WHERE name LIKE "%Smith%"'
    $safeInput = Invoke-EscapeFilterValue -value $userInput
    # Output: '\"SELECT * FROM users WHERE name LIKE \"%Smith%\"'

.NOTES
    This function is typically used before incorporating user input into a query string
    to avoid SQL injection or similar query manipulation issues.

.INPUTS
    String

.OUTPUTS
    String

.LINK
    Invoke-BuildCondition
#>


function Invoke-EscapeFilterValue([string]$value)
{
    # Escapes quotes, asterisks, and backslashes
    return $value -replace '\\', '\\\\' -replace '\*', '\\*' -replace '\"', '\\"'
}
#EndRegion './Private/Invoke-EscapeFilterValue.ps1' 42
#Region './Public/Close-ApiSession.ps1' -1

<#
.SYNOPSIS
Closes the current API session.

.DESCRIPTION
The Close-ApiSession function clears the current API session stored in a script-scoped variable, effectively ending the session. This is typically used to clean up session data after API interactions are complete.

.EXAMPLE
Close-ApiSession

This example demonstrates how to call the Close-ApiSession function to clear the current API session.

.NOTES
This function checks if the $script:apiSession variable is populated before attempting to clear it to prevent errors.

.LINK
Get-CurrentApiSession
Initialize-ApiSession

#>


function Close-ApiSession {
    if(-not $script:apiSession) {
        return
    }
    $script:apiSession.Clear()
}
#EndRegion './Public/Close-ApiSession.ps1' 28
#Region './Public/ConvertTo-PlainText.ps1' -1

<#
.SYNOPSIS
   Converts a PSCredential object's password to plain text.

.DESCRIPTION
   The ConvertTo-PlainText function takes a PSCredential object as input and converts the secure string password to plain text.

.PARAMETER Credential
   The PSCredential object whose password is to be converted to plain text. This is a mandatory parameter.

.EXAMPLE
   $cred = Get-Credential
   ConvertTo-PlainText -Credential $cred

   This example demonstrates how to use the ConvertTo-PlainText function. It first prompts the user for a username and password (Get-Credential), then converts the password to plain text.

.NOTES
   Be careful when using this function, as it can expose sensitive password information in plain text.
#>

function ConvertTo-PlainText {
    [CmdletBinding()]
    param (
        [Parameter(Mandatory = $true)]
        [System.Management.Automation.PSCredential]
        $Credential
    )

    try {
        $bstr = [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($Credential.Password)
        $PlainTextPassword = [System.Runtime.InteropServices.Marshal]::PtrToStringAuto($bstr)
    }
    finally {
        if ($null -ne $bstr) {
            [System.Runtime.InteropServices.Marshal]::ZeroFreeBSTR($bstr)
        }
    }

    return $PlainTextPassword
}
#EndRegion './Public/ConvertTo-PlainText.ps1' 40
#Region './Public/Get-ApiWebSession.ps1' -1

<#
.SYNOPSIS
Retrieves the current API web session.

.DESCRIPTION
The Get-ApiWebSession function returns the web session object stored in a script-scoped variable. This session object can be used for making authenticated web requests to the API.

.EXAMPLE
$session = Get-ApiWebSession

This example demonstrates how to retrieve the current API web session and store it in a variable.

.NOTES
This function is part of the BaseApiBuilder module which provides a set of tools for interacting with RESTful APIs.

.LINK
Initialize-ApiSession - For initializing a new API session.
Close-ApiSession - For closing the current API session.
#>


Function Get-ApiWebSession {

    return $script:apiSession.WebSession

}
#EndRegion './Public/Get-ApiWebSession.ps1' 26
#Region './Public/Get-AuthHeaders.ps1' -1

<#
.SYNOPSIS
Retrieves the authentication headers for the current API session.

.DESCRIPTION
The Get-AuthHeaders function returns the authentication headers stored in a script-scoped variable. These headers are used for making authenticated requests to the API. If the authentication headers are not set, the function will throw an error instructing to initialize an authentication session.

.EXAMPLE
$headers = Get-AuthHeaders

This example demonstrates how to retrieve the authentication headers for the current API session.

.NOTES
This function is part of the BaseApiBuilder module which provides a set of tools for interacting with RESTful APIs. It requires an active authentication session initialized by calling Initialize-AuthSession.

.LINK
Initialize-AuthSession - For initializing the authentication session.
Close-ApiSession - For closing the current API session.

#>


function Get-AuthHeaders {
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseSingularNouns','')]
    [CmdletBinding()]
    param()
    if ($null -eq $script:apiSession.AuthHeaders) {
        Write-Error "Authentication is required. Please call Initialize-AuthSession."
        exit
    }
    return $script:apiSession.AuthHeaders
}
#EndRegion './Public/Get-AuthHeaders.ps1' 32
#Region './Public/Get-BaseUri.ps1' -1

<#
.SYNOPSIS
Retrieves the base URI for the current API session.

.DESCRIPTION
The Get-BaseUri function returns the base URI stored in a script-scoped variable if it has been set. If the base URI is not set, it throws an error instructing the user to initialize it using Set-BaseUri.

.EXAMPLE
$baseUri = Get-BaseUri

This example demonstrates how to retrieve the base URI for the current API session.

.NOTES
This function is part of the BaseApiBuilder module which provides a set of tools for interacting with RESTful APIs. It requires the base URI to be initialized before calling this function.

.LINK
Set-BaseUri - For initializing the base URI for the API session..

#>


function Get-BaseUri {
    [CmdletBinding()]
    param ()

    # Check if the apiSession is initialized and contains the BaseUrl
    if ($script:apiSession -and $script:apiSession.Contains("BaseUri") -and $null -ne $script:apiSession.BaseUri) {
        return $script:apiSession["BaseUri"]
    }
    else {
        Write-Error "BaseUri is not set. Please initialize it using Set-BaseUri."
        return $null
    }
}
#EndRegion './Public/Get-BaseUri.ps1' 34
#Region './Public/Get-CurrentApiSession.ps1' -1

<#
.SYNOPSIS
Retrieves the current API session.

.DESCRIPTION
The Get-CurrentApiSession function returns the current API session object stored in a script-scoped variable. This session object can be used to manage and maintain state across multiple API calls within the same session.

.EXAMPLE
$session = Get-CurrentApiSession

This example demonstrates how to retrieve the current API session and store it in a variable.

.NOTES
This function is part of the BaseApiBuilder module which provides a set of tools for interacting with RESTful APIs. It is essential for managing the lifecycle of an API session.

.LINK
Initialize-ApiSession - For initializing a new API session.
Close-ApiSession - For closing the current API session.
Get-ApiWebSession - For retrieving the web session object.
Get-AuthHeaders - For retrieving authentication headers for the current session.
#>


function Get-CurrentApiSession {
    return $script:apiSession
}
#EndRegion './Public/Get-CurrentApiSession.ps1' 26
#Region './Public/Initialize-ApiSession.ps1' -1

<#
.SYNOPSIS
    Initializes an API session by setting up web request headers, a user agent, and an optional base URI.

.DESCRIPTION
    The Initialize-ApiSession function sets up a session for interacting with APIs. It combines authentication and custom headers,
    sets a user agent, optionally configures a base URI, and initializes a web request session. It closes any existing API session
    before setting up a new one.

.PARAMETER BaseURI
    The base URI for the API. This is not mandatory but recommended if all requests will use the same base URI.

.PARAMETER AuthHeaders
    A hashtable of authentication headers. Default is an empty hashtable.

.PARAMETER CustomHeaders
    A hashtable of custom headers to be used in the API session. Default is an empty hashtable.

.PARAMETER UserAgent
    The user agent string to be used in the session. Defaults to "PowerShell API Client".

.PARAMETER WebSession
    An existing WebRequestSession object that can be reused. If not provided, a new session will be created.

.EXAMPLE
    $authHeaders = @{ "Authorization" = "Bearer your_token" }
    $session = Initialize-ApiSession -BaseURI "https://api.example.com" -AuthHeaders $authHeaders

.OUTPUTS
    Hashtable
    Returns a hashtable containing session details including time, base URI, authentication headers, and the web request session.
#>

function Initialize-ApiSession
{
    [CmdletBinding()]
    [OutputType([bool])]
    param (
        [Parameter(Mandatory = $false)]
        [string]$BaseURI,

        [Parameter()]
        [Hashtable]$AuthHeaders = @{},

        [Parameter()]
        [Hashtable]$CustomHeaders = @{},

        [Parameter()]
        [string]$UserAgent = "PowerShell API Client",

        [Parameter()]
        [Microsoft.PowerShell.Commands.WebRequestSession]$WebSession
    )

    Close-ApiSession

    $CombinedHeaders = $AuthHeaders + $CustomHeaders
    if ($UserAgent)
    {
        $CombinedHeaders["User-Agent"] = $UserAgent
    }

    if ($BaseURI)
    {
        #Set-BaseUri -Uri $BaseURI
    }

    if (-not $WebSession)
    {
        $WebSession = Initialize-WebRequestSession -Headers $CombinedHeaders
    }

    $hash = @{
        Time        = (Get-Date)
        BaseUri     = $BaseURI
        AuthHeaders = $AuthHeaders
        WebSession  = $WebSession
    }

    Set-CurrentApiSession -SessionHash $hash
    Write-Verbose "API session initialized successfully."

    return (Get-CurrentApiSession)
}
#EndRegion './Public/Initialize-ApiSession.ps1' 84
#Region './Public/Initialize-AuthSession.ps1' -1

<#
.SYNOPSIS
Initializes an authentication session for API calls.

.DESCRIPTION
The Initialize-AuthSession function is designed to create an authentication session using either an API key or user credentials. It returns a hashtable with the necessary authorization headers for making authenticated API requests. If an API key is provided, it uses Bearer authentication; otherwise, it uses Basic authentication with the provided credentials.

.PARAMETER ApiKey
The API key for Bearer authentication. This parameter is optional and mutually exclusive with the Credentials parameter.

.PARAMETER Credentials
The user credentials for Basic authentication. This parameter is optional and mutually exclusive with the ApiKey parameter.

.EXAMPLE
$authSession = Initialize-AuthSession -ApiKey 'your_api_key_here'
This example demonstrates how to initialize an authentication session using an API key.

.EXAMPLE
$creds = Get-Credential
$authSession = Initialize-AuthSession -Credentials $creds
This example demonstrates how to initialize an authentication session using user credentials.

.NOTES
This function requires either an ApiKey or Credentials parameter to be provided. If neither or both are provided, it will result in an error.

.LINK
Get-AuthHeaders - For retrieving authentication headers for the current session.
#>


function Initialize-AuthSession {
    [OutputType([hashtable])]
    [CmdletBinding()]
    param(
        [string]$ApiKey = $null,
        [PSCredential]$Credentials = $null
    )

    if ($ApiKey) {
        $authSession = @{ Authorization = "Bearer $ApiKey" }
        return $authSession
    }
    elseif ($Credentials) {
        if ($network) { $Pass = $($Credentials.GetNetworkCredential().Password) }
        else { $Pass = (ConvertTo-PlainText -Credential $Credentials) }
        $authSession = @{ Authorization = "Basic " + [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes("$($Credentials.UserName):$($Pass)")) }
        return $authSession
    }
    else {
        Write-Error "No valid authentication method provided."
    }
}
#EndRegion './Public/Initialize-AuthSession.ps1' 52
#Region './Public/Initialize-WebRequestSession.ps1' -1

<#
.SYNOPSIS
    Initializes and returns a web request session object with custom headers and credentials.

.DESCRIPTION
    The Initialize-WebRequestSession function creates a new web request session, configuring it with optional headers,
    credentials, and a cookie container to manage cookies across requests. This session can be used with various
    cmdlets that require a WebRequestSession parameter.

.PARAMETER Headers
    A hashtable containing headers to be added to the web request session. Default is an empty hashtable.

.PARAMETER Credentials
    A PSCredential object containing user credentials for the web request session.

.EXAMPLE
    $headers = @{ "Authorization" = "Bearer token" }
    $creds = Get-Credential
    $session = Initialize-WebRequestSession -Headers $headers -Credentials $creds
    Invoke-WebRequest -Uri "https://example.com" -WebSession $session

.OUTPUTS
    Microsoft.PowerShell.Commands.WebRequestSession
    Returns a WebRequestSession object configured with headers, credentials, and cookie management.
#>

function Initialize-WebRequestSession
{
    [CmdletBinding()]
    param(
        [Parameter()]
        [hashtable]$Headers = @{},

        [Parameter()]
        [PSCredential]$Credentials
    )

    $session = New-Object Microsoft.PowerShell.Commands.WebRequestSession

    foreach ($key in $Headers.Keys)
    {
        $session.Headers.Add($key, $Headers[$key])
        Write-Verbose "Added header: $key with value: $($Headers[$key])"
    }

    if ($Credentials)
    {
        $session.Credentials = $Credentials
        Write-Verbose "Credentials set for the session."
    }

    $session.Cookies = New-Object System.Net.CookieContainer
    Write-Verbose "Cookie container initialized."

    # [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 | [Net.SecurityProtocolType]::Tls11 | [Net.SecurityProtocolType]::Tls
    Write-Verbose "Web request session object created."

    return $session
}
#EndRegion './Public/Initialize-WebRequestSession.ps1' 59
#Region './Public/Invoke-ApiRequest.ps1' -1

<#
.SYNOPSIS
    Invokes an API request to a specified endpoint.

.DESCRIPTION
    The Invoke-ApiRequest function sends an HTTP request to the specified API endpoint. It can handle various HTTP methods and allows for additional query parameters and request body content.

.PARAMETER UriPrefix
    The base URI prefix for the API endpoint.

.PARAMETER Endpoint
    The specific API endpoint to which the request will be sent.

.PARAMETER QueryParams
    A hashtable of query parameters to be appended to the endpoint. Default is an empty hashtable.

.PARAMETER Method
    The HTTP method to be used for the request. Default is "Get".

.PARAMETER Body
    The content body of the request, used with methods like POST or PUT.

.EXAMPLE
    $response = Invoke-ApiRequest -UriPrefix "https://api.example.com" -Endpoint "data" -Method "Get"

    This example sends a GET request to https://api.example.com/data.

.EXAMPLE
    $body = @{name="John"; age=30} | ConvertTo-Json
    $response = Invoke-ApiRequest -UriPrefix "https://api.example.com" -Endpoint "users" -Method "Post" -Body $body

    This example sends a POST request to https://api.example.com/users with a JSON body containing name and age.

.OUTPUTS
    Object
    Returns the response from the API request.

.NOTES
    Ensure that the API endpoint and UriPrefix are correctly configured within the function.

.LINK
    For more information on HTTP methods: https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods
#>


function Invoke-ApiRequest {
    [OutputType([PSCustomObject])]
    [CmdletBinding()]
    param (
        [Parameter(Mandatory)]
        [string]$UriPrefix,

        [Parameter(Mandatory)]
        [string]$Endpoint,

        [Parameter()]
        [hashtable]$QueryParams = @{},

        [Parameter()]
        [string]$Method = "Get",

        [Parameter()]
        [string]$Body
    )

    $BaseURI = Get-BaseUri
    $CombinedUri = Join-Path $UriPrefix $Endpoint
    $Uri = New-ApiUri -BaseUri $BaseURI -Endpoint $CombinedUri -QueryParams $QueryParams

    $webSession = Get-ApiWebSession

    # Prepare the parameters hashtable for Invoke-RestMethod
    $restParams = @{
        Uri         = $Uri
        Method      = $Method
        WebSession  = $webSession
    }

    # Conditionally add the Body parameter if it's provided
    if ($Body) {
        $restParams['Body'] = $Body
    }

    # Execute the API request
    $response = Invoke-RestMethod @restParams
    return $response
}
#EndRegion './Public/Invoke-ApiRequest.ps1' 87
#Region './Public/New-ApiSession.ps1' -1

<#
.SYNOPSIS
Creates a new API session object.

.DESCRIPTION
The New-ApiSession function initializes a new, empty API session object as a script-scoped hashtable. This session object is used to store session-specific information such as authentication headers, base URI, and other relevant data for making API calls.

.EXAMPLE
New-ApiSession

This example demonstrates how to create a new API session object.

.NOTES
This function is part of the BaseApiBuilder module which provides a set of tools for interacting with RESTful APIs. It is the first step in establishing a session for API interactions.

#>


function New-ApiSession {
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseShouldProcessForStateChangingFunctions', '')]
    [CmdletBinding()]
    param ()

    $script:apiSession = @{}

}
#EndRegion './Public/New-ApiSession.ps1' 26
#Region './Public/New-ApiUri.ps1' -1

<#
.SYNOPSIS
Creates a new API URI based on base URI, endpoint, and query parameters.

.DESCRIPTION
The New-ApiUri function constructs a complete URI for API calls. It takes a base URI, an endpoint, and an optional hashtable of query parameters, then returns the constructed URI. If query parameters include nested hashtables, they are converted into a filter string format.

.PARAMETER BaseUri
The base URI of the API.

.PARAMETER Endpoint
The specific endpoint to be appended to the base URI.

.PARAMETER QueryParams
An optional hashtable of query parameters to be appended to the URI. Supports nested hashtables for complex filters.

.EXAMPLE
$baseUri = "https://api.example.com"
$endpoint = "data"
$queryParams = @{ "filter" = "active"; "sort" = "name" }
$uri = New-ApiUri -BaseUri $baseUri -Endpoint $endpoint -QueryParams $queryParams

This example constructs a URI for the "data" endpoint on "https://api.example.com", with a filter for active items and sorting by name.

.NOTES
This function is part of a PowerShell module designed to simplify API interactions by generating URIs dynamically based on provided parameters.

.LINK
- Get-AuthHeaders - For retrieving authentication headers for API calls.
- Initialize-ApiSession - For initializing a new API session.
#>


function New-ApiUri
{
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseShouldProcessForStateChangingFunctions', '')]
    [CmdletBinding()]
    param(
        [string]$BaseUri,
        [string]$Endpoint,
        [hashtable]$QueryParams
    )

    $uriBuilder = New-Object System.UriBuilder $BaseUri
    $uriBuilder.Path += $Endpoint

    # Build the query string from the hashtable
    $query = $QueryParams.GetEnumerator() | Where-Object {
        # Exclude null or empty values
        $null -ne $_.Value -and ($_.Value -isnot [string] -or -not [string]::IsNullOrEmpty($_.Value))
    } | ForEach-Object {
        $key = [Uri]::EscapeDataString($_.Key)
        $value = $_.Value

        # Handle complex filters stored in a nested hashtable
        if ($value -is [hashtable])
        {
            # Convert hashtable to a filter string (e.g., "key1='value1' and key2='value2'")
            $filterConditions = $value.GetEnumerator() | Where-Object {
                $null -ne $_.Value -and ($_.Value -isnot [string] -or -not [string]::IsNullOrEmpty($_.Value))
            } | ForEach-Object {
                $filterKey = $_.Key
                $filterValue = $_.Value
                "$filterKey='$filterValue'"
            }
            $value = $filterConditions -join ' and '
        }

        # Prepare the key-value pair for the query string if not empty
        if (-not [string]::IsNullOrEmpty($value))
        {
            $value = [Uri]::EscapeDataString($value)
            "$key=$value"
        }
    }

    # Only join non-empty entries
    $uriBuilder.Query = ($query | Where-Object { $_ }) -join '&'

    # Return the complete URI
    return $uriBuilder.Uri.AbsoluteUri
}
#EndRegion './Public/New-ApiUri.ps1' 82
#Region './Public/New-FilterQuery.ps1' -1

<#
.SYNOPSIS
    Constructs a complete filter query string from a hashtable of filter conditions.

.DESCRIPTION
    The New-FilterQuery function constructs a comprehensive query string by processing a hashtable
    where each key-value pair represents a field and its associated conditions.
    It uses the Invoke-BuildCondition function to generate conditional strings for each field,
    and then combines these conditions into a single query string using logical 'and'.

.PARAMETER Filters
    A hashtable containing the fields and their corresponding conditions.
    Each key in the hashtable is a field name, and each value is another hashtable
    where the keys are operators (e.g., '=', '<', 'LIKE') and the values are the conditions
    to apply with those operators.

.EXAMPLE
    $filters = @{
        'Name' = @{
            'LIKE' = 'John%'
        }
        'Age' = @{
            '>=' = 30
        }
    }
    $query = New-FilterQuery -Filters $filters
    # Output: (Name LIKE 'John%') and (Age >= '30')

.NOTES
    This function relies on Invoke-BuildCondition to handle the creation of condition strings.
    Ensure that the filters and values provided are valid and that they are formatted correctly
    to avoid errors in the query construction.

.INPUTS
    Hashtable

.OUTPUTS
    String

.LINK
    Invoke-BuildCondition
    Invoke-EscapeFilterValue
#>

function New-FilterQuery
{
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseShouldProcessForStateChangingFunctions', '')]
    [CmdletBinding()]
    param (
        [Parameter(Mandatory = $true)]
        [hashtable]$Filters
    )

    $queryParts = @()
    foreach ($field in $Filters.Keys)
    {
        $details = $Filters[$field]
        $queryParts += Invoke-BuildCondition $field $details
    }

    $queryString = $queryParts -join ' and '
    return $queryString
}
#EndRegion './Public/New-FilterQuery.ps1' 63
#Region './Public/Set-BaseUri.ps1' -1

<#
.SYNOPSIS
Sets the base URI for API calls.

.DESCRIPTION
The Set-BaseUri function is used to set the base URI for subsequent API calls. It stores the base URI in a script-scoped variable for use by other functions in the module.

.PARAMETER Uri
The base URI to be used for API calls. This parameter is mandatory.

.EXAMPLE
Set-BaseUri -Uri "https://api.example.com"

This example sets the base URI to "https://api.example.com" for all subsequent API calls.

.NOTES
This function is part of a PowerShell module designed to simplify interactions with RESTful APIs by managing session state, including authentication and base URIs.

.LINK
- Initialize-AuthSession - For initializing the authentication session.
- New-ApiSession - For creating a new API session object.
#>


function Set-BaseUri {
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseShouldProcessForStateChangingFunctions', '')]
    [CmdletBinding()]
    param (
        [Parameter(Mandatory = $true)]
        [string]$Uri
    )

    # Ensure the apiSession variable is initialized
    if (-not $script:apiSession) {
        $script:apiSession = @{}
    }

    # Set the BaseUrl in the apiSession
    $script:apiSession["BaseUri"] = $Uri
    Write-Verbose "BaseUri set to: $Uri"
}
#EndRegion './Public/Set-BaseUri.ps1' 41
#Region './Public/Set-CurrentApiSession.ps1' -1

<#
.SYNOPSIS
    Sets the current API session to a specified session hash.

.DESCRIPTION
    The Set-CurrentApiSession function updates the global variable $script:apiSession with a new session hash.
    This session hash typically includes session details such as the base URI, headers, and other configurations.

.PARAMETER SessionHash
    A hashtable containing the session details to be set as the current API session.

.EXAMPLE
    $sessionDetails = @{
        Time = (Get-Date)
        BaseUri = 'https://api.example.com'
        AuthHeaders = @{ Authorization = "Bearer your_token_here" }
    }
    Set-CurrentApiSession -SessionHash $sessionDetails
    This example sets the current API session to the specified session details.

.OUTPUTS
    None. This function updates a global variable and does not output directly.

.NOTES
    This function is typically used in scripts where API session details need to be maintained across multiple function calls.
#>

function Set-CurrentApiSession
{
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseShouldProcessForStateChangingFunctions', '')]
    [CmdletBinding()]
    param (
        [Parameter(Mandatory = $True)]
        [hashtable]$SessionHash
    )

    $script:apiSession = $SessionHash
    Write-Verbose "API session updated successfully."
}
#EndRegion './Public/Set-CurrentApiSession.ps1' 39
#Region './Public/Test-ApiSession.ps1' -1

<#
.SYNOPSIS
Tests the current API session for validity and throws an error if the session is invalid.

.DESCRIPTION
The Test-ApiSession function checks if the current API session is initialized and if the web session within it is valid. If either condition is not met, the function throws an error that stops execution, indicating that the API session is not valid. This behavior ensures that subsequent API operations are not attempted on an invalid session.

.EXAMPLE
try {
    Test-ApiSession
    # Additional code to run on a valid session
} catch {
    Write-Error "Session validation failed: $_"
}

This example demonstrates how to call the Test-ApiSession function within a try/catch block to handle possible errors from an invalid API session.

.NOTES
This function is part of a PowerShell module designed to manage API sessions. It is crucial to use this function to ensure that an API session is properly initialized and valid before attempting to make API calls. The function will halt script execution if the session is found to be invalid.

.LINK
- Get-CurrentApiSession - For retrieving the current API session.
- New-ApiSession - For creating a new API session.
#>


function Test-ApiSession {
    [CmdletBinding()]
    [OutputType([void])]
    param ()

    $functionName = $(($MyInvocation.MyCommand).Name)
    $VerbosePrefix = "[${functionName}] -"

    # Check if the API session is initialized
    $currentSession = Get-CurrentApiSession
    if (-not $currentSession) {
        Write-Verbose "$VerbosePrefix API session is not initialized."
        Throw "API session is not initialized."
    }

    # Check if the web session is valid
    if (-not $currentSession.WebSession) {
        Write-Verbose "$VerbosePrefix Web session is not valid."
        Throw "Web session is not valid."
    }

    Write-Verbose "API session is valid."
}
#EndRegion './Public/Test-ApiSession.ps1' 49