Web.psm1

[CmdletBinding()]
param()
$baseName = [System.IO.Path]::GetFileNameWithoutExtension($PSCommandPath)
$script:PSModuleInfo = Test-ModuleManifest -Path "$PSScriptRoot\$baseName.psd1"
$script:PSModuleInfo | Format-List | Out-String -Stream | ForEach-Object { Write-Debug $_ }
$scriptName = $script:PSModuleInfo.Name
Write-Debug "[$scriptName] - Importing module"
#region [functions] - [public]
Write-Debug "[$scriptName] - [functions] - [public] - Processing folder"
#region [functions] - [public] - [ConvertTo-WebQueryString]
Write-Debug "[$scriptName] - [functions] - [public] - [ConvertTo-WebQueryString] - Importing"
filter ConvertTo-WebQueryString {
    <#
        .SYNOPSIS
        Converts an object to a properly formatted web query string.

        .DESCRIPTION
        This function takes an input object (typically a hashtable) and converts it into a web query string.
        It encodes the keys and values to ensure compatibility with URLs.
        If the `-AsURLEncoded` switch is provided, the encoding will be URL-friendly, using `+` for spaces instead of `%20`.

        .EXAMPLE
        ConvertTo-WebQueryString -InputObject @{a = 1; b = 2 }

        ?a=1&b=2

        Converts a hashtable into a query string with key-value pairs.

        .EXAMPLE
        ConvertTo-WebQueryString -InputObject @{a='this is value of a'; b='valueOfB'}

        ?a=this%20is%20value%20of%20a&b=valueOfB

        Converts a hashtable where values contain spaces. The default encoding uses `%20` for spaces.

        .EXAMPLE
        ConvertTo-WebQueryString -InputObject @{a='this is value of a'; b='valueOfB'} -AsURLEncoded

        ?a=this+is+value+of+a&b=valueOfB

        Converts a hashtable while using `+` for spaces, which is preferred in some URL encoding schemes.

        .LINK
        https://psmodule.io/Web/Functions/ConvertTo-WebQueryString/
    #>

    [OutputType([string])]
    [CmdletBinding()]
    param(
        # The input object to be converted into a query string.
        # Must be a hashtable or convertible to one.
        [Parameter(
            Mandatory,
            ValueFromPipeline
        )]
        [hashtable] $InputObject,

        # Switch to enable alternative URL encoding (`+` for spaces).
        [Parameter()]
        [switch] $AsURLEncoded
    )

    $parameters = if ($AsURLEncoded) {
        ($InputObject.GetEnumerator() | ForEach-Object {
            "$([System.Web.HttpUtility]::UrlEncode($_.Key))=$([System.Web.HttpUtility]::UrlEncode($_.Value))"
        }) -join '&'
    } else {
        ($InputObject.GetEnumerator() | ForEach-Object {
            "$([System.Uri]::EscapeDataString($_.Key))=$([System.Uri]::EscapeDataString($_.Value))"
        }) -join '&'
    }

    if ($parameters) {
        '?' + $parameters
    }
}
Write-Debug "[$scriptName] - [functions] - [public] - [ConvertTo-WebQueryString] - Done"
#endregion [functions] - [public] - [ConvertTo-WebQueryString]
#region [functions] - [public] - [Join-WebUri]
Write-Debug "[$scriptName] - [functions] - [public] - [Join-WebUri] - Importing"
function Join-WebUri {
    <#
        .SYNOPSIS
        Join a base URI with a child paths.

        .DESCRIPTION
        Join a base URI with a child paths to create a new URI.
        The child paths are normalized before joining with the base URI.

        .EXAMPLE
        Join-WebUri -Path 'https://example.com' -ChildPath 'foo' -AdditionalChildPath 'bar'
        https://example.com/foo/bar

        Joins the base URI <https://example.com> with the child paths 'foo' and 'bar' to create the URI <https://example.com/foo/bar>.

        .EXAMPLE
        Join-WebUri 'https://example.com' '/foo/' '/bar/' '//baz/something/' '/test/'

        <https://example.com/foo/bar/baz/something/test>

        Combines the base URI <https://example.com> with the child paths '/foo/', '/bar/', '//baz/something/', and '/test/'.

        .LINK
        https://psmodule.io/Web/Functions/Join-WebUri/
    #>

    [OutputType([string])]
    [CmdletBinding()]
    param (
        # The base URI to join with the child path.
        [Parameter(Mandatory)]
        [uri] $Path,

        # The child path to join with the base URI.
        [Parameter(Mandatory)]
        [string] $ChildPath,

        # Additional child paths to join with the base URI.
        [Parameter(ValueFromRemainingArguments)]
        [string[]] $AdditionalChildPath
    )

    $segments = $ChildPath, $AdditionalChildPath
    $normalizedSegments = $segments | ForEach-Object { $_.Trim('/') }
    $uri = $Path.ToString().TrimEnd('/') + '/' + ($normalizedSegments -join '/')
    $uri
}
Write-Debug "[$scriptName] - [functions] - [public] - [Join-WebUri] - Done"
#endregion [functions] - [public] - [Join-WebUri]
Write-Debug "[$scriptName] - [functions] - [public] - Done"
#endregion [functions] - [public]

#region Member exporter
$exports = @{
    Alias    = '*'
    Cmdlet   = ''
    Function = @(
        'ConvertTo-WebQueryString'
        'Join-WebUri'
    )
}
Export-ModuleMember @exports
#endregion Member exporter