| | | 1 | | <# |
| | | 2 | | .SYNOPSIS |
| | | 3 | | Adds a named scriptblock to the specified scope, allowing retrieval via a getter function. |
| | | 4 | | .DESCRIPTION |
| | | 5 | | This function allows you to define a scriptblock with a name and an optional scope (Global or Script). |
| | | 6 | | The scriptblock can be retrieved later using a getter function that is automatically created. |
| | | 7 | | .PARAMETER Name |
| | | 8 | | The name of the scriptblock. If the name includes a scope prefix (e.g., `global:` or `script:`), it will be used |
| | | 9 | | .PARAMETER Operator |
| | | 10 | | An optional operator that can be used to separate the name from the scriptblock. This is only applicable when us |
| | | 11 | | .PARAMETER ScriptBlock |
| | | 12 | | The scriptblock to be associated with the specified name and scope. |
| | | 13 | | .PARAMETER Scope |
| | | 14 | | The scope in which to define the scriptblock. Valid values are `Global` or `Script`. If not specified, it defaul |
| | | 15 | | .EXAMPLE |
| | | 16 | | Add-KrScriptBlock -Name 'MyScript' -ScriptBlock { Write-Host "Hello, World!" } |
| | | 17 | | This creates a scriptblock named `MyScript` in the `Script` scope that writes "Hello, World!" to the console. |
| | | 18 | | .EXAMPLE |
| | | 19 | | Add-KrScriptBlock -Name 'global:MyGlobalScript' -ScriptBlock { Write-Host "Hello from Global!" } -Scope Global |
| | | 20 | | This creates a scriptblock named `MyGlobalScript` in the `Global` scope that writes "Hello from Global!" to the |
| | | 21 | | .NOTES |
| | | 22 | | This function is part of the Kestrun PowerShell module and is designed to facilitate the management of scriptblo |
| | | 23 | | .LINK |
| | | 24 | | https://github.com/Kestrun/Kestrun |
| | | 25 | | #> |
| | | 26 | | function Add-KrScriptBlock { |
| | | 27 | | [KestrunRuntimeApi('Everywhere')] |
| | | 28 | | [CmdletBinding(DefaultParameterSetName = 'Split')] |
| | | 29 | | param( |
| | | 30 | | # Style 1/2: separate name (+ optional '=') and scriptblock |
| | | 31 | | [Parameter(Mandatory, Position = 0, ParameterSetName = 'Split')] |
| | | 32 | | [Parameter(Mandatory, Position = 0, ParameterSetName = 'WithEquals')] |
| | | 33 | | [string]$Name, |
| | | 34 | | |
| | | 35 | | # Style 2 only: allow bare '=' token between name and scriptblock |
| | | 36 | | [Parameter(Mandatory, Position = 1, ParameterSetName = 'WithEquals')] |
| | | 37 | | [ValidateSet('=')] |
| | | 38 | | [string]$Operator, |
| | | 39 | | |
| | | 40 | | [Parameter(Mandatory, Position = 1, ParameterSetName = 'Split')] |
| | | 41 | | [Parameter(Mandatory, Position = 2, ParameterSetName = 'WithEquals')] |
| | | 42 | | [scriptblock]$ScriptBlock, |
| | | 43 | | |
| | | 44 | | # Optional explicit scope |
| | | 45 | | [Parameter(Position = 99)] |
| | | 46 | | [ValidateSet('Global', 'Script')] |
| | | 47 | | [string]$Scope |
| | | 48 | | ) |
| | | 49 | | |
| | 0 | 50 | | if ($PSCmdlet.ParameterSetName -eq 'Split') { |
| | | 51 | | |
| | | 52 | | # Parse "name = { ... }" packed into one argument |
| | 0 | 53 | | $m2 = [regex]::Match( |
| | | 54 | | $Name, |
| | | 55 | | '^\s*(?:(global|script):)?\s*([A-Za-z_][\w\-.]*)\s*=\s*$' |
| | | 56 | | ) |
| | 0 | 57 | | if ($m2.Success) { |
| | 0 | 58 | | if (-not $Scope) { |
| | 0 | 59 | | $Scope = if ($m2.Groups[1].Value) { $m2.Groups[1].Value } else { 'Script' } |
| | | 60 | | } |
| | 0 | 61 | | $Name = $m2.Groups[2].Value |
| | | 62 | | # If user also typed a separate '=' (Operator), ignore it |
| | 0 | 63 | | if ($PSBoundParameters.ContainsKey('Operator')) { |
| | 0 | 64 | | $null = $PSBoundParameters.Remove('Operator') |
| | | 65 | | } |
| | | 66 | | } |
| | | 67 | | } |
| | | 68 | | # If scope was embedded in the name (e.g., global:foo), honor it unless -Scope was passed |
| | 0 | 69 | | $CleanName = $Name |
| | 0 | 70 | | if (-not $PSBoundParameters.ContainsKey('Scope') -and $Name -match '^(global|script):(.+)$') { |
| | 0 | 71 | | $Scope = $matches[1] |
| | 0 | 72 | | $CleanName = $matches[2] |
| | | 73 | | } |
| | 0 | 74 | | if (-not $Scope) { $Scope = 'Script' } |
| | | 75 | | |
| | 0 | 76 | | Set-Item -Path function:$($Scope):Get-KrScriptBlock_$CleanName -Value "return {$($ScriptBlock.ToString())}" |
| | | 77 | | |
| | | 78 | | # Alias: ScriptBlock:<name> → getter |
| | 0 | 79 | | Set-Alias -Name "ScriptBlock:$CleanName" -Value "Get-KrScriptBlock_$CleanName" -Scope $Scope |
| | | 80 | | } |
| | | 81 | | |
| | | 82 | | # Convenience alias |
| | | 83 | | <# |
| | | 84 | | .SYNOPSIS |
| | | 85 | | Creates a convenience alias for the Add-KrScriptBlock function. |
| | | 86 | | .DESCRIPTION |
| | | 87 | | This alias allows users to call the Add-KrScriptBlock function simply by typing `ScriptBlock`. |
| | | 88 | | .EXAMPLE |
| | | 89 | | ScriptBlock MyScript = { Write-Host "Hello, World!" } |
| | | 90 | | This is equivalent to calling Add-KrScriptBlock -Name 'MyScript' -ScriptBlock { Write-Host "Hello, World!" } with th |
| | | 91 | | #> |
| | 0 | 92 | | Set-Alias -Name ScriptBlock -Value Add-KrScriptBlock -Scope Global |
| | | 93 | | |