mirror of
https://github.com/aktsmm/Agent-Skills.git
synced 2026-09-14 20:16:56 +08:00
259 lines
7.1 KiB
PowerShell
259 lines
7.1 KiB
PowerShell
param(
|
|
[ValidateSet('GET', 'POST', 'PATCH', 'PUT', 'DELETE')]
|
|
[string]$Method,
|
|
|
|
[string]$Path,
|
|
|
|
[ValidateSet('v1.0', 'beta')]
|
|
[string]$ApiVersion = 'v1.0',
|
|
|
|
[string]$Select,
|
|
|
|
[string]$Filter,
|
|
|
|
[int]$Top,
|
|
|
|
[string]$Expand,
|
|
|
|
[string]$OrderBy,
|
|
|
|
[string[]]$Headers,
|
|
|
|
[string]$BodyJson,
|
|
|
|
[string]$PermissionProfile,
|
|
|
|
[string]$IntentSummary,
|
|
|
|
[switch]$AllowWrites,
|
|
|
|
[switch]$DryRun,
|
|
|
|
[string]$RunnerPath,
|
|
|
|
[string]$RequestFile
|
|
)
|
|
|
|
$ErrorActionPreference = 'Stop'
|
|
|
|
function Get-RequestValue {
|
|
param(
|
|
[object]$ExplicitValue,
|
|
[object]$FileValue,
|
|
[switch]$AllowEmptyString
|
|
)
|
|
|
|
if ($null -ne $ExplicitValue) {
|
|
if ($AllowEmptyString -or $ExplicitValue -ne '') {
|
|
return $ExplicitValue
|
|
}
|
|
}
|
|
|
|
return $FileValue
|
|
}
|
|
|
|
function Resolve-RunnerCommand {
|
|
param(
|
|
[string]$ExplicitRunnerPath
|
|
)
|
|
|
|
if ($ExplicitRunnerPath) {
|
|
return $ExplicitRunnerPath
|
|
}
|
|
|
|
if ($env:GRAPH_GATEWAY_RUNNER) {
|
|
return $env:GRAPH_GATEWAY_RUNNER
|
|
}
|
|
|
|
if ($env:MSGRAPH_RUNNER) {
|
|
return $env:MSGRAPH_RUNNER
|
|
}
|
|
|
|
$runner = Get-Command 'msgraph' -ErrorAction SilentlyContinue
|
|
if ($runner) {
|
|
return $runner.Source
|
|
}
|
|
|
|
throw 'Microsoft Graph runner was not found. Set -RunnerPath, GRAPH_GATEWAY_RUNNER, or MSGRAPH_RUNNER, or install a runner that exposes the msgraph command.'
|
|
}
|
|
|
|
function Assert-Request {
|
|
param(
|
|
[string]$ResolvedMethod,
|
|
[string]$ResolvedPath,
|
|
[bool]$IsWrite,
|
|
[bool]$AllowWriteExecution
|
|
)
|
|
|
|
if ([string]::IsNullOrWhiteSpace($ResolvedMethod)) {
|
|
throw 'Method is required.'
|
|
}
|
|
|
|
if ([string]::IsNullOrWhiteSpace($ResolvedPath)) {
|
|
throw 'Path is required.'
|
|
}
|
|
|
|
if (-not $ResolvedPath.StartsWith('/')) {
|
|
throw 'Path must start with /. Example: /me/messages'
|
|
}
|
|
|
|
if ($ResolvedMethod -eq 'DELETE') {
|
|
throw 'DELETE is blocked by the current Microsoft Graph gateway policy.'
|
|
}
|
|
|
|
if ($IsWrite -and -not $AllowWriteExecution) {
|
|
throw 'Write execution requires -AllowWrites.'
|
|
}
|
|
}
|
|
|
|
function Get-ImportantBodyFields {
|
|
param(
|
|
[object]$ResolvedBody
|
|
)
|
|
|
|
if ($null -eq $ResolvedBody) {
|
|
return @()
|
|
}
|
|
|
|
if ($ResolvedBody -is [string]) {
|
|
if ([string]::IsNullOrWhiteSpace($ResolvedBody)) {
|
|
return @()
|
|
}
|
|
|
|
try {
|
|
$parsedBody = $ResolvedBody | ConvertFrom-Json -Depth 20
|
|
} catch {
|
|
return @('Body JSON could not be parsed for summary generation')
|
|
}
|
|
} else {
|
|
$parsedBody = $ResolvedBody
|
|
}
|
|
|
|
if ($parsedBody -isnot [psobject]) {
|
|
return @()
|
|
}
|
|
|
|
return @($parsedBody.PSObject.Properties.Name | Select-Object -First 8)
|
|
}
|
|
|
|
function New-ConfirmationPreview {
|
|
param(
|
|
[string]$ResolvedMethod,
|
|
[string]$ResolvedPath,
|
|
[string]$ResolvedApiVersion,
|
|
[string]$ResolvedPermissionProfile,
|
|
[string]$ResolvedIntentSummary,
|
|
[object]$ResolvedBody
|
|
)
|
|
|
|
$isWrite = $ResolvedMethod -ne 'GET'
|
|
$importantFields = Get-ImportantBodyFields -ResolvedBody $ResolvedBody
|
|
|
|
[pscustomobject]@{
|
|
isWrite = $isWrite
|
|
target = $ResolvedPath
|
|
method = $ResolvedMethod
|
|
apiVersion = $ResolvedApiVersion
|
|
permissionProfile = $ResolvedPermissionProfile
|
|
intentSummary = $ResolvedIntentSummary
|
|
importantBodyFields = $importantFields
|
|
}
|
|
}
|
|
|
|
$requestFromFile = $null
|
|
if ($RequestFile) {
|
|
if (-not (Test-Path -LiteralPath $RequestFile)) {
|
|
throw "Request file was not found: $RequestFile"
|
|
}
|
|
|
|
$requestFromFile = Get-Content -LiteralPath $RequestFile -Raw -Encoding UTF8 | ConvertFrom-Json -Depth 20
|
|
}
|
|
|
|
$resolvedMethod = Get-RequestValue -ExplicitValue $Method -FileValue $requestFromFile.method
|
|
$resolvedPath = Get-RequestValue -ExplicitValue $Path -FileValue $requestFromFile.path
|
|
$resolvedApiVersion = Get-RequestValue -ExplicitValue $ApiVersion -FileValue $requestFromFile.apiVersion
|
|
$resolvedSelect = Get-RequestValue -ExplicitValue $Select -FileValue $requestFromFile.query.select -AllowEmptyString
|
|
$resolvedFilter = Get-RequestValue -ExplicitValue $Filter -FileValue $requestFromFile.query.filter -AllowEmptyString
|
|
$resolvedTop = Get-RequestValue -ExplicitValue $Top -FileValue $requestFromFile.query.top
|
|
$resolvedExpand = Get-RequestValue -ExplicitValue $Expand -FileValue $requestFromFile.query.expand -AllowEmptyString
|
|
$resolvedOrderBy = Get-RequestValue -ExplicitValue $OrderBy -FileValue $requestFromFile.query.orderBy -AllowEmptyString
|
|
$resolvedHeaders = Get-RequestValue -ExplicitValue $Headers -FileValue $requestFromFile.headers
|
|
$resolvedBody = Get-RequestValue -ExplicitValue $BodyJson -FileValue $requestFromFile.body
|
|
$resolvedPermissionProfile = Get-RequestValue -ExplicitValue $PermissionProfile -FileValue $requestFromFile.permissionProfile
|
|
$resolvedIntentSummary = Get-RequestValue -ExplicitValue $IntentSummary -FileValue $requestFromFile.intentSummary
|
|
|
|
$isWrite = $resolvedMethod -ne 'GET'
|
|
Assert-Request -ResolvedMethod $resolvedMethod -ResolvedPath $resolvedPath -IsWrite $isWrite -AllowWriteExecution $AllowWrites.IsPresent
|
|
|
|
$argumentList = [System.Collections.Generic.List[string]]::new()
|
|
$argumentList.Add('graph-call')
|
|
$argumentList.Add($resolvedMethod)
|
|
$argumentList.Add($resolvedPath)
|
|
|
|
if ($resolvedApiVersion) {
|
|
$argumentList.Add('--api-version')
|
|
$argumentList.Add($resolvedApiVersion)
|
|
}
|
|
|
|
if ($resolvedSelect) {
|
|
$argumentList.Add('--select')
|
|
$argumentList.Add($resolvedSelect)
|
|
}
|
|
|
|
if ($resolvedFilter) {
|
|
$argumentList.Add('--filter')
|
|
$argumentList.Add($resolvedFilter)
|
|
}
|
|
|
|
if ($resolvedTop) {
|
|
$argumentList.Add('--top')
|
|
$argumentList.Add([string]$resolvedTop)
|
|
}
|
|
|
|
if ($resolvedExpand) {
|
|
$argumentList.Add('--expand')
|
|
$argumentList.Add($resolvedExpand)
|
|
}
|
|
|
|
if ($resolvedOrderBy) {
|
|
$argumentList.Add('--orderby')
|
|
$argumentList.Add($resolvedOrderBy)
|
|
}
|
|
|
|
if ($resolvedHeaders) {
|
|
foreach ($header in @($resolvedHeaders)) {
|
|
$argumentList.Add('--headers')
|
|
$argumentList.Add([string]$header)
|
|
}
|
|
}
|
|
|
|
if ($null -ne $resolvedBody -and ($resolvedBody -ne '')) {
|
|
$bodyArgument = if ($resolvedBody -is [string]) { $resolvedBody } else { $resolvedBody | ConvertTo-Json -Depth 20 -Compress }
|
|
$argumentList.Add('--body')
|
|
$argumentList.Add($bodyArgument)
|
|
}
|
|
|
|
if ($isWrite) {
|
|
$argumentList.Add('--allow-writes')
|
|
}
|
|
|
|
$preview = New-ConfirmationPreview `
|
|
-ResolvedMethod $resolvedMethod `
|
|
-ResolvedPath $resolvedPath `
|
|
-ResolvedApiVersion $resolvedApiVersion `
|
|
-ResolvedPermissionProfile $resolvedPermissionProfile `
|
|
-ResolvedIntentSummary $resolvedIntentSummary `
|
|
-ResolvedBody $resolvedBody
|
|
|
|
if ($DryRun) {
|
|
[pscustomobject]@{
|
|
runnerCommand = if ($RunnerPath) { $RunnerPath } elseif ($env:GRAPH_GATEWAY_RUNNER) { $env:GRAPH_GATEWAY_RUNNER } elseif ($env:MSGRAPH_RUNNER) { $env:MSGRAPH_RUNNER } else { $null }
|
|
arguments = @($argumentList)
|
|
preview = $preview
|
|
}
|
|
return
|
|
}
|
|
|
|
$runnerCommand = Resolve-RunnerCommand -ExplicitRunnerPath $RunnerPath
|
|
|
|
& $runnerCommand @argumentList |