Private/Throttle/Resolve-ThrottleOperationName.ps1
|
<#
Copyright (c) 2025-2026 Robert Faddes SPDX-License-Identifier: MPL-2.0 #> <# .SYNOPSIS Resolves an API path and HTTP method to a rate-limit operation name. .DESCRIPTION Uses the explicit operation mapping table to classify an API request. If no explicit match is found, infers an operation name from the path structure and HTTP method using Datto RMM naming conventions. Returns $null for GET requests, which are not write-limited. Unknown write operations emit a debug trace indicating inference. #> function Resolve-ThrottleOperationName { [CmdletBinding()] param ( [Parameter(Mandatory)] [string] $Path, [Parameter(Mandatory)] [Microsoft.PowerShell.Commands.WebRequestMethod] $Method ) # GET requests are never write-limited — no operation name needed if ($Method -eq 'Get') { return $null } # Normalise: strip query parameters and any leading api/v2/ or v2/ prefix $NormPath = ($Path -replace '\?.*$', '') -replace '^(api/)?v2/', '' -replace '^/', '' # Replace GUIDs and numeric IDs in path segments with {id} placeholder for mapping lookup $TemplatePath = $NormPath -replace '[0-9a-fA-F]{8}(-[0-9a-fA-F]{4}){3}-[0-9a-fA-F]{12}', '{id}' -replace '(?<=(/|^))\d+(?=(/|$))', '{id}' # Try explicit mapping first $MapKey = "$($Method.ToString().ToUpper()):$TemplatePath" if ($Script:OperationMapping.ContainsKey($MapKey)) { Write-Debug "Throttle: Operation classified via mapping — $MapKey → $($Script:OperationMapping[$MapKey])" return $Script:OperationMapping[$MapKey] } # Fallback: infer operation name from path segments and HTTP method $Segments = ($TemplatePath -replace '/{id}', '' -replace '{id}/', '' -replace '{id}', '') -split '/' | Where-Object {$_} $MethodSuffix = switch ($Method.ToString().ToUpper()) { 'POST' {'update'} 'PUT' {'create'} 'DELETE' {'delete'} 'PATCH' {'update'} default {'unknown'} } $InferredName = ($Segments -join '-') + "-$MethodSuffix" Write-Debug "Throttle: Operation name inferred (no explicit mapping) — $MapKey → $InferredName" return $InferredName } # SIG # Begin signature block # MIIF+wYJKoZIhvcNAQcCoIIF7DCCBegCAQExDzANBglghkgBZQMEAgEFADB5Bgor # BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG # KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCAkrAv4jX1gGyeI # sLr835sv+9eH69enRIpUAUP5O1V4cqCCA04wggNKMIICMqADAgECAhB464iXHfI6 # gksEkDDTyrNsMA0GCSqGSIb3DQEBCwUAMD0xFjAUBgNVBAoMDVJvYmVydCBGYWRk # ZXMxIzAhBgNVBAMMGkRhdHRvUk1NLkNvcmUgQ29kZSBTaWduaW5nMB4XDTI2MDMz # MTAwMTMzMFoXDTI4MDMzMTAwMjMzMFowPTEWMBQGA1UECgwNUm9iZXJ0IEZhZGRl # czEjMCEGA1UEAwwaRGF0dG9STU0uQ29yZSBDb2RlIFNpZ25pbmcwggEiMA0GCSqG # SIb3DQEBAQUAA4IBDwAwggEKAoIBAQChn1EpMYQgl1RgWzQj2+wp2mvdfb3UsaBS # nxEVGoQ0gj96tJ2MHAF7zsITdUjwaflKS1vE6wAlOg5EI1V79tJCMxzM0bFpOdR1 # L5F2HE/ovIAKNkHxFUF5qWU8vVeAsOViFQ4yhHpzLen0WLF6vhmc9eH23dLQy5fy # tELZQEc2WbQFa4HMAitP/P9kHAu6CUx5s4woLIOyyR06jkr3l9vk0sxcbCxx7+dF # RrsSLyPYPH+bUAB8+a0hs+6qCeteBuUfLvGzpMhpzKAsY82WZ3Rd9X38i32dYj+y # dYx+nx+UEMDLjDJrZgnVa8as4RojqVLcEns5yb/XTjLxDc58VatdAgMBAAGjRjBE # MA4GA1UdDwEB/wQEAwIHgDATBgNVHSUEDDAKBggrBgEFBQcDAzAdBgNVHQ4EFgQU # H+B0vf97dYXqdUX1YMcWhFsY6fcwDQYJKoZIhvcNAQELBQADggEBAJmD4EEGNmcD # 1JtFoRGxuLJaTHxDwBsjqcRQRE1VPZNGaiwIm8oSQdHVjQg0oIyK7SEb02cs6n6Y # NZbwf7B7WZJ4aKYbcoLug1k1x9SoqwBmfElECeJTKXf6dkRRNmrAodpGCixR4wMH # KXqwqP5F+5j7bdnQPiIVXuMesxc4tktz362ysph1bqKjDQSCBpwi0glEIH7bv5Ms # Ey9Gl3fe+vYC5W06d2LYVebEfm9+7766hsOgpdDVgdtnN+e6uwIJjG/6PTG6TMDP # y+pr5K6LyUVYJYcWWUTZRBqqwBHiLGekPbxrjEVfxUY32Pq4QfLzUH5hhUCAk4HN # XpF9pOzFLMUxggIDMIIB/wIBATBRMD0xFjAUBgNVBAoMDVJvYmVydCBGYWRkZXMx # IzAhBgNVBAMMGkRhdHRvUk1NLkNvcmUgQ29kZSBTaWduaW5nAhB464iXHfI6gksE # kDDTyrNsMA0GCWCGSAFlAwQCAQUAoIGEMBgGCisGAQQBgjcCAQwxCjAIoAKAAKEC # gAAwGQYJKoZIhvcNAQkDMQwGCisGAQQBgjcCAQQwHAYKKwYBBAGCNwIBCzEOMAwG # CisGAQQBgjcCARUwLwYJKoZIhvcNAQkEMSIEIIIgHGbXurszacvPCGdFSy0uDK9e # ipvnU77D/J70Q8GbMA0GCSqGSIb3DQEBAQUABIIBAF+imQ3y1VkSnsobZBcXv3x7 # 6UmoHUx0QVF0gTwBKzY8R+rXEhUs3owSFXFOuzQLO1NNkgbs8USGcwcbdevGqnkv # jtWwN4r9xAnA7dTCJiVTJlOV1LQn8ePVZiCUd+khLs3WSxM8eXi4jOJvBzsmh5v8 # FOJVdF95iCNdGPPNULgZABfZ86uQi4ynAxjYcWyJoNf91j061/dkW0eXN9Yx1Hm0 # WGPOuSRwa/32EocHyWz8nlSBfhI0VAZpU563YZtuuJixIrbcirHips1OMpnaJ14j # iRGiwzbc8MTT7nDNEg1gqRqNv4wqockoRw0a+3TJi/34ry1zQYY8EHWBtyQm4ls= # SIG # End signature block |