diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml new file mode 100644 index 0000000..36bd853 --- /dev/null +++ b/.github/FUNDING.yml @@ -0,0 +1 @@ +github: [StartAutomating] diff --git a/.github/workflows/BuildGQL.yml b/.github/workflows/BuildGQL.yml new file mode 100644 index 0000000..c8ad629 --- /dev/null +++ b/.github/workflows/BuildGQL.yml @@ -0,0 +1,552 @@ + +name: Build GQL +on: + push: + pull_request: + workflow_dispatch: +jobs: + TestPowerShellOnLinux: + runs-on: ubuntu-latest + steps: + - name: InstallPester + id: InstallPester + shell: pwsh + run: | + $Parameters = @{} + $Parameters.PesterMaxVersion = ${env:PesterMaxVersion} + foreach ($k in @($parameters.Keys)) { + if ([String]::IsNullOrEmpty($parameters[$k])) { + $parameters.Remove($k) + } + } + Write-Host "::debug:: InstallPester $(@(foreach ($p in $Parameters.GetEnumerator()) {'-' + $p.Key + ' ' + $p.Value}) -join ' ')" + & {<# + .Synopsis + Installs Pester + .Description + Installs Pester + #> + param( + # The maximum pester version. Defaults to 4.99.99. + [string] + $PesterMaxVersion = '4.99.99' + ) + [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 + Install-Module -Name Pester -Repository PSGallery -Force -Scope CurrentUser -MaximumVersion $PesterMaxVersion -SkipPublisherCheck -AllowClobber + Import-Module Pester -Force -PassThru -MaximumVersion $PesterMaxVersion} @Parameters + - name: Check out repository + uses: actions/checkout@v4 + - name: RunPester + id: RunPester + shell: pwsh + run: | + $Parameters = @{} + $Parameters.ModulePath = ${env:ModulePath} + $Parameters.PesterMaxVersion = ${env:PesterMaxVersion} + $Parameters.NoCoverage = ${env:NoCoverage} + $Parameters.NoCoverage = $parameters.NoCoverage -match 'true'; + foreach ($k in @($parameters.Keys)) { + if ([String]::IsNullOrEmpty($parameters[$k])) { + $parameters.Remove($k) + } + } + Write-Host "::debug:: RunPester $(@(foreach ($p in $Parameters.GetEnumerator()) {'-' + $p.Key + ' ' + $p.Value}) -join ' ')" + & {<# + .Synopsis + Runs Pester + .Description + Runs Pester tests after importing a PowerShell module + #> + param( + # The module path. If not provided, will default to the second half of the repository ID. + [string] + $ModulePath, + # The Pester max version. By default, this is pinned to 4.99.99. + [string] + $PesterMaxVersion = '4.99.99', + + # If set, will not collect code coverage. + [switch] + $NoCoverage + ) + + $global:ErrorActionPreference = 'continue' + $global:ProgressPreference = 'silentlycontinue' + + $orgName, $moduleName = $env:GITHUB_REPOSITORY -split "/" + if (-not $ModulePath) { $ModulePath = ".\$moduleName.psd1" } + $importedPester = Import-Module Pester -Force -PassThru -MaximumVersion $PesterMaxVersion + $importedModule = Import-Module $ModulePath -Force -PassThru + $importedPester, $importedModule | Out-Host + + $codeCoverageParameters = @{ + CodeCoverage = "$($importedModule | Split-Path)\*-*.ps1" + CodeCoverageOutputFile = ".\$moduleName.Coverage.xml" + } + + if ($NoCoverage) { + $codeCoverageParameters = @{} + } + + + $result = + Invoke-Pester -PassThru -Verbose -OutputFile ".\$moduleName.TestResults.xml" -OutputFormat NUnitXml @codeCoverageParameters + + if ($result.FailedCount -gt 0) { + "::debug:: $($result.FailedCount) tests failed" + foreach ($r in $result.TestResult) { + if (-not $r.Passed) { + "::error::$($r.describe, $r.context, $r.name -join ' ') $($r.FailureMessage)" + } + } + throw "::error:: $($result.FailedCount) tests failed" + } + } @Parameters + - name: PublishTestResults + uses: actions/upload-artifact@v3 + with: + name: PesterResults + path: '**.TestResults.xml' + if: ${{always()}} + TagReleaseAndPublish: + runs-on: ubuntu-latest + if: ${{ success() }} + steps: + - name: Check out repository + uses: actions/checkout@v2 + - name: TagModuleVersion + id: TagModuleVersion + shell: pwsh + run: | + $Parameters = @{} + $Parameters.ModulePath = ${env:ModulePath} + $Parameters.UserEmail = ${env:UserEmail} + $Parameters.UserName = ${env:UserName} + $Parameters.TagVersionFormat = ${env:TagVersionFormat} + $Parameters.TagAnnotationFormat = ${env:TagAnnotationFormat} + foreach ($k in @($parameters.Keys)) { + if ([String]::IsNullOrEmpty($parameters[$k])) { + $parameters.Remove($k) + } + } + Write-Host "::debug:: TagModuleVersion $(@(foreach ($p in $Parameters.GetEnumerator()) {'-' + $p.Key + ' ' + $p.Value}) -join ' ')" + & {param( + [string] + $ModulePath, + + # The user email associated with a git commit. + [string] + $UserEmail, + + # The user name associated with a git commit. + [string] + $UserName, + + # The tag version format (default value: 'v$(imported.Version)') + # This can expand variables. $imported will contain the imported module. + [string] + $TagVersionFormat = 'v$($imported.Version)', + + # The tag version format (default value: '$($imported.Name) $(imported.Version)') + # This can expand variables. $imported will contain the imported module. + [string] + $TagAnnotationFormat = '$($imported.Name) $($imported.Version)' + ) + + + $gitHubEvent = if ($env:GITHUB_EVENT_PATH) { + [IO.File]::ReadAllText($env:GITHUB_EVENT_PATH) | ConvertFrom-Json + } else { $null } + + + @" + ::group::GitHubEvent + $($gitHubEvent | ConvertTo-Json -Depth 100) + ::endgroup:: + "@ | Out-Host + + if (-not ($gitHubEvent.head_commit.message -match "Merge Pull Request #(?\d+)") -and + (-not $gitHubEvent.psobject.properties['inputs'])) { + "::warning::Pull Request has not merged, skipping Tagging" | Out-Host + return + } + + + + $imported = + if (-not $ModulePath) { + $orgName, $moduleName = $env:GITHUB_REPOSITORY -split "/" + Import-Module ".\$moduleName.psd1" -Force -PassThru -Global + } else { + Import-Module $modulePath -Force -PassThru -Global + } + + if (-not $imported) { return } + + $targetVersion =$ExecutionContext.InvokeCommand.ExpandString($TagVersionFormat) + $existingTags = git tag --list + + @" + Target Version: $targetVersion + + Existing Tags: + $($existingTags -join [Environment]::NewLine) + "@ | Out-Host + + $versionTagExists = $existingTags | Where-Object { $_ -match $targetVersion } + + if ($versionTagExists) { + "::warning::Version $($versionTagExists)" + return + } + + if (-not $UserName) { $UserName = $env:GITHUB_ACTOR } + if (-not $UserEmail) { $UserEmail = "$UserName@github.com" } + git config --global user.email $UserEmail + git config --global user.name $UserName + + git tag -a $targetVersion -m $ExecutionContext.InvokeCommand.ExpandString($TagAnnotationFormat) + git push origin --tags + + if ($env:GITHUB_ACTOR) { + exit 0 + }} @Parameters + - name: ReleaseModule + id: ReleaseModule + shell: pwsh + run: | + $Parameters = @{} + $Parameters.ModulePath = ${env:ModulePath} + $Parameters.UserEmail = ${env:UserEmail} + $Parameters.UserName = ${env:UserName} + $Parameters.TagVersionFormat = ${env:TagVersionFormat} + $Parameters.ReleaseNameFormat = ${env:ReleaseNameFormat} + $Parameters.ReleaseAsset = ${env:ReleaseAsset} + $Parameters.ReleaseAsset = $parameters.ReleaseAsset -split ';' -replace '^[''"]' -replace '[''"]$' + foreach ($k in @($parameters.Keys)) { + if ([String]::IsNullOrEmpty($parameters[$k])) { + $parameters.Remove($k) + } + } + Write-Host "::debug:: ReleaseModule $(@(foreach ($p in $Parameters.GetEnumerator()) {'-' + $p.Key + ' ' + $p.Value}) -join ' ')" + & {param( + [string] + $ModulePath, + + # The user email associated with a git commit. + [string] + $UserEmail, + + # The user name associated with a git commit. + [string] + $UserName, + + # The tag version format (default value: 'v$(imported.Version)') + # This can expand variables. $imported will contain the imported module. + [string] + $TagVersionFormat = 'v$($imported.Version)', + + # The release name format (default value: '$($imported.Name) $($imported.Version)') + [string] + $ReleaseNameFormat = '$($imported.Name) $($imported.Version)', + + # Any assets to attach to the release. Can be a wildcard or file name. + [string[]] + $ReleaseAsset + ) + + + $gitHubEvent = if ($env:GITHUB_EVENT_PATH) { + [IO.File]::ReadAllText($env:GITHUB_EVENT_PATH) | ConvertFrom-Json + } else { $null } + + + @" + ::group::GitHubEvent + $($gitHubEvent | ConvertTo-Json -Depth 100) + ::endgroup:: + "@ | Out-Host + + if (-not ($gitHubEvent.head_commit.message -match "Merge Pull Request #(?\d+)") -and + (-not $gitHubEvent.psobject.properties['inputs'])) { + "::warning::Pull Request has not merged, skipping GitHub release" | Out-Host + return + } + + + + $imported = + if (-not $ModulePath) { + $orgName, $moduleName = $env:GITHUB_REPOSITORY -split "/" + Import-Module ".\$moduleName.psd1" -Force -PassThru -Global + } else { + Import-Module $modulePath -Force -PassThru -Global + } + + if (-not $imported) { return } + + $targetVersion =$ExecutionContext.InvokeCommand.ExpandString($TagVersionFormat) + $targetReleaseName = $targetVersion + $releasesURL = 'https://api.github.com/repos/${{github.repository}}/releases' + "Release URL: $releasesURL" | Out-Host + $listOfReleases = Invoke-RestMethod -Uri $releasesURL -Method Get -Headers @{ + "Accept" = "application/vnd.github.v3+json" + "Authorization" = 'Bearer ${{ secrets.GITHUB_TOKEN }}' + } + + $releaseExists = $listOfReleases | Where-Object tag_name -eq $targetVersion + + if ($releaseExists) { + "::warning::Release '$($releaseExists.Name )' Already Exists" | Out-Host + $releasedIt = $releaseExists + } else { + $releasedIt = Invoke-RestMethod -Uri $releasesURL -Method Post -Body ( + [Ordered]@{ + owner = '${{github.owner}}' + repo = '${{github.repository}}' + tag_name = $targetVersion + name = $ExecutionContext.InvokeCommand.ExpandString($ReleaseNameFormat) + body = + if ($env:RELEASENOTES) { + $env:RELEASENOTES + } elseif ($imported.PrivateData.PSData.ReleaseNotes) { + $imported.PrivateData.PSData.ReleaseNotes + } else { + "$($imported.Name) $targetVersion" + } + draft = if ($env:RELEASEISDRAFT) { [bool]::Parse($env:RELEASEISDRAFT) } else { $false } + prerelease = if ($env:PRERELEASE) { [bool]::Parse($env:PRERELEASE) } else { $false } + } | ConvertTo-Json + ) -Headers @{ + "Accept" = "application/vnd.github.v3+json" + "Content-type" = "application/json" + "Authorization" = 'Bearer ${{ secrets.GITHUB_TOKEN }}' + } + } + + + + + + if (-not $releasedIt) { + throw "Release failed" + } else { + $releasedIt | Out-Host + } + + $releaseUploadUrl = $releasedIt.upload_url -replace '\{.+$' + + if ($ReleaseAsset) { + $fileList = Get-ChildItem -Recurse + $filesToRelease = + @(:nextFile foreach ($file in $fileList) { + foreach ($relAsset in $ReleaseAsset) { + if ($relAsset -match '[\*\?]') { + if ($file.Name -like $relAsset) { + $file; continue nextFile + } + } elseif ($file.Name -eq $relAsset -or $file.FullName -eq $relAsset) { + $file; continue nextFile + } + } + }) + + $releasedFiles = @{} + foreach ($file in $filesToRelease) { + if ($releasedFiles[$file.Name]) { + Write-Warning "Already attached file $($file.Name)" + continue + } else { + $fileBytes = [IO.File]::ReadAllBytes($file.FullName) + $releasedFiles[$file.Name] = + Invoke-RestMethod -Uri "${releaseUploadUrl}?name=$($file.Name)" -Headers @{ + "Accept" = "application/vnd.github+json" + "Authorization" = 'Bearer ${{ secrets.GITHUB_TOKEN }}' + } -Body $fileBytes -ContentType Application/octet-stream + $releasedFiles[$file.Name] + } + } + + "Attached $($releasedFiles.Count) file(s) to release" | Out-Host + } + + + + } @Parameters + - name: PublishPowerShellGallery + id: PublishPowerShellGallery + shell: pwsh + run: | + $Parameters = @{} + $Parameters.ModulePath = ${env:ModulePath} + $Parameters.Exclude = ${env:Exclude} + $Parameters.Exclude = $parameters.Exclude -split ';' -replace '^[''"]' -replace '[''"]$' + foreach ($k in @($parameters.Keys)) { + if ([String]::IsNullOrEmpty($parameters[$k])) { + $parameters.Remove($k) + } + } + Write-Host "::debug:: PublishPowerShellGallery $(@(foreach ($p in $Parameters.GetEnumerator()) {'-' + $p.Key + ' ' + $p.Value}) -join ' ')" + & {param( + [string] + $ModulePath, + + [string[]] + $Exclude = @('*.png', '*.mp4', '*.jpg','*.jpeg', '*.gif', 'docs[/\]*') + ) + + $gitHubEvent = if ($env:GITHUB_EVENT_PATH) { + [IO.File]::ReadAllText($env:GITHUB_EVENT_PATH) | ConvertFrom-Json + } else { $null } + + if (-not $Exclude) { + $Exclude = @('*.png', '*.mp4', '*.jpg','*.jpeg', '*.gif','docs[/\]*') + } + + + @" + ::group::GitHubEvent + $($gitHubEvent | ConvertTo-Json -Depth 100) + ::endgroup:: + "@ | Out-Host + + @" + ::group::PSBoundParameters + $($PSBoundParameters | ConvertTo-Json -Depth 100) + ::endgroup:: + "@ | Out-Host + + if (-not ($gitHubEvent.head_commit.message -match "Merge Pull Request #(?\d+)") -and + (-not $gitHubEvent.psobject.properties['inputs'])) { + "::warning::Pull Request has not merged, skipping Gallery Publish" | Out-Host + return + } + + + $imported = + if (-not $ModulePath) { + $orgName, $moduleName = $env:GITHUB_REPOSITORY -split "/" + Import-Module ".\$moduleName.psd1" -Force -PassThru -Global + } else { + Import-Module $modulePath -Force -PassThru -Global + } + + if (-not $imported) { return } + + $foundModule = try { Find-Module -Name $imported.Name -ErrorAction SilentlyContinue} catch {} + + if ($foundModule -and (([Version]$foundModule.Version) -ge ([Version]$imported.Version))) { + "::warning::Gallery Version of $moduleName is more recent ($($foundModule.Version) >= $($imported.Version))" | Out-Host + } else { + + $gk = '${{secrets.GALLERYKEY}}' + + $rn = Get-Random + $moduleTempFolder = Join-Path $pwd "$rn" + $moduleTempPath = Join-Path $moduleTempFolder $moduleName + New-Item -ItemType Directory -Path $moduleTempPath -Force | Out-Host + + Write-Host "Staging Directory: $ModuleTempPath" + + $imported | Split-Path | + Get-ChildItem -Force | + Where-Object Name -NE $rn | + Copy-Item -Destination $moduleTempPath -Recurse + + $moduleGitPath = Join-Path $moduleTempPath '.git' + Write-Host "Removing .git directory" + if (Test-Path $moduleGitPath) { + Remove-Item -Recurse -Force $moduleGitPath + } + + if ($Exclude) { + "::notice::Attempting to Exlcude $exclude" | Out-Host + Get-ChildItem $moduleTempPath -Recurse | + Where-Object { + foreach ($ex in $exclude) { + if ($_.FullName -like $ex) { + "::notice::Excluding $($_.FullName)" | Out-Host + return $true + } + } + } | + Remove-Item + } + + Write-Host "Module Files:" + Get-ChildItem $moduleTempPath -Recurse + Write-Host "Publishing $moduleName [$($imported.Version)] to Gallery" + Publish-Module -Path $moduleTempPath -NuGetApiKey $gk + if ($?) { + Write-Host "Published to Gallery" + } else { + Write-Host "Gallery Publish Failed" + exit 1 + } + } + } @Parameters + BuildGQL: + runs-on: ubuntu-latest + if: ${{ success() }} + steps: + - name: Check out repository + uses: actions/checkout@v2 + - name: GitLogger + uses: GitLogging/GitLoggerAction@main + id: GitLogger + - name: Use PSSVG Action + uses: StartAutomating/PSSVG@main + id: PSSVG + - name: Use PipeScript Action + uses: StartAutomating/PipeScript@main + id: PipeScript + - name: UseEZOut + uses: StartAutomating/EZOut@master + - name: UseHelpOut + uses: StartAutomating/HelpOut@master + - name: Run GQL (on branch) + uses: ./ + id: ActionOnBranch + env: + ReadOnlyToken: ${{ secrets.READ_ONLY_TOKEN }} + - name: Log in to ghcr.io + uses: docker/login-action@master + with: + registry: ${{ env.REGISTRY }} + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + env: + REGISTRY: ghcr.io + - name: Extract Docker Metadata (for branch) + if: ${{github.ref_name != 'main' && github.ref_name != 'master' && github.ref_name != 'latest'}} + id: meta + uses: docker/metadata-action@master + with: + images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} + env: + REGISTRY: ghcr.io + IMAGE_NAME: ${{ github.repository }} + - name: Extract Docker Metadata (for main) + if: ${{github.ref_name == 'main' || github.ref_name == 'master' || github.ref_name == 'latest'}} + id: metaMain + uses: docker/metadata-action@master + with: + images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} + flavor: latest=true + - name: Build and push Docker image (from main) + if: ${{github.ref_name == 'main' || github.ref_name == 'master' || github.ref_name == 'latest'}} + uses: docker/build-push-action@master + with: + context: . + push: true + tags: ${{ steps.metaMain.outputs.tags }} + labels: ${{ steps.metaMain.outputs.labels }} + - name: Build and push Docker image (from branch) + if: ${{github.ref_name != 'main' && github.ref_name != 'master' && github.ref_name != 'latest'}} + uses: docker/build-push-action@master + with: + context: . + push: true + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} + diff --git a/Assets/GQL-Animated.svg b/Assets/GQL-Animated.svg new file mode 100644 index 0000000..fa52af2 --- /dev/null +++ b/Assets/GQL-Animated.svg @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + GQL + diff --git a/Assets/GQL.svg b/Assets/GQL.svg new file mode 100644 index 0000000..34dbfb3 --- /dev/null +++ b/Assets/GQL.svg @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + + GQL + diff --git a/Build/GQL.GitHubAction.PSDevOps.ps1 b/Build/GQL.GitHubAction.PSDevOps.ps1 new file mode 100644 index 0000000..6f72ac7 --- /dev/null +++ b/Build/GQL.GitHubAction.PSDevOps.ps1 @@ -0,0 +1,10 @@ +#requires -Module PSDevOps +Import-BuildStep -SourcePath ( + Join-Path $PSScriptRoot 'GitHub' +) -BuildSystem GitHubAction + +$PSScriptRoot | Split-Path | Push-Location + +New-GitHubAction -Name "GetGQL" -Description 'Get GraphQL with PowerShell' -Action GQLAction -Icon chevron-right -OutputPath .\action.yml + +Pop-Location \ No newline at end of file diff --git a/Build/GQL.GitHubWorkflow.PSDevOps.ps1 b/Build/GQL.GitHubWorkflow.PSDevOps.ps1 new file mode 100644 index 0000000..2bc2fdb --- /dev/null +++ b/Build/GQL.GitHubWorkflow.PSDevOps.ps1 @@ -0,0 +1,12 @@ +#requires -Module PSDevOps +Import-BuildStep -SourcePath ( + Join-Path $PSScriptRoot 'GitHub' +) -BuildSystem GitHubWorkflow + +Push-Location ($PSScriptRoot | Split-Path) +New-GitHubWorkflow -Name "Build GQL" -On Push, + PullRequest, + Demand -Job TestPowerShellOnLinux, + TagReleaseAndPublish, BuildGQL -OutputPath .\.github\workflows\BuildGQL.yml + +Pop-Location \ No newline at end of file diff --git a/Build/GQL.HelpOut.ps1 b/Build/GQL.HelpOut.ps1 new file mode 100644 index 0000000..74c9e3d --- /dev/null +++ b/Build/GQL.HelpOut.ps1 @@ -0,0 +1,11 @@ +#requires -Module HelpOut + +#region Load the Module +Push-Location ($PSScriptRoot | Split-Path) +$importedModule = Import-Module .\ -Global -PassThru +#endregion Load the Module + +# This will save the MarkdownHelp to the docs folder, and output all of the files created. +Save-MarkdownHelp -PassThru -Module $importedModule.Name -ExcludeCommandType Alias + +Pop-Location \ No newline at end of file diff --git a/Build/GQL.PSSVG.ps1 b/Build/GQL.PSSVG.ps1 new file mode 100644 index 0000000..18113ea --- /dev/null +++ b/Build/GQL.PSSVG.ps1 @@ -0,0 +1,106 @@ +#requires -Module PSSVG + +$AssetsPath = $PSScriptRoot | Split-Path | Join-Path -ChildPath "Assets" + +if (-not (Test-Path $AssetsPath)) { + New-Item -ItemType Directory -Path $AssetsPath | Out-Null +} +$myName = $MyInvocation.MyCommand.Name -replace '\.PSSVG\.ps1$' + +$strokeWidth = '0.5%' +$fontName = 'Noto Sans' +foreach ($variant in '','Animated') { + $outputPath = if (-not $variant) { + Join-Path $assetsPath "$myName.svg" + } else { + Join-Path $assetsPath "$myName-$variant.svg" + } + $symbolDefinition = SVG.symbol -Id 'PowerShellWeb' @( + svg -content $( + $fillParameters = [Ordered]@{ + Fill = '#4488FF' + Class = 'foreground-fill' + } + + $strokeParameters = [Ordered]@{ + Stroke = '#4488FF' + Class = 'foreground-stroke' + StrokeWidth = $strokeWidth + } + + $transparentFill = [Ordered]@{Fill='transparent'} + $animationDuration = [Ordered]@{ + Dur = "4.2s" + RepeatCount = "indefinite" + } + + SVG.GoogleFont -FontName $fontName + + svg.symbol -Id psChevron -Content @( + svg.polygon -Points (@( + "40,20" + "45,20" + "60,50" + "35,80" + "32.5,80" + "55,50" + ) -join ' ') + ) -ViewBox 100, 100 + + + + SVG.circle -CX 50% -Cy 50% -R 42% @transparentFill @strokeParameters -Content @( + ) + SVG.ellipse -Cx 50% -Cy 50% -Rx 23% -Ry 42% @transparentFill @strokeParameters -Content @( + if ($variant -match 'animate') { + svg.animate -Values '23%;16%;23%' -AttributeName rx @animationDuration + } + ) + SVG.ellipse -Cx 50% -Cy 50% -Rx 16% -Ry 42% @transparentFill @strokeParameters -Content @( + if ($variant -match 'animate') { + svg.animate -Values '16%;23%;16%' -AttributeName rx @animationDuration + } + ) -Opacity .9 + SVG.ellipse -Cx 50% -Cy 50% -Rx 15% -Ry 42% @transparentFill @strokeParameters -Content @( + if ($variant -match 'animate') { + svg.animate -Values '15%;16%;15%' -AttributeName rx @animationDuration + } + ) -Opacity .8 + SVG.ellipse -Cx 50% -Cy 50% -Rx 42% -Ry 23% @transparentFill @strokeParameters -Content @( + if ($variant -match 'animate') { + svg.animate -Values '23%;16%;23%' -AttributeName ry @animationDuration + } + ) + SVG.ellipse -Cx 50% -Cy 50% -Rx 42% -Ry 16% @transparentFill @strokeParameters -Content @( + if ($variant -match 'animate') { + svg.animate -Values '16%;23%;16%' -AttributeName ry @animationDuration + } + ) -Opacity .9 + SVG.ellipse -Cx 50% -Cy 50% -Rx 42% -Ry 15% @transparentFill @strokeParameters -Content @( + if ($variant -match 'animate') { + svg.animate -Values '15%;16%;15%' -AttributeName ry @animationDuration + } + ) -Opacity .8 + + svg.use -Href '#psChevron' -Y 39% @fillParameters -Height 23% + ) -ViewBox 0, 0, 200, 200 -TransformOrigin 50%, 50% + ) + + $shapeSplat = [Ordered]@{ + CenterX=(1080/2) + CenterY=(1080/2) + Radius=((1080 * .15) /2) + } + + + svg -Content @( + SVG.GoogleFont -FontName $fontName + $symbolDefinition + SVG.Use -Href '#PowerShellWeb' -Height 60% -Width 60% -X 20% -Y 20% + # svg.use -Href '#psChevron' -Y 75.75% -X 14% @fillParameters -Height 7.5% + # svg.use -Href '#psChevron' -Y 75.75% -X 14% @fillParameters -Height 7.5% -TransformOrigin '50% 50%' -Transform 'scale(-1 1)' + SVG.Hexagon @shapeSplat -StrokeWidth .5em -Stroke '#4488FF' -Fill 'transparent' -Class 'foreground-stroke' + # SVG.ConvexPolygon -SideCount 3 @shapeSplat -Rotate 180 -StrokeWidth .25em -Stroke '#4488FF' -Fill 'transparent' -Class 'foreground-stroke' -Opacity .3 + SVG.text -X 50% -Y 80% -TextAnchor middle -FontFamily $fontName -Style "font-family:`"$fontName`",sans-serif" -FontSize 4.2em -Fill '#4488FF' -Content 'GQL' -Class 'foreground-fill' -DominantBaseline middle + ) -OutputPath $outputPath -ViewBox 0, 0, 1080, 1080 +} diff --git a/Build/GitHub/Actions/GQLAction.ps1 b/Build/GitHub/Actions/GQLAction.ps1 new file mode 100644 index 0000000..87372e0 --- /dev/null +++ b/Build/GitHub/Actions/GQLAction.ps1 @@ -0,0 +1,349 @@ +<# +.Synopsis + GitHub Action for GQL +.Description + GitHub Action for GQL. This will: + + * Import GQL + * If `-Run` is provided, run that script + * Otherwise, unless `-SkipScriptFile` is passed, run all *.GQL.ps1 files beneath the workflow directory + * If any `-ActionScript` was provided, run scripts from the action path that match a wildcard pattern. + + If you will be making changes using the GitHubAPI, you should provide a -GitHubToken + If none is provided, and ENV:GITHUB_TOKEN is set, this will be used instead. + Any files changed can be outputted by the script, and those changes can be checked back into the repo. + Make sure to use the "persistCredentials" option with checkout. +#> + +param( +# A PowerShell Script that uses GQL. +# Any files outputted from the script will be added to the repository. +# If those files have a .Message attached to them, they will be committed with that message. +[string] +$Run, + +# If set, will not process any files named *.GQL.ps1 +[switch] +$SkipScriptFile, + +# A list of modules to be installed from the PowerShell gallery before scripts run. +[string[]] +$InstallModule, + +# If provided, will commit any remaining changes made to the workspace with this commit message. +[string] +$CommitMessage, + +# If provided, will checkout a new branch before making the changes. +# If not provided, will use the current branch. +[string] +$TargetBranch, + +# The name of one or more scripts to run, from this action's path. +[string[]] +$ActionScript, + +# The github token to use for requests. +[string] +$GitHubToken = '{{ secrets.GITHUB_TOKEN }}', + +# The user email associated with a git commit. If this is not provided, it will be set to the username@noreply.github.com. +[string] +$UserEmail, + +# The user name associated with a git commit. +[string] +$UserName, + +# If set, will not push any changes made to the repository. +# (they will still be committed unless `-NoCommit` is passed) +[switch] +$NoPush, + +# If set, will not commit any changes made to the repository. +# (this also implies `-NoPush`) +[switch] +$NoCommit +) + +$ErrorActionPreference = 'continue' +"::group::Parameters" | Out-Host +[PSCustomObject]$PSBoundParameters | Format-List | Out-Host +"::endgroup::" | Out-Host + +$gitHubEventJson = [IO.File]::ReadAllText($env:GITHUB_EVENT_PATH) +$gitHubEvent = + if ($env:GITHUB_EVENT_PATH) { + $gitHubEventJson | ConvertFrom-Json + } else { $null } +"::group::Parameters" | Out-Host +$gitHubEvent | Format-List | Out-Host +"::endgroup::" | Out-Host + + +$anyFilesChanged = $false +$ActionModuleName = 'GQL' +$actorInfo = $null + + +$checkDetached = git symbolic-ref -q HEAD +if ($LASTEXITCODE) { + "::warning::On detached head, skipping action" | Out-Host + exit 0 +} + +function InstallActionModule { + param([string]$ModuleToInstall) + $moduleInWorkspace = Get-ChildItem -Path $env:GITHUB_WORKSPACE -Recurse -File | + Where-Object Name -eq "$($moduleToInstall).psd1" | + Where-Object { + $(Get-Content $_.FullName -Raw) -match 'ModuleVersion' + } + if (-not $moduleInWorkspace) { + $availableModules = Get-Module -ListAvailable + if ($availableModules.Name -notcontains $moduleToInstall) { + Install-Module $moduleToInstall -Scope CurrentUser -Force -AcceptLicense -AllowClobber + } + Import-Module $moduleToInstall -Force -PassThru | Out-Host + } else { + Import-Module $moduleInWorkspace.FullName -Force -PassThru | Out-Host + } +} +function ImportActionModule { + #region -InstallModule + if ($InstallModule) { + "::group::Installing Modules" | Out-Host + foreach ($moduleToInstall in $InstallModule) { + InstallActionModule -ModuleToInstall $moduleToInstall + } + "::endgroup::" | Out-Host + } + #endregion -InstallModule + + if ($env:GITHUB_ACTION_PATH) { + $LocalModulePath = Join-Path $env:GITHUB_ACTION_PATH "$ActionModuleName.psd1" + if (Test-path $LocalModulePath) { + Import-Module $LocalModulePath -Force -PassThru | Out-String + } else { + throw "Module '$ActionModuleName' not found" + } + } elseif (-not (Get-Module $ActionModuleName)) { + throw "Module '$ActionModuleName' not found" + } + + "::notice title=ModuleLoaded::$ActionModuleName Loaded from Path - $($LocalModulePath)" | Out-Host + if ($env:GITHUB_STEP_SUMMARY) { + "# $($ActionModuleName)" | + Out-File -Append -FilePath $env:GITHUB_STEP_SUMMARY + } +} +function InitializeAction { + #region Custom + #endregion Custom + + # Configure git based on the $env:GITHUB_ACTOR + if (-not $UserName) { $UserName = $env:GITHUB_ACTOR } + if (-not $actorID) { $actorID = $env:GITHUB_ACTOR_ID } + $actorInfo = + if ($GitHubToken -notmatch '^\{{2}' -and $GitHubToken -notmatch '\}{2}$') { + Invoke-RestMethod -Uri "https://api.github.com/user/$actorID" -Headers @{ Authorization = "token $GitHubToken" } + } else { + Invoke-RestMethod -Uri "https://api.github.com/user/$actorID" + } + + if (-not $UserEmail) { $UserEmail = "$UserName@noreply.github.com" } + git config --global user.email $UserEmail + git config --global user.name $actorInfo.name + + # Pull down any changes + git pull | Out-Host + + if ($TargetBranch) { + "::notice title=Expanding target branch string $targetBranch" | Out-Host + $TargetBranch = $ExecutionContext.SessionState.InvokeCommand.ExpandString($TargetBranch) + "::notice title=Checking out target branch::$targetBranch" | Out-Host + git checkout -b $TargetBranch | Out-Host + git pull | Out-Host + } +} + +function InvokeActionModule { + $myScriptStart = [DateTime]::Now + $myScript = $ExecutionContext.SessionState.PSVariable.Get("Run").Value + if ($myScript) { + Invoke-Expression -Command $myScript | + . ProcessOutput | + Out-Host + return + } + $myScriptTook = [Datetime]::Now - $myScriptStart + $MyScriptFilesStart = [DateTime]::Now + + $myScriptList = @() + $shouldSkip = $ExecutionContext.SessionState.PSVariable.Get("SkipScriptFile").Value + if ($shouldSkip) { + return + } + $scriptFiles = @( + Get-ChildItem -Recurse -Path $env:GITHUB_WORKSPACE | + Where-Object Name -Match "\.$($ActionModuleName)\.ps1$" + if ($ActionScript) { + if ($ActionScript -match '^\s{0,}/' -and $ActionScript -match '/\s{0,}$') { + $ActionScriptPattern = $ActionScript.Trim('/').Trim() -as [regex] + if ($ActionScriptPattern) { + $ActionScriptPattern = [regex]::new($ActionScript.Trim('/').Trim(), 'IgnoreCase,IgnorePatternWhitespace', [timespan]::FromSeconds(0.5)) + Get-ChildItem -Recurse -Path $env:GITHUB_ACTION_PATH | + Where-Object { $_.Name -Match "\.$($ActionModuleName)\.ps1$" -and $_.FullName -match $ActionScriptPattern } + } + } else { + Get-ChildItem -Recurse -Path $env:GITHUB_ACTION_PATH | + Where-Object Name -Match "\.$($ActionModuleName)\.ps1$" | + Where-Object FullName -Like $ActionScript + } + } + ) | Select-Object -Unique + $scriptFiles | + ForEach-Object -Begin { + if ($env:GITHUB_STEP_SUMMARY) { + "## $ActionModuleName Scripts" | + Out-File -Append -FilePath $env:GITHUB_STEP_SUMMARY + } + } -Process { + $myScriptList += $_.FullName.Replace($env:GITHUB_WORKSPACE, '').TrimStart('/') + $myScriptCount++ + $scriptFile = $_ + if ($env:GITHUB_STEP_SUMMARY) { + "### $($scriptFile.Fullname -replace [Regex]::Escape($env:GITHUB_WORKSPACE))" | + Out-File -Append -FilePath $env:GITHUB_STEP_SUMMARY + } + $scriptCmd = $ExecutionContext.SessionState.InvokeCommand.GetCommand($scriptFile.FullName, 'ExternalScript') + foreach ($requiredModule in $CommandInfo.ScriptBlock.Ast.ScriptRequirements.RequiredModules) { + if ($requiredModule.Name -and + (-not $requiredModule.MaximumVersion) -and + (-not $requiredModule.RequiredVersion) + ) { + InstallActionModule $requiredModule.Name + } + } + $scriptFileOutputs = . $scriptCmd + $scriptFileOutputs | + . ProcessOutput | + Out-Host + } + + $MyScriptFilesTook = [Datetime]::Now - $MyScriptFilesStart + $SummaryOfMyScripts = "$myScriptCount $ActionModuleName scripts took $($MyScriptFilesTook.TotalSeconds) seconds" + $SummaryOfMyScripts | + Out-Host + if ($env:GITHUB_STEP_SUMMARY) { + $SummaryOfMyScripts | + Out-File -Append -FilePath $env:GITHUB_STEP_SUMMARY + } + #region Custom + #endregion Custom +} + +function OutError { + $anyRuntimeExceptions = $false + foreach ($err in $error) { + $errParts = @( + "::error " + @( + if ($err.InvocationInfo.ScriptName) { + "file=$($err.InvocationInfo.ScriptName)" + } + if ($err.InvocationInfo.ScriptLineNumber -ge 1) { + "line=$($err.InvocationInfo.ScriptLineNumber)" + if ($err.InvocationInfo.OffsetInLine -ge 1) { + "col=$($err.InvocationInfo.OffsetInLine)" + } + } + if ($err.CategoryInfo.Activity) { + "title=$($err.CategoryInfo.Activity)" + } + ) -join ',' + "::" + $err.Exception.Message + if ($err.CategoryInfo.Category -eq 'OperationStopped' -and + $err.CategoryInfo.Reason -eq 'RuntimeException') { + $anyRuntimeExceptions = $true + } + ) -join '' + $errParts | Out-Host + if ($anyRuntimeExceptions) { + exit 1 + } + } +} + +function PushActionOutput { + if ($anyFilesChanged) { + "::notice::$($anyFilesChanged) Files Changed" | Out-Host + } + if ($CommitMessage -or $anyFilesChanged) { + if ($CommitMessage) { + Get-ChildItem $env:GITHUB_WORKSPACE -Recurse | + ForEach-Object { + $gitStatusOutput = git status $_.Fullname -s + if ($gitStatusOutput) { + git add $_.Fullname + } + } + + git commit -m $ExecutionContext.SessionState.InvokeCommand.ExpandString($CommitMessage) + } + + $checkDetached = git symbolic-ref -q HEAD + if (-not $LASTEXITCODE -and -not $NoPush -and -not $noCommit) { + if ($TargetBranch -and $anyFilesChanged) { + "::notice::Pushing Changes to $targetBranch" | Out-Host + git push --set-upstream origin $TargetBranch + } elseif ($anyFilesChanged) { + "::notice::Pushing Changes" | Out-Host + git push + } + "Git Push Output: $($gitPushed | Out-String)" + } else { + "::notice::Not pushing changes (on detached head)" | Out-Host + $LASTEXITCODE = 0 + exit 0 + } + } +} + +filter ProcessOutput { + $out = $_ + $outItem = Get-Item -Path $out -ErrorAction Ignore + if (-not $outItem -and $out -is [string]) { + $out | Out-Host + if ($env:GITHUB_STEP_SUMMARY) { + "> $out" | Out-File -Append -FilePath $env:GITHUB_STEP_SUMMARY + } + return + } + $fullName, $shouldCommit = + if ($out -is [IO.FileInfo]) { + $out.FullName, (git status $out.Fullname -s) + } elseif ($outItem) { + $outItem.FullName, (git status $outItem.Fullname -s) + } + if ($shouldCommit -and -not $NoCommit) { + "$fullName has changed, and should be committed" | Out-Host + git add $fullName + if ($out.Message) { + git commit -m "$($out.Message)" | Out-Host + } elseif ($out.CommitMessage) { + git commit -m "$($out.CommitMessage)" | Out-Host + } elseif ($gitHubEvent.head_commit.message) { + git commit -m "$($gitHubEvent.head_commit.message)" | Out-Host + } + $anyFilesChanged = $true + } + $out +} + +. ImportActionModule +. InitializeAction +. InvokeActionModule +. PushActionOutput +. OutError \ No newline at end of file diff --git a/Build/GitHub/Jobs/BuildGQL.psd1 b/Build/GitHub/Jobs/BuildGQL.psd1 new file mode 100644 index 0000000..a8581ec --- /dev/null +++ b/Build/GitHub/Jobs/BuildGQL.psd1 @@ -0,0 +1,36 @@ +@{ + "runs-on" = "ubuntu-latest" + if = '${{ success() }}' + steps = @( + @{ + name = 'Check out repository' + uses = 'actions/checkout@v2' + }, + @{ + name = 'GitLogger' + uses = 'GitLogging/GitLoggerAction@main' + id = 'GitLogger' + }, + @{ + name = 'Use PSSVG Action' + uses = 'StartAutomating/PSSVG@main' + id = 'PSSVG' + }, + @{ + name = 'Use PipeScript Action' + uses = 'StartAutomating/PipeScript@main' + id = 'PipeScript' + }, + 'RunEZOut', + 'RunHelpOut' + @{ + name = 'Run GQL (on branch)' + uses = './' + id = 'ActionOnBranch' + env = @{ + ReadOnlyToken = '${{ secrets.READ_ONLY_TOKEN }}' + } + }, + 'BuildAndPublishContainer' + ) +} \ No newline at end of file diff --git a/Build/GitHub/Steps/BuildAndPublishContainer.psd1 b/Build/GitHub/Steps/BuildAndPublishContainer.psd1 new file mode 100644 index 0000000..4145af3 --- /dev/null +++ b/Build/GitHub/Steps/BuildAndPublishContainer.psd1 @@ -0,0 +1,57 @@ +@{ + 'name'='Log in to ghcr.io' + 'uses'='docker/login-action@master' + 'with'=@{ + 'registry'='${{ env.REGISTRY }}' + 'username'='${{ github.actor }}' + 'password'='${{ secrets.GITHUB_TOKEN }}' + } + env = @{ + 'REGISTRY'='ghcr.io' + } +} +@{ + name = 'Extract Docker Metadata (for branch)' + if = '${{github.ref_name != ''main'' && github.ref_name != ''master'' && github.ref_name != ''latest''}}' + id = 'meta' + uses = 'docker/metadata-action@master' + with = @{ + 'images'='${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}' + } + env = @{ + REGISTRY = 'ghcr.io' + IMAGE_NAME = '${{ github.repository }}' + } +} +@{ + name = 'Extract Docker Metadata (for main)' + if = '${{github.ref_name == ''main'' || github.ref_name == ''master'' || github.ref_name == ''latest''}}' + id = 'metaMain' + uses = 'docker/metadata-action@master' + with = @{ + 'images'='${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}' + 'flavor'='latest=true' + } +} +@{ + name = 'Build and push Docker image (from main)' + if = '${{github.ref_name == ''main'' || github.ref_name == ''master'' || github.ref_name == ''latest''}}' + uses = 'docker/build-push-action@master' + with = @{ + 'context'='.' + 'push'='true' + 'tags'='${{ steps.metaMain.outputs.tags }}' + 'labels'='${{ steps.metaMain.outputs.labels }}' + } +} +@{ + name = 'Build and push Docker image (from branch)' + if = '${{github.ref_name != ''main'' && github.ref_name != ''master'' && github.ref_name != ''latest''}}' + uses = 'docker/build-push-action@master' + with = @{ + 'context'='.' + 'push'='true' + 'tags'='${{ steps.meta.outputs.tags }}' + 'labels'='${{ steps.meta.outputs.labels }}' + } +} \ No newline at end of file diff --git a/Build/GitHub/Steps/PublishTestResults.psd1 b/Build/GitHub/Steps/PublishTestResults.psd1 new file mode 100644 index 0000000..5b169ed --- /dev/null +++ b/Build/GitHub/Steps/PublishTestResults.psd1 @@ -0,0 +1,10 @@ +@{ + name = 'PublishTestResults' + uses = 'actions/upload-artifact@v3' + with = @{ + name = 'PesterResults' + path = '**.TestResults.xml' + } + if = '${{always()}}' +} + diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..eb46760 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,10 @@ +## GQL 0.1 + +* Initial Release of GQL +* One Simple Command for GraphQL: `Get-GQL` (or `GQL`) +* Container and GitHub action included! + +--- + +> Like It? [Star It](https://github.com/PowerShellWeb/WebSocket) +> Love It? [Support It](https://github.com/sponsors/StartAutomating) \ No newline at end of file diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md new file mode 100644 index 0000000..ca2e753 --- /dev/null +++ b/CODE_OF_CONDUCT.md @@ -0,0 +1,9 @@ +# Code of Conduct + +We have a simple subjective code of conduct: + +1. Be Respectful +2. Be Helpful +3. Do No Harm + +Failure to follow the code of conduct may result in blocks or banishment. \ No newline at end of file diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..9a5c057 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,7 @@ +# Contibuting + +We welcome suggestions and careful contributions. + +To suggest something, please [open an issue](https://github.com/PowerShellWeb/GQL/issues) or start a [discussion](https://github.com/PowerShellWeb/GQL/discussion) + +To add a feature, please open an issue and create a pull request. diff --git a/Commands/Get-GQL.ps1 b/Commands/Get-GQL.ps1 new file mode 100644 index 0000000..a9ddfc2 --- /dev/null +++ b/Commands/Get-GQL.ps1 @@ -0,0 +1,256 @@ +function Get-GQL +{ + <# + .SYNOPSIS + Gets a GraphQL query. + .DESCRIPTION + Gets a GraphQL query and returns the results as a PowerShell object. + .EXAMPLE + # Getting git sponsorship information from GitHub GraphQL. + # **To use this example, we'll need to provide `$MyPat` with a Personal Access Token.** + Get-GQL -Query ./Examples/GitSponsors.gql -PersonalAccessToken $myPat + .EXAMPLE + # We can decorate graph object results to customize them. + + # Let's add a Sponsors property to the output object that returns the sponsor nodes. + Update-TypeData -TypeName 'GitSponsors' -MemberName 'Sponsors' -MemberType ScriptProperty -Value { + $this.viewer.sponsors.nodes + } -Force + + # And let's add a Sponsoring property to the output object that returns the sponsoring nodes. + Update-TypeData -TypeName 'GitSponsors' -MemberName 'Sponsoring' -MemberType ScriptProperty -Value { + $this.viewer.sponsoring.nodes + } -Force + + # And let's display sponsoring and sponsors by default + Update-TypeData -TypeName 'GitSponsors' -DefaultDisplayPropertySet 'Sponsors','Sponsoring' -Force + + # Now we can run the query and get the results. + Get-GQL -Query ./Examples/GitSponsors.gql -PersonalAccessToken $myPat -PSTypeName 'GitSponsors' | + Select-Object -Property Sponsors,Sponsoring + #> + [Alias('GQL','GraphAPI','GraphQL','GraphQueryLanguage')] + [CmdletBinding(SupportsShouldProcess)] + param( + # One or more queries to run. + [Parameter(ValueFromPipelineByPropertyName)] + [Alias('FullName')] + [string[]] + $Query, + + # The Personal Access Token to use for the query. + [Parameter(ValueFromPipelineByPropertyName)] + [Alias('Token','PAT','AccessToken')] + [string] + $PersonalAccessToken, + + # The GraphQL endpoint to query. + [Parameter(ValueFromPipelineByPropertyName)] + [Alias('uri')] + [uri] + $GraphQLUri = "https://api.github.com/graphql", + + # Any variables or parameters to provide to the query. + [Parameter(ValueFromPipelineByPropertyName)] + [Alias('Parameters','Variable','Variables')] + [Collections.IDictionary] + $Parameter, + + # Any additional headers to include in the request + [Alias('Headers')] + [Collections.IDictionary] + $Header, + + # Adds PSTypeName(s) to use for the output object, making it a decorated object. + # By decorating an object with one or more typenames, we can: + # + # * Add additional properties and methods to the object + # * Format the output object any way we want + [Alias('Decorate','Decoration','PSTypeNames','TypeName','TypeNames','Type')] + [string[]] + $PSTypeName, + + # If set, will cache the results of the query. + # This can be useful for queries that would be run frequently, but change infrequently. + [Parameter(ValueFromPipelineByPropertyName)] + [switch] + $Cache, + + # If set, will refresh the cache. + # This can be useful to force an update of cached information. + # `-Refresh` implies `-Cache` (it just will not return an uncached value). + [Parameter(ValueFromPipelineByPropertyName)] + [switch] + $Refresh, + + [Parameter(ValueFromPipelineByPropertyName)] + [ValidatePattern('\.json$')] + [string[]] + $OutputPath + ) + + process { + #region Handle Input + # Capture the input object + $inputObject = $_ + if ($inputObject -is [IO.FileInfo]) { + if ($inputObject.Extension -notin '.gql','.graphql') { + Write-Verbose "Skipping non-GQL file: $($inputObject.FullName)" + continue + } + } + #endregion Handle Input + + #region Optionally Determine GraphQLUri from InvocationName + if (-not $PSBoundParameters['GraphQLUri'] -and + $MyInvocation.InvocationName -match '\w+\.\w+/') { + $GraphQLUri = $MyInvocation.InvocationName + } + #endregion Optionally Determine GraphQLUri from InvocationName + + #region Cache the Access Token + if (-not $PSBoundParameters['PersonalAccessToken']) { + if ($script:GraphQLTokenCache -is [Collections.IDictionary] -and + $script:GraphQLTokenCache.Contains($GraphQLUri)) { + $PersonalAccessToken = $script:GraphQLTokenCache[$GraphQLUri] + } + } elseif ($PSBoundParameters['PersonalAccessToken']) { + if (-not $script:GraphQLTokenCache) { + $script:GraphQLTokenCache = [Ordered]@{} + } + $script:GraphQLTokenCache[$GraphQLUri] = $PersonalAccessToken + } + #endregion Cache the Access Token + + #region Prepare the REST Parameters + $invokeSplat = @{ + Headers = if ($header) { + $invokeSplat.Headers = [Ordered]@{} + $header + } else { + [Ordered]@{} + } + Uri = $GraphQLUri + Method = 'POST' + } + $invokeSplat.Headers.Authorization = "bearer $PersonalAccessToken" + #endregion Prepare the REST Parameters + + #region Handle Each Query + $queryNumber = -1 + :nextQuery foreach ($gqlQuery in $Query) { + $queryNumber++ + $queryLines = @($gqlQuery -split '(?>\r\n|\n)') + #region Check for File or Cached Query + if ($queryLines.Length -eq 1) { + if ($script:GraphQLQueries -is [Collections.IDictionary] -and + $script:GraphQLQueries.Contains($gqlQuery)) { + $gqlQuery = $script:GraphQLQueries[$gqlQuery] + } + + if (Test-Path $gqlQuery) { + $newQuery = Get-Content -Path $gqlQuery -Raw + $gqlQuery = $newQuery + } elseif ($query -match '[\\/]') { + $psCmdlet.WriteError( + [Management.Automation.ErrorRecord]::new( + [Exception]::new("Query file not found: '$gqlQuery'"), + 'NotFound', + 'ObjectNotFound', + $gqlQuery + ) + ) + continue nextQuery + } + } + #endregion Check for File or Cached Query + + if ($PSBoundParameters['Refresh']) { + $Cache = $true + } + + $queryCacheKey = "$gqlQuery$(if ($Parameter) { $Parameter | ConvertTo-Json -Depth 10})" + if ($Cache -and -not $script:GraphQLOutputCache) { + $script:GraphQLOutputCache = [Ordered]@{} + } + + if ($script:GraphQLOutputCache.$queryCacheKey -and + -not $Refresh + ) { + $script:GraphQLOutputCache.$queryCacheKey + continue nextQuery + } + + $queryOutPath = + if ($OutputPath) { + if ($OutputPath[$queryNumber]) { + $OutputPath[$queryNumber] + } else { + $OutputPath[-1] + } + } + + + + #region Run the Query + $invokeSplat.Body = [Ordered]@{query = $gqlQuery} + if ($Parameter) { + $invokeSplat.Body.variables = $Parameter + } + if ($WhatIfPreference) { + $invokeSplat.Headers.Clear() + $invokeSplat + continue nextQuery + } + $invokeSplat.Body = ConvertTo-Json -InputObject $invokeSplat.Body -Depth 10 + $shouldProcessMessage = "Querying $GraphQLUri with $gqlQuery" + if (-not $PSCmdlet.ShouldProcess($shouldProcessMessage)) { + continue nextQuery + } + $gqlOutput = Invoke-RestMethod @invokeSplat *>&1 + if ($gqlOutput -is [Management.Automation.ErrorRecord]) { + $PSCmdlet.WriteError($gqlOutput) + continue nextQuery + } + + if ($gqlOutput.errors) { + foreach ($gqlError in $gqlOutput.errors) { + $psCmdlet.WriteError(( + [Management.Automation.ErrorRecord]::new( + [Exception]::new($gqlError.message), + 'GQLError', + 'NotSpecified', $gqlError + ) + )) + } + continue nextQuery + } + + if ($gqlOutput.data) { + $gqlOutput = $gqlOutput.data + } + + if (-not $gqlOutput) { + continue nextQuery + } + + if ($PSTypeName) { + $gqlOutput.pstypenames.clear() + for ($goBackwards = $pstypename.Length - 1; $goBackwards -ge 0; $goBackwards--) { + $gqlOutput.pstypenames.add($pstypename[$goBackwards]) + } + } + if ($Cache) { + $script:GraphQLOutputCache[$queryCacheKey] = $gqlOutput + } + if ($queryOutPath) { + New-Item -ItemType File -Path $queryOutPath -Force -Value ( + ConvertTo-Json -Depth 100 -InputObject $gqlOutput + ) + } else { + $gqlOutput + } + #endregion Run the Query + #endregion Handle Each Query + } + } +} diff --git a/Container.init.ps1 b/Container.init.ps1 new file mode 100644 index 0000000..8eb01a6 --- /dev/null +++ b/Container.init.ps1 @@ -0,0 +1,111 @@ +<# +.SYNOPSIS + Initializes a container during build. +.DESCRIPTION + Initializes the container image with the necessary modules and packages. + + This script should be called from the Dockerfile, during the creation of the container image. + + ~~~Dockerfile + # Thank you Microsoft! Thank you PowerShell! Thank you Docker! + FROM mcr.microsoft.com/powershell + # Set the shell to PowerShell (thanks again, Docker!) + SHELL ["/bin/pwsh", "-nologo", "-command"] + # Run the initialization script. This will do all remaining initialization in a single layer. + RUN --mount=type=bind,src=./,target=/Initialize ./Initialize/Container.init.ps1 + ~~~ + + The scripts arguments can be provided with either an `ARG` or `ENV` instruction in the Dockerfile. +.NOTES + Did you know that in PowerShell you can 'use' namespaces that do not really exist? + This seems like a nice way to describe a relationship to a container image. + That is why this file is using the namespace 'mcr.microsoft.com/powershell'. + (this does nothing, but most likely will be used in the future) +#> +using namespace 'mcr.microsoft.com/powershell AS powershell' + +param( +# The name of the module to be installed. +[string]$ModuleName = $( + if ($env:ModuleName) { $env:ModuleName } + else { + (Get-ChildItem -Path $PSScriptRoot | + Where-Object Extension -eq '.psd1' | + Select-String 'ModuleVersion\s=' | + Select-Object -ExpandProperty Path -First 1) -replace '\.psd1$' + } +), +# The packages to be installed. +[string[]]$InstallAptGet = @($env:InstallAptGet -split ','), +# The modules to be installed. +[string[]]$InstallModule = @($env:InstallModule -split ','), +# The Ruby gems to be installed. +[string[]]$InstallRubyGem = @($env:InstallRubyGem -split ','), + +# If set, will keep the .git directories. +[switch]$KeepGit = $($env:KeepGit -match $true) +) + +# Copy all container-related scripts to the root of the container. +Get-ChildItem -Path $PSScriptRoot | + Where-Object Name -Match '^Container\..+?\.ps1$' | + Copy-Item -Destination / + +# Create a profile +New-Item -Path $Profile -ItemType File -Force | Out-Null + +if ($ModuleName) { + # Get the root module directory + $rootModuleDirectory = @($env:PSModulePath -split '[;:]')[0] + + # Determine the path to the module destination. + $moduleDestination = "$rootModuleDirectory/$ModuleName" + # Copy the module to the destination + # (this is being used instead of the COPY statement in Docker, to avoid additional layers). + Copy-Item -Path "$psScriptRoot" -Destination $moduleDestination -Recurse -Force + + # and import this module in the profile + Add-Content -Path $profile -Value "Import-Module $ModuleName" -Force +} + +# If we have modules to install +if ($InstallModule) { + # Install the modules + Install-Module -Name $InstallModule -Force -AcceptLicense -Scope CurrentUser + # and import them in the profile + Add-Content -Path $Profile -Value "Import-Module '$($InstallModule -join "','")'" -Force +} + +# If we have packages to install +if ($InstallAptGet) { + # install the packages + apt-get update && + apt-get install -y @InstallAptGet '--no-install-recommends' && + apt-get clean | + Out-Host +} + +if ($InstallRubyGem) { + # Install the Ruby gems + gem install @InstallRubyGem +} + +if ($ModuleName) { + # In our profile, push into the module's directory + Add-Content -Path $Profile -Value "Get-Module $ModuleName | Split-Path | Push-Location" -Force +} + +if (-not $KeepGit) { + # Remove the .git directories from any modules + Get-ChildItem -Path $rootModuleDirectory -Directory -Force -Recurse | + Where-Object Name -eq '.git' | + Remove-Item -Recurse -Force +} + +# Congratulations! You have successfully initialized the container image. +# This script should work in about any module, with minor adjustments. +# If you have any adjustments, please put them below here, in the `#region Custom` + +#region Custom + +#endregion Custom \ No newline at end of file diff --git a/Container.start.ps1 b/Container.start.ps1 new file mode 100644 index 0000000..751fd19 --- /dev/null +++ b/Container.start.ps1 @@ -0,0 +1,70 @@ +<# +.SYNOPSIS + Starts the container. +.DESCRIPTION + Starts a container. + + This script should be called from the Dockerfile as the ENTRYPOINT (or from within the ENTRYPOINT). + + It should be deployed to the root of the container image. + + ~~~Dockerfile + # Thank you Microsoft! Thank you PowerShell! Thank you Docker! + FROM mcr.microsoft.com/powershell + # Set the shell to PowerShell (thanks again, Docker!) + SHELL ["/bin/pwsh", "-nologo", "-command"] + # Run the initialization script. This will do all remaining initialization in a single layer. + RUN --mount=type=bind,src=./,target=/Initialize ./Initialize/Container.init.ps1 + + ENTRYPOINT ["pwsh", "-nologo", "-file", "/Container.start.ps1"] + ~~~ +.NOTES + Did you know that in PowerShell you can 'use' namespaces that do not really exist? + This seems like a nice way to describe a relationship to a container image. + That is why this file is using the namespace 'mcr.microsoft.com/powershell'. + (this does nothing, but most likely will be used in the future) +#> +using namespace 'ghcr.io/powershellweb/gql' + +param() + +$env:IN_CONTAINER = $true +$PSStyle.OutputRendering = 'Ansi' + +$mountedFolders = @(if (Test-Path '/proc/mounts') { + (Select-String "\S+\s(?

\S+).+rw?,.+symlinkroot=/mnt/host" "/proc/mounts").Matches.Groups | + Where-Object Name -eq p | + Get-Item -path { $_.Value } +}) + +if ($mountedFolders) { + "Mounted $($mountedFolders.Length) folders:" | Out-Host + $mountedFolders | Out-Host +} + +if ($args) { + # If there are arguments, output them (you could handle them in a more complex way). + "$args" | Out-Host + $global:ContainerStartArguments = @() + $args + + #region Custom + + #endregion Custom +} else { + # If there are no arguments, see if there is a Microservice.ps1 + if (Test-Path './Microservice.ps1') { + # If there is a Microservice.ps1, run it. + . ./Microservice.ps1 + } + #region Custom + + #endregion Custom +} + +# If you want to do something when the container is stopped, you can register an event. +# This can call a script that does some cleanup, or sends a message as the service is exiting. +Register-EngineEvent -SourceIdentifier PowerShell.Exiting -Action { + if (Test-Path '/Container.stop.ps1') { + & /Container.stop.ps1 + } +} | Out-Null \ No newline at end of file diff --git a/Container.stop.ps1 b/Container.stop.ps1 new file mode 100644 index 0000000..bb6dfe6 --- /dev/null +++ b/Container.stop.ps1 @@ -0,0 +1,9 @@ +<# +.SYNOPSIS + Stops the container. +.DESCRIPTION + This script is called when the container is about to stop. + + It can be used to perform any necessary cleanup before the container is stopped. +#> +"Container now exiting, thank you for using $env:ModuleName!" | Out-Host diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..db01572 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,11 @@ +# Thank you Microsoft! Thank you PowerShell! Thank you Docker! +FROM mcr.microsoft.com/powershell AS powershell + +# Set the module name to the name of the module we are building +ENV ModuleName=HtmxPS +ENV InstallAptGet="git","curl","ca-certificates","libc6","libgcc1" +ENV InstallModule="ugit" +# Copy the module into the container +RUN --mount=type=bind,src=./,target=/Initialize /bin/pwsh -nologo -command /Initialize/Container.init.ps1 +# Set the entrypoint to the script we just created. +ENTRYPOINT [ "/bin/pwsh","-nologo","-noexit","-file","/Container.start.ps1" ] \ No newline at end of file diff --git a/Examples/GetEnumValues.gql b/Examples/GetEnumValues.gql new file mode 100644 index 0000000..f8c7763 --- /dev/null +++ b/Examples/GetEnumValues.gql @@ -0,0 +1,6 @@ +query getEnumValues($typeName: String!){ + __type(name:$typeName) { + name + enumValues { name } + } +} diff --git a/Examples/GetSchemaTypeNames.gql b/Examples/GetSchemaTypeNames.gql new file mode 100644 index 0000000..e3b8e27 --- /dev/null +++ b/Examples/GetSchemaTypeNames.gql @@ -0,0 +1,7 @@ +query { + __schema { + types { + name + } + } +} diff --git a/Examples/GetSchemaTypeNames.json b/Examples/GetSchemaTypeNames.json new file mode 100644 index 0000000..9ab0424 --- /dev/null +++ b/Examples/GetSchemaTypeNames.json @@ -0,0 +1,4896 @@ +{ + "__schema": { + "types": [ + { + "name": "AbortQueuedMigrationsInput" + }, + { + "name": "AbortQueuedMigrationsPayload" + }, + { + "name": "AbortRepositoryMigrationInput" + }, + { + "name": "AbortRepositoryMigrationPayload" + }, + { + "name": "AcceptEnterpriseAdministratorInvitationInput" + }, + { + "name": "AcceptEnterpriseAdministratorInvitationPayload" + }, + { + "name": "AcceptEnterpriseMemberInvitationInput" + }, + { + "name": "AcceptEnterpriseMemberInvitationPayload" + }, + { + "name": "AcceptTopicSuggestionInput" + }, + { + "name": "AcceptTopicSuggestionPayload" + }, + { + "name": "AccessUserNamespaceRepositoryInput" + }, + { + "name": "AccessUserNamespaceRepositoryPayload" + }, + { + "name": "Actor" + }, + { + "name": "ActorLocation" + }, + { + "name": "ActorType" + }, + { + "name": "AddAssigneesToAssignableInput" + }, + { + "name": "AddAssigneesToAssignablePayload" + }, + { + "name": "AddCommentInput" + }, + { + "name": "AddCommentPayload" + }, + { + "name": "AddDiscussionCommentInput" + }, + { + "name": "AddDiscussionCommentPayload" + }, + { + "name": "AddDiscussionPollVoteInput" + }, + { + "name": "AddDiscussionPollVotePayload" + }, + { + "name": "AddEnterpriseOrganizationMemberInput" + }, + { + "name": "AddEnterpriseOrganizationMemberPayload" + }, + { + "name": "AddEnterpriseSupportEntitlementInput" + }, + { + "name": "AddEnterpriseSupportEntitlementPayload" + }, + { + "name": "AddLabelsToLabelableInput" + }, + { + "name": "AddLabelsToLabelablePayload" + }, + { + "name": "AddProjectCardInput" + }, + { + "name": "AddProjectCardPayload" + }, + { + "name": "AddProjectColumnInput" + }, + { + "name": "AddProjectColumnPayload" + }, + { + "name": "AddProjectV2DraftIssueInput" + }, + { + "name": "AddProjectV2DraftIssuePayload" + }, + { + "name": "AddProjectV2ItemByIdInput" + }, + { + "name": "AddProjectV2ItemByIdPayload" + }, + { + "name": "AddPullRequestReviewCommentInput" + }, + { + "name": "AddPullRequestReviewCommentPayload" + }, + { + "name": "AddPullRequestReviewInput" + }, + { + "name": "AddPullRequestReviewPayload" + }, + { + "name": "AddPullRequestReviewThreadInput" + }, + { + "name": "AddPullRequestReviewThreadPayload" + }, + { + "name": "AddPullRequestReviewThreadReplyInput" + }, + { + "name": "AddPullRequestReviewThreadReplyPayload" + }, + { + "name": "AddReactionInput" + }, + { + "name": "AddReactionPayload" + }, + { + "name": "AddStarInput" + }, + { + "name": "AddStarPayload" + }, + { + "name": "AddSubIssueInput" + }, + { + "name": "AddSubIssuePayload" + }, + { + "name": "AddUpvoteInput" + }, + { + "name": "AddUpvotePayload" + }, + { + "name": "AddVerifiableDomainInput" + }, + { + "name": "AddVerifiableDomainPayload" + }, + { + "name": "AddedToMergeQueueEvent" + }, + { + "name": "AddedToProjectEvent" + }, + { + "name": "AnnouncementBanner" + }, + { + "name": "AnnouncementBannerI" + }, + { + "name": "App" + }, + { + "name": "ApproveDeploymentsInput" + }, + { + "name": "ApproveDeploymentsPayload" + }, + { + "name": "ApproveVerifiableDomainInput" + }, + { + "name": "ApproveVerifiableDomainPayload" + }, + { + "name": "ArchiveProjectV2ItemInput" + }, + { + "name": "ArchiveProjectV2ItemPayload" + }, + { + "name": "ArchiveRepositoryInput" + }, + { + "name": "ArchiveRepositoryPayload" + }, + { + "name": "Assignable" + }, + { + "name": "AssignedEvent" + }, + { + "name": "Assignee" + }, + { + "name": "AuditEntry" + }, + { + "name": "AuditEntryActor" + }, + { + "name": "AuditLogOrder" + }, + { + "name": "AuditLogOrderField" + }, + { + "name": "AutoMergeDisabledEvent" + }, + { + "name": "AutoMergeEnabledEvent" + }, + { + "name": "AutoMergeRequest" + }, + { + "name": "AutoRebaseEnabledEvent" + }, + { + "name": "AutoSquashEnabledEvent" + }, + { + "name": "AutomaticBaseChangeFailedEvent" + }, + { + "name": "AutomaticBaseChangeSucceededEvent" + }, + { + "name": "Base64String" + }, + { + "name": "BaseRefChangedEvent" + }, + { + "name": "BaseRefDeletedEvent" + }, + { + "name": "BaseRefForcePushedEvent" + }, + { + "name": "BigInt" + }, + { + "name": "Blame" + }, + { + "name": "BlameRange" + }, + { + "name": "Blob" + }, + { + "name": "Boolean" + }, + { + "name": "Bot" + }, + { + "name": "BranchActorAllowanceActor" + }, + { + "name": "BranchNamePatternParameters" + }, + { + "name": "BranchNamePatternParametersInput" + }, + { + "name": "BranchProtectionRule" + }, + { + "name": "BranchProtectionRuleConflict" + }, + { + "name": "BranchProtectionRuleConflictConnection" + }, + { + "name": "BranchProtectionRuleConflictEdge" + }, + { + "name": "BranchProtectionRuleConnection" + }, + { + "name": "BranchProtectionRuleEdge" + }, + { + "name": "BulkSponsorship" + }, + { + "name": "BypassActor" + }, + { + "name": "BypassForcePushAllowance" + }, + { + "name": "BypassForcePushAllowanceConnection" + }, + { + "name": "BypassForcePushAllowanceEdge" + }, + { + "name": "BypassPullRequestAllowance" + }, + { + "name": "BypassPullRequestAllowanceConnection" + }, + { + "name": "BypassPullRequestAllowanceEdge" + }, + { + "name": "CVSS" + }, + { + "name": "CWE" + }, + { + "name": "CWEConnection" + }, + { + "name": "CWEEdge" + }, + { + "name": "CancelEnterpriseAdminInvitationInput" + }, + { + "name": "CancelEnterpriseAdminInvitationPayload" + }, + { + "name": "CancelEnterpriseMemberInvitationInput" + }, + { + "name": "CancelEnterpriseMemberInvitationPayload" + }, + { + "name": "CancelSponsorshipInput" + }, + { + "name": "CancelSponsorshipPayload" + }, + { + "name": "ChangeUserStatusInput" + }, + { + "name": "ChangeUserStatusPayload" + }, + { + "name": "CheckAnnotation" + }, + { + "name": "CheckAnnotationConnection" + }, + { + "name": "CheckAnnotationData" + }, + { + "name": "CheckAnnotationEdge" + }, + { + "name": "CheckAnnotationLevel" + }, + { + "name": "CheckAnnotationPosition" + }, + { + "name": "CheckAnnotationRange" + }, + { + "name": "CheckAnnotationSpan" + }, + { + "name": "CheckConclusionState" + }, + { + "name": "CheckRun" + }, + { + "name": "CheckRunAction" + }, + { + "name": "CheckRunConnection" + }, + { + "name": "CheckRunEdge" + }, + { + "name": "CheckRunFilter" + }, + { + "name": "CheckRunOutput" + }, + { + "name": "CheckRunOutputImage" + }, + { + "name": "CheckRunState" + }, + { + "name": "CheckRunStateCount" + }, + { + "name": "CheckRunType" + }, + { + "name": "CheckStatusState" + }, + { + "name": "CheckStep" + }, + { + "name": "CheckStepConnection" + }, + { + "name": "CheckStepEdge" + }, + { + "name": "CheckSuite" + }, + { + "name": "CheckSuiteAutoTriggerPreference" + }, + { + "name": "CheckSuiteConnection" + }, + { + "name": "CheckSuiteEdge" + }, + { + "name": "CheckSuiteFilter" + }, + { + "name": "Claimable" + }, + { + "name": "ClearLabelsFromLabelableInput" + }, + { + "name": "ClearLabelsFromLabelablePayload" + }, + { + "name": "ClearProjectV2ItemFieldValueInput" + }, + { + "name": "ClearProjectV2ItemFieldValuePayload" + }, + { + "name": "CloneProjectInput" + }, + { + "name": "CloneProjectPayload" + }, + { + "name": "CloneTemplateRepositoryInput" + }, + { + "name": "CloneTemplateRepositoryPayload" + }, + { + "name": "Closable" + }, + { + "name": "CloseDiscussionInput" + }, + { + "name": "CloseDiscussionPayload" + }, + { + "name": "CloseIssueInput" + }, + { + "name": "CloseIssuePayload" + }, + { + "name": "ClosePullRequestInput" + }, + { + "name": "ClosePullRequestPayload" + }, + { + "name": "ClosedEvent" + }, + { + "name": "Closer" + }, + { + "name": "CodeOfConduct" + }, + { + "name": "CodeScanningParameters" + }, + { + "name": "CodeScanningParametersInput" + }, + { + "name": "CodeScanningTool" + }, + { + "name": "CodeScanningToolInput" + }, + { + "name": "CollaboratorAffiliation" + }, + { + "name": "Comment" + }, + { + "name": "CommentAuthorAssociation" + }, + { + "name": "CommentCannotUpdateReason" + }, + { + "name": "CommentDeletedEvent" + }, + { + "name": "Commit" + }, + { + "name": "CommitAuthor" + }, + { + "name": "CommitAuthorEmailPatternParameters" + }, + { + "name": "CommitAuthorEmailPatternParametersInput" + }, + { + "name": "CommitComment" + }, + { + "name": "CommitCommentConnection" + }, + { + "name": "CommitCommentEdge" + }, + { + "name": "CommitCommentThread" + }, + { + "name": "CommitConnection" + }, + { + "name": "CommitContributionOrder" + }, + { + "name": "CommitContributionOrderField" + }, + { + "name": "CommitContributionsByRepository" + }, + { + "name": "CommitEdge" + }, + { + "name": "CommitHistoryConnection" + }, + { + "name": "CommitMessage" + }, + { + "name": "CommitMessagePatternParameters" + }, + { + "name": "CommitMessagePatternParametersInput" + }, + { + "name": "CommittableBranch" + }, + { + "name": "CommitterEmailPatternParameters" + }, + { + "name": "CommitterEmailPatternParametersInput" + }, + { + "name": "Comparison" + }, + { + "name": "ComparisonCommitConnection" + }, + { + "name": "ComparisonStatus" + }, + { + "name": "ConnectedEvent" + }, + { + "name": "ContributingGuidelines" + }, + { + "name": "Contribution" + }, + { + "name": "ContributionCalendar" + }, + { + "name": "ContributionCalendarDay" + }, + { + "name": "ContributionCalendarMonth" + }, + { + "name": "ContributionCalendarWeek" + }, + { + "name": "ContributionLevel" + }, + { + "name": "ContributionOrder" + }, + { + "name": "ContributionsCollection" + }, + { + "name": "ConvertProjectCardNoteToIssueInput" + }, + { + "name": "ConvertProjectCardNoteToIssuePayload" + }, + { + "name": "ConvertProjectV2DraftIssueItemToIssueInput" + }, + { + "name": "ConvertProjectV2DraftIssueItemToIssuePayload" + }, + { + "name": "ConvertPullRequestToDraftInput" + }, + { + "name": "ConvertPullRequestToDraftPayload" + }, + { + "name": "ConvertToDraftEvent" + }, + { + "name": "ConvertedNoteToIssueEvent" + }, + { + "name": "ConvertedToDiscussionEvent" + }, + { + "name": "CopilotEndpoints" + }, + { + "name": "CopyProjectV2Input" + }, + { + "name": "CopyProjectV2Payload" + }, + { + "name": "CreateAttributionInvitationInput" + }, + { + "name": "CreateAttributionInvitationPayload" + }, + { + "name": "CreateBranchProtectionRuleInput" + }, + { + "name": "CreateBranchProtectionRulePayload" + }, + { + "name": "CreateCheckRunInput" + }, + { + "name": "CreateCheckRunPayload" + }, + { + "name": "CreateCheckSuiteInput" + }, + { + "name": "CreateCheckSuitePayload" + }, + { + "name": "CreateCommitOnBranchInput" + }, + { + "name": "CreateCommitOnBranchPayload" + }, + { + "name": "CreateDeploymentInput" + }, + { + "name": "CreateDeploymentPayload" + }, + { + "name": "CreateDeploymentStatusInput" + }, + { + "name": "CreateDeploymentStatusPayload" + }, + { + "name": "CreateDiscussionInput" + }, + { + "name": "CreateDiscussionPayload" + }, + { + "name": "CreateEnterpriseOrganizationInput" + }, + { + "name": "CreateEnterpriseOrganizationPayload" + }, + { + "name": "CreateEnvironmentInput" + }, + { + "name": "CreateEnvironmentPayload" + }, + { + "name": "CreateIpAllowListEntryInput" + }, + { + "name": "CreateIpAllowListEntryPayload" + }, + { + "name": "CreateIssueInput" + }, + { + "name": "CreateIssuePayload" + }, + { + "name": "CreateLabelInput" + }, + { + "name": "CreateLabelPayload" + }, + { + "name": "CreateLinkedBranchInput" + }, + { + "name": "CreateLinkedBranchPayload" + }, + { + "name": "CreateMigrationSourceInput" + }, + { + "name": "CreateMigrationSourcePayload" + }, + { + "name": "CreateProjectInput" + }, + { + "name": "CreateProjectPayload" + }, + { + "name": "CreateProjectV2FieldInput" + }, + { + "name": "CreateProjectV2FieldPayload" + }, + { + "name": "CreateProjectV2Input" + }, + { + "name": "CreateProjectV2Payload" + }, + { + "name": "CreateProjectV2StatusUpdateInput" + }, + { + "name": "CreateProjectV2StatusUpdatePayload" + }, + { + "name": "CreatePullRequestInput" + }, + { + "name": "CreatePullRequestPayload" + }, + { + "name": "CreateRefInput" + }, + { + "name": "CreateRefPayload" + }, + { + "name": "CreateRepositoryInput" + }, + { + "name": "CreateRepositoryPayload" + }, + { + "name": "CreateRepositoryRulesetInput" + }, + { + "name": "CreateRepositoryRulesetPayload" + }, + { + "name": "CreateSponsorsListingInput" + }, + { + "name": "CreateSponsorsListingPayload" + }, + { + "name": "CreateSponsorsTierInput" + }, + { + "name": "CreateSponsorsTierPayload" + }, + { + "name": "CreateSponsorshipInput" + }, + { + "name": "CreateSponsorshipPayload" + }, + { + "name": "CreateSponsorshipsInput" + }, + { + "name": "CreateSponsorshipsPayload" + }, + { + "name": "CreateTeamDiscussionCommentInput" + }, + { + "name": "CreateTeamDiscussionCommentPayload" + }, + { + "name": "CreateTeamDiscussionInput" + }, + { + "name": "CreateTeamDiscussionPayload" + }, + { + "name": "CreateUserListInput" + }, + { + "name": "CreateUserListPayload" + }, + { + "name": "CreatedCommitContribution" + }, + { + "name": "CreatedCommitContributionConnection" + }, + { + "name": "CreatedCommitContributionEdge" + }, + { + "name": "CreatedIssueContribution" + }, + { + "name": "CreatedIssueContributionConnection" + }, + { + "name": "CreatedIssueContributionEdge" + }, + { + "name": "CreatedIssueOrRestrictedContribution" + }, + { + "name": "CreatedPullRequestContribution" + }, + { + "name": "CreatedPullRequestContributionConnection" + }, + { + "name": "CreatedPullRequestContributionEdge" + }, + { + "name": "CreatedPullRequestOrRestrictedContribution" + }, + { + "name": "CreatedPullRequestReviewContribution" + }, + { + "name": "CreatedPullRequestReviewContributionConnection" + }, + { + "name": "CreatedPullRequestReviewContributionEdge" + }, + { + "name": "CreatedRepositoryContribution" + }, + { + "name": "CreatedRepositoryContributionConnection" + }, + { + "name": "CreatedRepositoryContributionEdge" + }, + { + "name": "CreatedRepositoryOrRestrictedContribution" + }, + { + "name": "CrossReferencedEvent" + }, + { + "name": "Date" + }, + { + "name": "DateTime" + }, + { + "name": "DeclineTopicSuggestionInput" + }, + { + "name": "DeclineTopicSuggestionPayload" + }, + { + "name": "DefaultRepositoryPermissionField" + }, + { + "name": "Deletable" + }, + { + "name": "DeleteBranchProtectionRuleInput" + }, + { + "name": "DeleteBranchProtectionRulePayload" + }, + { + "name": "DeleteDeploymentInput" + }, + { + "name": "DeleteDeploymentPayload" + }, + { + "name": "DeleteDiscussionCommentInput" + }, + { + "name": "DeleteDiscussionCommentPayload" + }, + { + "name": "DeleteDiscussionInput" + }, + { + "name": "DeleteDiscussionPayload" + }, + { + "name": "DeleteEnvironmentInput" + }, + { + "name": "DeleteEnvironmentPayload" + }, + { + "name": "DeleteIpAllowListEntryInput" + }, + { + "name": "DeleteIpAllowListEntryPayload" + }, + { + "name": "DeleteIssueCommentInput" + }, + { + "name": "DeleteIssueCommentPayload" + }, + { + "name": "DeleteIssueInput" + }, + { + "name": "DeleteIssuePayload" + }, + { + "name": "DeleteLabelInput" + }, + { + "name": "DeleteLabelPayload" + }, + { + "name": "DeleteLinkedBranchInput" + }, + { + "name": "DeleteLinkedBranchPayload" + }, + { + "name": "DeletePackageVersionInput" + }, + { + "name": "DeletePackageVersionPayload" + }, + { + "name": "DeleteProjectCardInput" + }, + { + "name": "DeleteProjectCardPayload" + }, + { + "name": "DeleteProjectColumnInput" + }, + { + "name": "DeleteProjectColumnPayload" + }, + { + "name": "DeleteProjectInput" + }, + { + "name": "DeleteProjectPayload" + }, + { + "name": "DeleteProjectV2FieldInput" + }, + { + "name": "DeleteProjectV2FieldPayload" + }, + { + "name": "DeleteProjectV2Input" + }, + { + "name": "DeleteProjectV2ItemInput" + }, + { + "name": "DeleteProjectV2ItemPayload" + }, + { + "name": "DeleteProjectV2Payload" + }, + { + "name": "DeleteProjectV2StatusUpdateInput" + }, + { + "name": "DeleteProjectV2StatusUpdatePayload" + }, + { + "name": "DeleteProjectV2WorkflowInput" + }, + { + "name": "DeleteProjectV2WorkflowPayload" + }, + { + "name": "DeletePullRequestReviewCommentInput" + }, + { + "name": "DeletePullRequestReviewCommentPayload" + }, + { + "name": "DeletePullRequestReviewInput" + }, + { + "name": "DeletePullRequestReviewPayload" + }, + { + "name": "DeleteRefInput" + }, + { + "name": "DeleteRefPayload" + }, + { + "name": "DeleteRepositoryRulesetInput" + }, + { + "name": "DeleteRepositoryRulesetPayload" + }, + { + "name": "DeleteTeamDiscussionCommentInput" + }, + { + "name": "DeleteTeamDiscussionCommentPayload" + }, + { + "name": "DeleteTeamDiscussionInput" + }, + { + "name": "DeleteTeamDiscussionPayload" + }, + { + "name": "DeleteUserListInput" + }, + { + "name": "DeleteUserListPayload" + }, + { + "name": "DeleteVerifiableDomainInput" + }, + { + "name": "DeleteVerifiableDomainPayload" + }, + { + "name": "DemilestonedEvent" + }, + { + "name": "DependabotUpdate" + }, + { + "name": "DependabotUpdateError" + }, + { + "name": "DependencyGraphDependency" + }, + { + "name": "DependencyGraphDependencyConnection" + }, + { + "name": "DependencyGraphDependencyEdge" + }, + { + "name": "DependencyGraphEcosystem" + }, + { + "name": "DependencyGraphManifest" + }, + { + "name": "DependencyGraphManifestConnection" + }, + { + "name": "DependencyGraphManifestEdge" + }, + { + "name": "DeployKey" + }, + { + "name": "DeployKeyConnection" + }, + { + "name": "DeployKeyEdge" + }, + { + "name": "DeployedEvent" + }, + { + "name": "Deployment" + }, + { + "name": "DeploymentConnection" + }, + { + "name": "DeploymentEdge" + }, + { + "name": "DeploymentEnvironmentChangedEvent" + }, + { + "name": "DeploymentOrder" + }, + { + "name": "DeploymentOrderField" + }, + { + "name": "DeploymentProtectionRule" + }, + { + "name": "DeploymentProtectionRuleConnection" + }, + { + "name": "DeploymentProtectionRuleEdge" + }, + { + "name": "DeploymentProtectionRuleType" + }, + { + "name": "DeploymentRequest" + }, + { + "name": "DeploymentRequestConnection" + }, + { + "name": "DeploymentRequestEdge" + }, + { + "name": "DeploymentReview" + }, + { + "name": "DeploymentReviewConnection" + }, + { + "name": "DeploymentReviewEdge" + }, + { + "name": "DeploymentReviewState" + }, + { + "name": "DeploymentReviewer" + }, + { + "name": "DeploymentReviewerConnection" + }, + { + "name": "DeploymentReviewerEdge" + }, + { + "name": "DeploymentState" + }, + { + "name": "DeploymentStatus" + }, + { + "name": "DeploymentStatusConnection" + }, + { + "name": "DeploymentStatusEdge" + }, + { + "name": "DeploymentStatusState" + }, + { + "name": "DequeuePullRequestInput" + }, + { + "name": "DequeuePullRequestPayload" + }, + { + "name": "DiffSide" + }, + { + "name": "DisablePullRequestAutoMergeInput" + }, + { + "name": "DisablePullRequestAutoMergePayload" + }, + { + "name": "DisconnectedEvent" + }, + { + "name": "Discussion" + }, + { + "name": "DiscussionCategory" + }, + { + "name": "DiscussionCategoryConnection" + }, + { + "name": "DiscussionCategoryEdge" + }, + { + "name": "DiscussionCloseReason" + }, + { + "name": "DiscussionComment" + }, + { + "name": "DiscussionCommentConnection" + }, + { + "name": "DiscussionCommentEdge" + }, + { + "name": "DiscussionConnection" + }, + { + "name": "DiscussionEdge" + }, + { + "name": "DiscussionOrder" + }, + { + "name": "DiscussionOrderField" + }, + { + "name": "DiscussionPoll" + }, + { + "name": "DiscussionPollOption" + }, + { + "name": "DiscussionPollOptionConnection" + }, + { + "name": "DiscussionPollOptionEdge" + }, + { + "name": "DiscussionPollOptionOrder" + }, + { + "name": "DiscussionPollOptionOrderField" + }, + { + "name": "DiscussionState" + }, + { + "name": "DiscussionStateReason" + }, + { + "name": "DismissPullRequestReviewInput" + }, + { + "name": "DismissPullRequestReviewPayload" + }, + { + "name": "DismissReason" + }, + { + "name": "DismissRepositoryVulnerabilityAlertInput" + }, + { + "name": "DismissRepositoryVulnerabilityAlertPayload" + }, + { + "name": "DraftIssue" + }, + { + "name": "DraftPullRequestReviewComment" + }, + { + "name": "DraftPullRequestReviewThread" + }, + { + "name": "EPSS" + }, + { + "name": "EnablePullRequestAutoMergeInput" + }, + { + "name": "EnablePullRequestAutoMergePayload" + }, + { + "name": "EnqueuePullRequestInput" + }, + { + "name": "EnqueuePullRequestPayload" + }, + { + "name": "Enterprise" + }, + { + "name": "EnterpriseAdministratorConnection" + }, + { + "name": "EnterpriseAdministratorEdge" + }, + { + "name": "EnterpriseAdministratorInvitation" + }, + { + "name": "EnterpriseAdministratorInvitationConnection" + }, + { + "name": "EnterpriseAdministratorInvitationEdge" + }, + { + "name": "EnterpriseAdministratorInvitationOrder" + }, + { + "name": "EnterpriseAdministratorInvitationOrderField" + }, + { + "name": "EnterpriseAdministratorRole" + }, + { + "name": "EnterpriseAllowPrivateRepositoryForkingPolicyValue" + }, + { + "name": "EnterpriseAuditEntryData" + }, + { + "name": "EnterpriseBillingInfo" + }, + { + "name": "EnterpriseConnection" + }, + { + "name": "EnterpriseDefaultRepositoryPermissionSettingValue" + }, + { + "name": "EnterpriseDisallowedMethodsSettingValue" + }, + { + "name": "EnterpriseEdge" + }, + { + "name": "EnterpriseEnabledDisabledSettingValue" + }, + { + "name": "EnterpriseEnabledSettingValue" + }, + { + "name": "EnterpriseFailedInvitationConnection" + }, + { + "name": "EnterpriseFailedInvitationEdge" + }, + { + "name": "EnterpriseIdentityProvider" + }, + { + "name": "EnterpriseMember" + }, + { + "name": "EnterpriseMemberConnection" + }, + { + "name": "EnterpriseMemberEdge" + }, + { + "name": "EnterpriseMemberInvitation" + }, + { + "name": "EnterpriseMemberInvitationConnection" + }, + { + "name": "EnterpriseMemberInvitationEdge" + }, + { + "name": "EnterpriseMemberInvitationOrder" + }, + { + "name": "EnterpriseMemberInvitationOrderField" + }, + { + "name": "EnterpriseMemberOrder" + }, + { + "name": "EnterpriseMemberOrderField" + }, + { + "name": "EnterpriseMembersCanCreateRepositoriesSettingValue" + }, + { + "name": "EnterpriseMembersCanMakePurchasesSettingValue" + }, + { + "name": "EnterpriseMembershipType" + }, + { + "name": "EnterpriseOrder" + }, + { + "name": "EnterpriseOrderField" + }, + { + "name": "EnterpriseOrganizationMembershipConnection" + }, + { + "name": "EnterpriseOrganizationMembershipEdge" + }, + { + "name": "EnterpriseOutsideCollaboratorConnection" + }, + { + "name": "EnterpriseOutsideCollaboratorEdge" + }, + { + "name": "EnterpriseOwnerInfo" + }, + { + "name": "EnterprisePendingMemberInvitationConnection" + }, + { + "name": "EnterprisePendingMemberInvitationEdge" + }, + { + "name": "EnterpriseRepositoryInfo" + }, + { + "name": "EnterpriseRepositoryInfoConnection" + }, + { + "name": "EnterpriseRepositoryInfoEdge" + }, + { + "name": "EnterpriseServerInstallation" + }, + { + "name": "EnterpriseServerInstallationConnection" + }, + { + "name": "EnterpriseServerInstallationEdge" + }, + { + "name": "EnterpriseServerInstallationMembershipConnection" + }, + { + "name": "EnterpriseServerInstallationMembershipEdge" + }, + { + "name": "EnterpriseServerInstallationOrder" + }, + { + "name": "EnterpriseServerInstallationOrderField" + }, + { + "name": "EnterpriseServerUserAccount" + }, + { + "name": "EnterpriseServerUserAccountConnection" + }, + { + "name": "EnterpriseServerUserAccountEdge" + }, + { + "name": "EnterpriseServerUserAccountEmail" + }, + { + "name": "EnterpriseServerUserAccountEmailConnection" + }, + { + "name": "EnterpriseServerUserAccountEmailEdge" + }, + { + "name": "EnterpriseServerUserAccountEmailOrder" + }, + { + "name": "EnterpriseServerUserAccountEmailOrderField" + }, + { + "name": "EnterpriseServerUserAccountOrder" + }, + { + "name": "EnterpriseServerUserAccountOrderField" + }, + { + "name": "EnterpriseServerUserAccountsUpload" + }, + { + "name": "EnterpriseServerUserAccountsUploadConnection" + }, + { + "name": "EnterpriseServerUserAccountsUploadEdge" + }, + { + "name": "EnterpriseServerUserAccountsUploadOrder" + }, + { + "name": "EnterpriseServerUserAccountsUploadOrderField" + }, + { + "name": "EnterpriseServerUserAccountsUploadSyncState" + }, + { + "name": "EnterpriseUserAccount" + }, + { + "name": "EnterpriseUserAccountMembershipRole" + }, + { + "name": "EnterpriseUserDeployment" + }, + { + "name": "Environment" + }, + { + "name": "EnvironmentConnection" + }, + { + "name": "EnvironmentEdge" + }, + { + "name": "EnvironmentOrderField" + }, + { + "name": "EnvironmentPinnedFilterField" + }, + { + "name": "Environments" + }, + { + "name": "ExternalIdentity" + }, + { + "name": "ExternalIdentityAttribute" + }, + { + "name": "ExternalIdentityConnection" + }, + { + "name": "ExternalIdentityEdge" + }, + { + "name": "ExternalIdentitySamlAttributes" + }, + { + "name": "ExternalIdentityScimAttributes" + }, + { + "name": "FileAddition" + }, + { + "name": "FileChanges" + }, + { + "name": "FileDeletion" + }, + { + "name": "FileExtensionRestrictionParameters" + }, + { + "name": "FileExtensionRestrictionParametersInput" + }, + { + "name": "FilePathRestrictionParameters" + }, + { + "name": "FilePathRestrictionParametersInput" + }, + { + "name": "FileViewedState" + }, + { + "name": "Float" + }, + { + "name": "FollowOrganizationInput" + }, + { + "name": "FollowOrganizationPayload" + }, + { + "name": "FollowUserInput" + }, + { + "name": "FollowUserPayload" + }, + { + "name": "FollowerConnection" + }, + { + "name": "FollowingConnection" + }, + { + "name": "FundingLink" + }, + { + "name": "FundingPlatform" + }, + { + "name": "GenericHovercardContext" + }, + { + "name": "Gist" + }, + { + "name": "GistComment" + }, + { + "name": "GistCommentConnection" + }, + { + "name": "GistCommentEdge" + }, + { + "name": "GistConnection" + }, + { + "name": "GistEdge" + }, + { + "name": "GistFile" + }, + { + "name": "GistOrder" + }, + { + "name": "GistOrderField" + }, + { + "name": "GistPrivacy" + }, + { + "name": "GitActor" + }, + { + "name": "GitActorConnection" + }, + { + "name": "GitActorEdge" + }, + { + "name": "GitHubMetadata" + }, + { + "name": "GitObject" + }, + { + "name": "GitObjectID" + }, + { + "name": "GitRefname" + }, + { + "name": "GitSSHRemote" + }, + { + "name": "GitSignature" + }, + { + "name": "GitSignatureState" + }, + { + "name": "GitTimestamp" + }, + { + "name": "GpgSignature" + }, + { + "name": "GrantEnterpriseOrganizationsMigratorRoleInput" + }, + { + "name": "GrantEnterpriseOrganizationsMigratorRolePayload" + }, + { + "name": "GrantMigratorRoleInput" + }, + { + "name": "GrantMigratorRolePayload" + }, + { + "name": "HTML" + }, + { + "name": "HeadRefDeletedEvent" + }, + { + "name": "HeadRefForcePushedEvent" + }, + { + "name": "HeadRefRestoredEvent" + }, + { + "name": "Hovercard" + }, + { + "name": "HovercardContext" + }, + { + "name": "ID" + }, + { + "name": "IdentityProviderConfigurationState" + }, + { + "name": "ImportProjectInput" + }, + { + "name": "ImportProjectPayload" + }, + { + "name": "Int" + }, + { + "name": "InviteEnterpriseAdminInput" + }, + { + "name": "InviteEnterpriseAdminPayload" + }, + { + "name": "InviteEnterpriseMemberInput" + }, + { + "name": "InviteEnterpriseMemberPayload" + }, + { + "name": "IpAllowListEnabledSettingValue" + }, + { + "name": "IpAllowListEntry" + }, + { + "name": "IpAllowListEntryConnection" + }, + { + "name": "IpAllowListEntryEdge" + }, + { + "name": "IpAllowListEntryOrder" + }, + { + "name": "IpAllowListEntryOrderField" + }, + { + "name": "IpAllowListForInstalledAppsEnabledSettingValue" + }, + { + "name": "IpAllowListOwner" + }, + { + "name": "Issue" + }, + { + "name": "IssueClosedStateReason" + }, + { + "name": "IssueComment" + }, + { + "name": "IssueCommentConnection" + }, + { + "name": "IssueCommentEdge" + }, + { + "name": "IssueCommentOrder" + }, + { + "name": "IssueCommentOrderField" + }, + { + "name": "IssueConnection" + }, + { + "name": "IssueContributionsByRepository" + }, + { + "name": "IssueEdge" + }, + { + "name": "IssueFilters" + }, + { + "name": "IssueOrPullRequest" + }, + { + "name": "IssueOrder" + }, + { + "name": "IssueOrderField" + }, + { + "name": "IssueState" + }, + { + "name": "IssueStateReason" + }, + { + "name": "IssueTemplate" + }, + { + "name": "IssueTimelineConnection" + }, + { + "name": "IssueTimelineItem" + }, + { + "name": "IssueTimelineItemEdge" + }, + { + "name": "IssueTimelineItems" + }, + { + "name": "IssueTimelineItemsConnection" + }, + { + "name": "IssueTimelineItemsEdge" + }, + { + "name": "IssueTimelineItemsItemType" + }, + { + "name": "JoinedGitHubContribution" + }, + { + "name": "Label" + }, + { + "name": "LabelConnection" + }, + { + "name": "LabelEdge" + }, + { + "name": "LabelOrder" + }, + { + "name": "LabelOrderField" + }, + { + "name": "Labelable" + }, + { + "name": "LabeledEvent" + }, + { + "name": "Language" + }, + { + "name": "LanguageConnection" + }, + { + "name": "LanguageEdge" + }, + { + "name": "LanguageOrder" + }, + { + "name": "LanguageOrderField" + }, + { + "name": "License" + }, + { + "name": "LicenseRule" + }, + { + "name": "LinkProjectV2ToRepositoryInput" + }, + { + "name": "LinkProjectV2ToRepositoryPayload" + }, + { + "name": "LinkProjectV2ToTeamInput" + }, + { + "name": "LinkProjectV2ToTeamPayload" + }, + { + "name": "LinkRepositoryToProjectInput" + }, + { + "name": "LinkRepositoryToProjectPayload" + }, + { + "name": "LinkedBranch" + }, + { + "name": "LinkedBranchConnection" + }, + { + "name": "LinkedBranchEdge" + }, + { + "name": "LockLockableInput" + }, + { + "name": "LockLockablePayload" + }, + { + "name": "LockReason" + }, + { + "name": "Lockable" + }, + { + "name": "LockedEvent" + }, + { + "name": "Mannequin" + }, + { + "name": "MannequinConnection" + }, + { + "name": "MannequinEdge" + }, + { + "name": "MannequinOrder" + }, + { + "name": "MannequinOrderField" + }, + { + "name": "MarkDiscussionCommentAsAnswerInput" + }, + { + "name": "MarkDiscussionCommentAsAnswerPayload" + }, + { + "name": "MarkFileAsViewedInput" + }, + { + "name": "MarkFileAsViewedPayload" + }, + { + "name": "MarkProjectV2AsTemplateInput" + }, + { + "name": "MarkProjectV2AsTemplatePayload" + }, + { + "name": "MarkPullRequestReadyForReviewInput" + }, + { + "name": "MarkPullRequestReadyForReviewPayload" + }, + { + "name": "MarkedAsDuplicateEvent" + }, + { + "name": "MarketplaceCategory" + }, + { + "name": "MarketplaceListing" + }, + { + "name": "MarketplaceListingConnection" + }, + { + "name": "MarketplaceListingEdge" + }, + { + "name": "MaxFilePathLengthParameters" + }, + { + "name": "MaxFilePathLengthParametersInput" + }, + { + "name": "MaxFileSizeParameters" + }, + { + "name": "MaxFileSizeParametersInput" + }, + { + "name": "MemberFeatureRequestNotification" + }, + { + "name": "MemberStatusable" + }, + { + "name": "MembersCanDeleteReposClearAuditEntry" + }, + { + "name": "MembersCanDeleteReposDisableAuditEntry" + }, + { + "name": "MembersCanDeleteReposEnableAuditEntry" + }, + { + "name": "MentionedEvent" + }, + { + "name": "MergeBranchInput" + }, + { + "name": "MergeBranchPayload" + }, + { + "name": "MergeCommitMessage" + }, + { + "name": "MergeCommitTitle" + }, + { + "name": "MergePullRequestInput" + }, + { + "name": "MergePullRequestPayload" + }, + { + "name": "MergeQueue" + }, + { + "name": "MergeQueueConfiguration" + }, + { + "name": "MergeQueueEntry" + }, + { + "name": "MergeQueueEntryConnection" + }, + { + "name": "MergeQueueEntryEdge" + }, + { + "name": "MergeQueueEntryState" + }, + { + "name": "MergeQueueGroupingStrategy" + }, + { + "name": "MergeQueueMergeMethod" + }, + { + "name": "MergeQueueMergingStrategy" + }, + { + "name": "MergeQueueParameters" + }, + { + "name": "MergeQueueParametersInput" + }, + { + "name": "MergeStateStatus" + }, + { + "name": "MergeableState" + }, + { + "name": "MergedEvent" + }, + { + "name": "Migration" + }, + { + "name": "MigrationSource" + }, + { + "name": "MigrationSourceType" + }, + { + "name": "MigrationState" + }, + { + "name": "Milestone" + }, + { + "name": "MilestoneConnection" + }, + { + "name": "MilestoneEdge" + }, + { + "name": "MilestoneItem" + }, + { + "name": "MilestoneOrder" + }, + { + "name": "MilestoneOrderField" + }, + { + "name": "MilestoneState" + }, + { + "name": "MilestonedEvent" + }, + { + "name": "Minimizable" + }, + { + "name": "MinimizeCommentInput" + }, + { + "name": "MinimizeCommentPayload" + }, + { + "name": "MoveProjectCardInput" + }, + { + "name": "MoveProjectCardPayload" + }, + { + "name": "MoveProjectColumnInput" + }, + { + "name": "MoveProjectColumnPayload" + }, + { + "name": "MovedColumnsInProjectEvent" + }, + { + "name": "Mutation" + }, + { + "name": "Node" + }, + { + "name": "NotificationRestrictionSettingValue" + }, + { + "name": "OIDCProvider" + }, + { + "name": "OIDCProviderType" + }, + { + "name": "OauthApplicationAuditEntryData" + }, + { + "name": "OauthApplicationCreateAuditEntry" + }, + { + "name": "OauthApplicationCreateAuditEntryState" + }, + { + "name": "OperationType" + }, + { + "name": "OrderDirection" + }, + { + "name": "OrgAddBillingManagerAuditEntry" + }, + { + "name": "OrgAddMemberAuditEntry" + }, + { + "name": "OrgAddMemberAuditEntryPermission" + }, + { + "name": "OrgBlockUserAuditEntry" + }, + { + "name": "OrgConfigDisableCollaboratorsOnlyAuditEntry" + }, + { + "name": "OrgConfigEnableCollaboratorsOnlyAuditEntry" + }, + { + "name": "OrgCreateAuditEntry" + }, + { + "name": "OrgCreateAuditEntryBillingPlan" + }, + { + "name": "OrgDisableOauthAppRestrictionsAuditEntry" + }, + { + "name": "OrgDisableSamlAuditEntry" + }, + { + "name": "OrgDisableTwoFactorRequirementAuditEntry" + }, + { + "name": "OrgEnableOauthAppRestrictionsAuditEntry" + }, + { + "name": "OrgEnableSamlAuditEntry" + }, + { + "name": "OrgEnableTwoFactorRequirementAuditEntry" + }, + { + "name": "OrgEnterpriseOwnerOrder" + }, + { + "name": "OrgEnterpriseOwnerOrderField" + }, + { + "name": "OrgInviteMemberAuditEntry" + }, + { + "name": "OrgInviteToBusinessAuditEntry" + }, + { + "name": "OrgOauthAppAccessApprovedAuditEntry" + }, + { + "name": "OrgOauthAppAccessBlockedAuditEntry" + }, + { + "name": "OrgOauthAppAccessDeniedAuditEntry" + }, + { + "name": "OrgOauthAppAccessRequestedAuditEntry" + }, + { + "name": "OrgOauthAppAccessUnblockedAuditEntry" + }, + { + "name": "OrgRemoveBillingManagerAuditEntry" + }, + { + "name": "OrgRemoveBillingManagerAuditEntryReason" + }, + { + "name": "OrgRemoveMemberAuditEntry" + }, + { + "name": "OrgRemoveMemberAuditEntryMembershipType" + }, + { + "name": "OrgRemoveMemberAuditEntryReason" + }, + { + "name": "OrgRemoveOutsideCollaboratorAuditEntry" + }, + { + "name": "OrgRemoveOutsideCollaboratorAuditEntryMembershipType" + }, + { + "name": "OrgRemoveOutsideCollaboratorAuditEntryReason" + }, + { + "name": "OrgRestoreMemberAuditEntry" + }, + { + "name": "OrgRestoreMemberAuditEntryMembership" + }, + { + "name": "OrgRestoreMemberMembershipOrganizationAuditEntryData" + }, + { + "name": "OrgRestoreMemberMembershipRepositoryAuditEntryData" + }, + { + "name": "OrgRestoreMemberMembershipTeamAuditEntryData" + }, + { + "name": "OrgUnblockUserAuditEntry" + }, + { + "name": "OrgUpdateDefaultRepositoryPermissionAuditEntry" + }, + { + "name": "OrgUpdateDefaultRepositoryPermissionAuditEntryPermission" + }, + { + "name": "OrgUpdateMemberAuditEntry" + }, + { + "name": "OrgUpdateMemberAuditEntryPermission" + }, + { + "name": "OrgUpdateMemberRepositoryCreationPermissionAuditEntry" + }, + { + "name": "OrgUpdateMemberRepositoryCreationPermissionAuditEntryVisibility" + }, + { + "name": "OrgUpdateMemberRepositoryInvitationPermissionAuditEntry" + }, + { + "name": "Organization" + }, + { + "name": "OrganizationAuditEntry" + }, + { + "name": "OrganizationAuditEntryConnection" + }, + { + "name": "OrganizationAuditEntryData" + }, + { + "name": "OrganizationAuditEntryEdge" + }, + { + "name": "OrganizationConnection" + }, + { + "name": "OrganizationEdge" + }, + { + "name": "OrganizationEnterpriseOwnerConnection" + }, + { + "name": "OrganizationEnterpriseOwnerEdge" + }, + { + "name": "OrganizationIdentityProvider" + }, + { + "name": "OrganizationInvitation" + }, + { + "name": "OrganizationInvitationConnection" + }, + { + "name": "OrganizationInvitationEdge" + }, + { + "name": "OrganizationInvitationRole" + }, + { + "name": "OrganizationInvitationSource" + }, + { + "name": "OrganizationInvitationType" + }, + { + "name": "OrganizationMemberConnection" + }, + { + "name": "OrganizationMemberEdge" + }, + { + "name": "OrganizationMemberRole" + }, + { + "name": "OrganizationMembersCanCreateRepositoriesSettingValue" + }, + { + "name": "OrganizationMigration" + }, + { + "name": "OrganizationMigrationState" + }, + { + "name": "OrganizationOrUser" + }, + { + "name": "OrganizationOrder" + }, + { + "name": "OrganizationOrderField" + }, + { + "name": "OrganizationTeamsHovercardContext" + }, + { + "name": "OrganizationsHovercardContext" + }, + { + "name": "Package" + }, + { + "name": "PackageConnection" + }, + { + "name": "PackageEdge" + }, + { + "name": "PackageFile" + }, + { + "name": "PackageFileConnection" + }, + { + "name": "PackageFileEdge" + }, + { + "name": "PackageFileOrder" + }, + { + "name": "PackageFileOrderField" + }, + { + "name": "PackageOrder" + }, + { + "name": "PackageOrderField" + }, + { + "name": "PackageOwner" + }, + { + "name": "PackageStatistics" + }, + { + "name": "PackageTag" + }, + { + "name": "PackageType" + }, + { + "name": "PackageVersion" + }, + { + "name": "PackageVersionConnection" + }, + { + "name": "PackageVersionEdge" + }, + { + "name": "PackageVersionOrder" + }, + { + "name": "PackageVersionOrderField" + }, + { + "name": "PackageVersionStatistics" + }, + { + "name": "PageInfo" + }, + { + "name": "ParentIssueAddedEvent" + }, + { + "name": "ParentIssueRemovedEvent" + }, + { + "name": "PatchStatus" + }, + { + "name": "PermissionGranter" + }, + { + "name": "PermissionSource" + }, + { + "name": "PinEnvironmentInput" + }, + { + "name": "PinEnvironmentPayload" + }, + { + "name": "PinIssueInput" + }, + { + "name": "PinIssuePayload" + }, + { + "name": "PinnableItem" + }, + { + "name": "PinnableItemConnection" + }, + { + "name": "PinnableItemEdge" + }, + { + "name": "PinnableItemType" + }, + { + "name": "PinnedDiscussion" + }, + { + "name": "PinnedDiscussionConnection" + }, + { + "name": "PinnedDiscussionEdge" + }, + { + "name": "PinnedDiscussionGradient" + }, + { + "name": "PinnedDiscussionPattern" + }, + { + "name": "PinnedEnvironment" + }, + { + "name": "PinnedEnvironmentConnection" + }, + { + "name": "PinnedEnvironmentEdge" + }, + { + "name": "PinnedEnvironmentOrder" + }, + { + "name": "PinnedEnvironmentOrderField" + }, + { + "name": "PinnedEvent" + }, + { + "name": "PinnedIssue" + }, + { + "name": "PinnedIssueConnection" + }, + { + "name": "PinnedIssueEdge" + }, + { + "name": "PreciseDateTime" + }, + { + "name": "PrivateRepositoryForkingDisableAuditEntry" + }, + { + "name": "PrivateRepositoryForkingEnableAuditEntry" + }, + { + "name": "ProfileItemShowcase" + }, + { + "name": "ProfileOwner" + }, + { + "name": "Project" + }, + { + "name": "ProjectCard" + }, + { + "name": "ProjectCardArchivedState" + }, + { + "name": "ProjectCardConnection" + }, + { + "name": "ProjectCardEdge" + }, + { + "name": "ProjectCardImport" + }, + { + "name": "ProjectCardItem" + }, + { + "name": "ProjectCardState" + }, + { + "name": "ProjectColumn" + }, + { + "name": "ProjectColumnConnection" + }, + { + "name": "ProjectColumnEdge" + }, + { + "name": "ProjectColumnImport" + }, + { + "name": "ProjectColumnPurpose" + }, + { + "name": "ProjectConnection" + }, + { + "name": "ProjectEdge" + }, + { + "name": "ProjectOrder" + }, + { + "name": "ProjectOrderField" + }, + { + "name": "ProjectOwner" + }, + { + "name": "ProjectProgress" + }, + { + "name": "ProjectState" + }, + { + "name": "ProjectTemplate" + }, + { + "name": "ProjectV2" + }, + { + "name": "ProjectV2Actor" + }, + { + "name": "ProjectV2ActorConnection" + }, + { + "name": "ProjectV2ActorEdge" + }, + { + "name": "ProjectV2Collaborator" + }, + { + "name": "ProjectV2Connection" + }, + { + "name": "ProjectV2CustomFieldType" + }, + { + "name": "ProjectV2Edge" + }, + { + "name": "ProjectV2Field" + }, + { + "name": "ProjectV2FieldCommon" + }, + { + "name": "ProjectV2FieldConfiguration" + }, + { + "name": "ProjectV2FieldConfigurationConnection" + }, + { + "name": "ProjectV2FieldConfigurationEdge" + }, + { + "name": "ProjectV2FieldConnection" + }, + { + "name": "ProjectV2FieldEdge" + }, + { + "name": "ProjectV2FieldOrder" + }, + { + "name": "ProjectV2FieldOrderField" + }, + { + "name": "ProjectV2FieldType" + }, + { + "name": "ProjectV2FieldValue" + }, + { + "name": "ProjectV2Filters" + }, + { + "name": "ProjectV2Item" + }, + { + "name": "ProjectV2ItemConnection" + }, + { + "name": "ProjectV2ItemContent" + }, + { + "name": "ProjectV2ItemEdge" + }, + { + "name": "ProjectV2ItemFieldDateValue" + }, + { + "name": "ProjectV2ItemFieldIterationValue" + }, + { + "name": "ProjectV2ItemFieldLabelValue" + }, + { + "name": "ProjectV2ItemFieldMilestoneValue" + }, + { + "name": "ProjectV2ItemFieldNumberValue" + }, + { + "name": "ProjectV2ItemFieldPullRequestValue" + }, + { + "name": "ProjectV2ItemFieldRepositoryValue" + }, + { + "name": "ProjectV2ItemFieldReviewerValue" + }, + { + "name": "ProjectV2ItemFieldSingleSelectValue" + }, + { + "name": "ProjectV2ItemFieldTextValue" + }, + { + "name": "ProjectV2ItemFieldUserValue" + }, + { + "name": "ProjectV2ItemFieldValue" + }, + { + "name": "ProjectV2ItemFieldValueCommon" + }, + { + "name": "ProjectV2ItemFieldValueConnection" + }, + { + "name": "ProjectV2ItemFieldValueEdge" + }, + { + "name": "ProjectV2ItemFieldValueOrder" + }, + { + "name": "ProjectV2ItemFieldValueOrderField" + }, + { + "name": "ProjectV2ItemOrder" + }, + { + "name": "ProjectV2ItemOrderField" + }, + { + "name": "ProjectV2ItemType" + }, + { + "name": "ProjectV2IterationField" + }, + { + "name": "ProjectV2IterationFieldConfiguration" + }, + { + "name": "ProjectV2IterationFieldIteration" + }, + { + "name": "ProjectV2Order" + }, + { + "name": "ProjectV2OrderField" + }, + { + "name": "ProjectV2Owner" + }, + { + "name": "ProjectV2PermissionLevel" + }, + { + "name": "ProjectV2Recent" + }, + { + "name": "ProjectV2Roles" + }, + { + "name": "ProjectV2SingleSelectField" + }, + { + "name": "ProjectV2SingleSelectFieldOption" + }, + { + "name": "ProjectV2SingleSelectFieldOptionColor" + }, + { + "name": "ProjectV2SingleSelectFieldOptionInput" + }, + { + "name": "ProjectV2SortBy" + }, + { + "name": "ProjectV2SortByConnection" + }, + { + "name": "ProjectV2SortByEdge" + }, + { + "name": "ProjectV2SortByField" + }, + { + "name": "ProjectV2SortByFieldConnection" + }, + { + "name": "ProjectV2SortByFieldEdge" + }, + { + "name": "ProjectV2State" + }, + { + "name": "ProjectV2StatusOrder" + }, + { + "name": "ProjectV2StatusUpdate" + }, + { + "name": "ProjectV2StatusUpdateConnection" + }, + { + "name": "ProjectV2StatusUpdateEdge" + }, + { + "name": "ProjectV2StatusUpdateOrderField" + }, + { + "name": "ProjectV2StatusUpdateStatus" + }, + { + "name": "ProjectV2View" + }, + { + "name": "ProjectV2ViewConnection" + }, + { + "name": "ProjectV2ViewEdge" + }, + { + "name": "ProjectV2ViewLayout" + }, + { + "name": "ProjectV2ViewOrder" + }, + { + "name": "ProjectV2ViewOrderField" + }, + { + "name": "ProjectV2Workflow" + }, + { + "name": "ProjectV2WorkflowConnection" + }, + { + "name": "ProjectV2WorkflowEdge" + }, + { + "name": "ProjectV2WorkflowOrder" + }, + { + "name": "ProjectV2WorkflowsOrderField" + }, + { + "name": "PropertyTargetDefinition" + }, + { + "name": "PropertyTargetDefinitionInput" + }, + { + "name": "PublicKey" + }, + { + "name": "PublicKeyConnection" + }, + { + "name": "PublicKeyEdge" + }, + { + "name": "PublishSponsorsTierInput" + }, + { + "name": "PublishSponsorsTierPayload" + }, + { + "name": "PullRequest" + }, + { + "name": "PullRequestBranchUpdateMethod" + }, + { + "name": "PullRequestChangedFile" + }, + { + "name": "PullRequestChangedFileConnection" + }, + { + "name": "PullRequestChangedFileEdge" + }, + { + "name": "PullRequestCommit" + }, + { + "name": "PullRequestCommitCommentThread" + }, + { + "name": "PullRequestCommitConnection" + }, + { + "name": "PullRequestCommitEdge" + }, + { + "name": "PullRequestConnection" + }, + { + "name": "PullRequestContributionsByRepository" + }, + { + "name": "PullRequestEdge" + }, + { + "name": "PullRequestMergeMethod" + }, + { + "name": "PullRequestOrder" + }, + { + "name": "PullRequestOrderField" + }, + { + "name": "PullRequestParameters" + }, + { + "name": "PullRequestParametersInput" + }, + { + "name": "PullRequestReview" + }, + { + "name": "PullRequestReviewComment" + }, + { + "name": "PullRequestReviewCommentConnection" + }, + { + "name": "PullRequestReviewCommentEdge" + }, + { + "name": "PullRequestReviewCommentState" + }, + { + "name": "PullRequestReviewConnection" + }, + { + "name": "PullRequestReviewContributionsByRepository" + }, + { + "name": "PullRequestReviewDecision" + }, + { + "name": "PullRequestReviewEdge" + }, + { + "name": "PullRequestReviewEvent" + }, + { + "name": "PullRequestReviewState" + }, + { + "name": "PullRequestReviewThread" + }, + { + "name": "PullRequestReviewThreadConnection" + }, + { + "name": "PullRequestReviewThreadEdge" + }, + { + "name": "PullRequestReviewThreadSubjectType" + }, + { + "name": "PullRequestRevisionMarker" + }, + { + "name": "PullRequestState" + }, + { + "name": "PullRequestTemplate" + }, + { + "name": "PullRequestThread" + }, + { + "name": "PullRequestTimelineConnection" + }, + { + "name": "PullRequestTimelineItem" + }, + { + "name": "PullRequestTimelineItemEdge" + }, + { + "name": "PullRequestTimelineItems" + }, + { + "name": "PullRequestTimelineItemsConnection" + }, + { + "name": "PullRequestTimelineItemsEdge" + }, + { + "name": "PullRequestTimelineItemsItemType" + }, + { + "name": "PullRequestUpdateState" + }, + { + "name": "Push" + }, + { + "name": "PushAllowance" + }, + { + "name": "PushAllowanceActor" + }, + { + "name": "PushAllowanceConnection" + }, + { + "name": "PushAllowanceEdge" + }, + { + "name": "Query" + }, + { + "name": "RateLimit" + }, + { + "name": "Reactable" + }, + { + "name": "ReactingUserConnection" + }, + { + "name": "ReactingUserEdge" + }, + { + "name": "Reaction" + }, + { + "name": "ReactionConnection" + }, + { + "name": "ReactionContent" + }, + { + "name": "ReactionEdge" + }, + { + "name": "ReactionGroup" + }, + { + "name": "ReactionOrder" + }, + { + "name": "ReactionOrderField" + }, + { + "name": "Reactor" + }, + { + "name": "ReactorConnection" + }, + { + "name": "ReactorEdge" + }, + { + "name": "ReadyForReviewEvent" + }, + { + "name": "Ref" + }, + { + "name": "RefConnection" + }, + { + "name": "RefEdge" + }, + { + "name": "RefNameConditionTarget" + }, + { + "name": "RefNameConditionTargetInput" + }, + { + "name": "RefOrder" + }, + { + "name": "RefOrderField" + }, + { + "name": "RefUpdate" + }, + { + "name": "RefUpdateRule" + }, + { + "name": "ReferencedEvent" + }, + { + "name": "ReferencedSubject" + }, + { + "name": "RegenerateEnterpriseIdentityProviderRecoveryCodesInput" + }, + { + "name": "RegenerateEnterpriseIdentityProviderRecoveryCodesPayload" + }, + { + "name": "RegenerateVerifiableDomainTokenInput" + }, + { + "name": "RegenerateVerifiableDomainTokenPayload" + }, + { + "name": "RejectDeploymentsInput" + }, + { + "name": "RejectDeploymentsPayload" + }, + { + "name": "Release" + }, + { + "name": "ReleaseAsset" + }, + { + "name": "ReleaseAssetConnection" + }, + { + "name": "ReleaseAssetEdge" + }, + { + "name": "ReleaseConnection" + }, + { + "name": "ReleaseEdge" + }, + { + "name": "ReleaseOrder" + }, + { + "name": "ReleaseOrderField" + }, + { + "name": "RemoveAssigneesFromAssignableInput" + }, + { + "name": "RemoveAssigneesFromAssignablePayload" + }, + { + "name": "RemoveEnterpriseAdminInput" + }, + { + "name": "RemoveEnterpriseAdminPayload" + }, + { + "name": "RemoveEnterpriseIdentityProviderInput" + }, + { + "name": "RemoveEnterpriseIdentityProviderPayload" + }, + { + "name": "RemoveEnterpriseMemberInput" + }, + { + "name": "RemoveEnterpriseMemberPayload" + }, + { + "name": "RemoveEnterpriseOrganizationInput" + }, + { + "name": "RemoveEnterpriseOrganizationPayload" + }, + { + "name": "RemoveEnterpriseSupportEntitlementInput" + }, + { + "name": "RemoveEnterpriseSupportEntitlementPayload" + }, + { + "name": "RemoveLabelsFromLabelableInput" + }, + { + "name": "RemoveLabelsFromLabelablePayload" + }, + { + "name": "RemoveOutsideCollaboratorInput" + }, + { + "name": "RemoveOutsideCollaboratorPayload" + }, + { + "name": "RemoveReactionInput" + }, + { + "name": "RemoveReactionPayload" + }, + { + "name": "RemoveStarInput" + }, + { + "name": "RemoveStarPayload" + }, + { + "name": "RemoveSubIssueInput" + }, + { + "name": "RemoveSubIssuePayload" + }, + { + "name": "RemoveUpvoteInput" + }, + { + "name": "RemoveUpvotePayload" + }, + { + "name": "RemovedFromMergeQueueEvent" + }, + { + "name": "RemovedFromProjectEvent" + }, + { + "name": "RenamedTitleEvent" + }, + { + "name": "RenamedTitleSubject" + }, + { + "name": "ReopenDiscussionInput" + }, + { + "name": "ReopenDiscussionPayload" + }, + { + "name": "ReopenIssueInput" + }, + { + "name": "ReopenIssuePayload" + }, + { + "name": "ReopenPullRequestInput" + }, + { + "name": "ReopenPullRequestPayload" + }, + { + "name": "ReopenedEvent" + }, + { + "name": "ReorderEnvironmentInput" + }, + { + "name": "ReorderEnvironmentPayload" + }, + { + "name": "RepoAccessAuditEntry" + }, + { + "name": "RepoAccessAuditEntryVisibility" + }, + { + "name": "RepoAddMemberAuditEntry" + }, + { + "name": "RepoAddMemberAuditEntryVisibility" + }, + { + "name": "RepoAddTopicAuditEntry" + }, + { + "name": "RepoArchivedAuditEntry" + }, + { + "name": "RepoArchivedAuditEntryVisibility" + }, + { + "name": "RepoChangeMergeSettingAuditEntry" + }, + { + "name": "RepoChangeMergeSettingAuditEntryMergeType" + }, + { + "name": "RepoConfigDisableAnonymousGitAccessAuditEntry" + }, + { + "name": "RepoConfigDisableCollaboratorsOnlyAuditEntry" + }, + { + "name": "RepoConfigDisableContributorsOnlyAuditEntry" + }, + { + "name": "RepoConfigDisableSockpuppetDisallowedAuditEntry" + }, + { + "name": "RepoConfigEnableAnonymousGitAccessAuditEntry" + }, + { + "name": "RepoConfigEnableCollaboratorsOnlyAuditEntry" + }, + { + "name": "RepoConfigEnableContributorsOnlyAuditEntry" + }, + { + "name": "RepoConfigEnableSockpuppetDisallowedAuditEntry" + }, + { + "name": "RepoConfigLockAnonymousGitAccessAuditEntry" + }, + { + "name": "RepoConfigUnlockAnonymousGitAccessAuditEntry" + }, + { + "name": "RepoCreateAuditEntry" + }, + { + "name": "RepoCreateAuditEntryVisibility" + }, + { + "name": "RepoDestroyAuditEntry" + }, + { + "name": "RepoDestroyAuditEntryVisibility" + }, + { + "name": "RepoRemoveMemberAuditEntry" + }, + { + "name": "RepoRemoveMemberAuditEntryVisibility" + }, + { + "name": "RepoRemoveTopicAuditEntry" + }, + { + "name": "ReportedContentClassifiers" + }, + { + "name": "Repository" + }, + { + "name": "RepositoryAffiliation" + }, + { + "name": "RepositoryAuditEntryData" + }, + { + "name": "RepositoryCodeowners" + }, + { + "name": "RepositoryCodeownersError" + }, + { + "name": "RepositoryCollaboratorConnection" + }, + { + "name": "RepositoryCollaboratorEdge" + }, + { + "name": "RepositoryConnection" + }, + { + "name": "RepositoryContactLink" + }, + { + "name": "RepositoryContributionType" + }, + { + "name": "RepositoryDiscussionAuthor" + }, + { + "name": "RepositoryDiscussionCommentAuthor" + }, + { + "name": "RepositoryEdge" + }, + { + "name": "RepositoryIdConditionTarget" + }, + { + "name": "RepositoryIdConditionTargetInput" + }, + { + "name": "RepositoryInfo" + }, + { + "name": "RepositoryInteractionAbility" + }, + { + "name": "RepositoryInteractionLimit" + }, + { + "name": "RepositoryInteractionLimitExpiry" + }, + { + "name": "RepositoryInteractionLimitOrigin" + }, + { + "name": "RepositoryInvitation" + }, + { + "name": "RepositoryInvitationConnection" + }, + { + "name": "RepositoryInvitationEdge" + }, + { + "name": "RepositoryInvitationOrder" + }, + { + "name": "RepositoryInvitationOrderField" + }, + { + "name": "RepositoryLockReason" + }, + { + "name": "RepositoryMigration" + }, + { + "name": "RepositoryMigrationConnection" + }, + { + "name": "RepositoryMigrationEdge" + }, + { + "name": "RepositoryMigrationOrder" + }, + { + "name": "RepositoryMigrationOrderDirection" + }, + { + "name": "RepositoryMigrationOrderField" + }, + { + "name": "RepositoryNameConditionTarget" + }, + { + "name": "RepositoryNameConditionTargetInput" + }, + { + "name": "RepositoryNode" + }, + { + "name": "RepositoryOrder" + }, + { + "name": "RepositoryOrderField" + }, + { + "name": "RepositoryOwner" + }, + { + "name": "RepositoryPermission" + }, + { + "name": "RepositoryPlanFeatures" + }, + { + "name": "RepositoryPrivacy" + }, + { + "name": "RepositoryPropertyConditionTarget" + }, + { + "name": "RepositoryPropertyConditionTargetInput" + }, + { + "name": "RepositoryRule" + }, + { + "name": "RepositoryRuleConditions" + }, + { + "name": "RepositoryRuleConditionsInput" + }, + { + "name": "RepositoryRuleConnection" + }, + { + "name": "RepositoryRuleEdge" + }, + { + "name": "RepositoryRuleInput" + }, + { + "name": "RepositoryRuleOrder" + }, + { + "name": "RepositoryRuleOrderField" + }, + { + "name": "RepositoryRuleType" + }, + { + "name": "RepositoryRuleset" + }, + { + "name": "RepositoryRulesetBypassActor" + }, + { + "name": "RepositoryRulesetBypassActorBypassMode" + }, + { + "name": "RepositoryRulesetBypassActorConnection" + }, + { + "name": "RepositoryRulesetBypassActorEdge" + }, + { + "name": "RepositoryRulesetBypassActorInput" + }, + { + "name": "RepositoryRulesetConnection" + }, + { + "name": "RepositoryRulesetEdge" + }, + { + "name": "RepositoryRulesetTarget" + }, + { + "name": "RepositoryTopic" + }, + { + "name": "RepositoryTopicConnection" + }, + { + "name": "RepositoryTopicEdge" + }, + { + "name": "RepositoryVisibility" + }, + { + "name": "RepositoryVisibilityChangeDisableAuditEntry" + }, + { + "name": "RepositoryVisibilityChangeEnableAuditEntry" + }, + { + "name": "RepositoryVulnerabilityAlert" + }, + { + "name": "RepositoryVulnerabilityAlertConnection" + }, + { + "name": "RepositoryVulnerabilityAlertDependencyScope" + }, + { + "name": "RepositoryVulnerabilityAlertEdge" + }, + { + "name": "RepositoryVulnerabilityAlertState" + }, + { + "name": "ReprioritizeSubIssueInput" + }, + { + "name": "ReprioritizeSubIssuePayload" + }, + { + "name": "RequestReviewsInput" + }, + { + "name": "RequestReviewsPayload" + }, + { + "name": "RequestableCheckStatusState" + }, + { + "name": "RequestedReviewer" + }, + { + "name": "RequestedReviewerConnection" + }, + { + "name": "RequestedReviewerEdge" + }, + { + "name": "RequirableByPullRequest" + }, + { + "name": "RequiredDeploymentsParameters" + }, + { + "name": "RequiredDeploymentsParametersInput" + }, + { + "name": "RequiredStatusCheckDescription" + }, + { + "name": "RequiredStatusCheckInput" + }, + { + "name": "RequiredStatusChecksParameters" + }, + { + "name": "RequiredStatusChecksParametersInput" + }, + { + "name": "RerequestCheckSuiteInput" + }, + { + "name": "RerequestCheckSuitePayload" + }, + { + "name": "ResolveReviewThreadInput" + }, + { + "name": "ResolveReviewThreadPayload" + }, + { + "name": "RestrictedContribution" + }, + { + "name": "RetireSponsorsTierInput" + }, + { + "name": "RetireSponsorsTierPayload" + }, + { + "name": "RevertPullRequestInput" + }, + { + "name": "RevertPullRequestPayload" + }, + { + "name": "ReviewDismissalAllowance" + }, + { + "name": "ReviewDismissalAllowanceActor" + }, + { + "name": "ReviewDismissalAllowanceConnection" + }, + { + "name": "ReviewDismissalAllowanceEdge" + }, + { + "name": "ReviewDismissedEvent" + }, + { + "name": "ReviewRequest" + }, + { + "name": "ReviewRequestConnection" + }, + { + "name": "ReviewRequestEdge" + }, + { + "name": "ReviewRequestRemovedEvent" + }, + { + "name": "ReviewRequestedEvent" + }, + { + "name": "ReviewStatusHovercardContext" + }, + { + "name": "RevokeEnterpriseOrganizationsMigratorRoleInput" + }, + { + "name": "RevokeEnterpriseOrganizationsMigratorRolePayload" + }, + { + "name": "RevokeMigratorRoleInput" + }, + { + "name": "RevokeMigratorRolePayload" + }, + { + "name": "RoleInOrganization" + }, + { + "name": "RuleEnforcement" + }, + { + "name": "RuleParameters" + }, + { + "name": "RuleParametersInput" + }, + { + "name": "RuleSource" + }, + { + "name": "SamlDigestAlgorithm" + }, + { + "name": "SamlSignatureAlgorithm" + }, + { + "name": "SavedReply" + }, + { + "name": "SavedReplyConnection" + }, + { + "name": "SavedReplyEdge" + }, + { + "name": "SavedReplyOrder" + }, + { + "name": "SavedReplyOrderField" + }, + { + "name": "SearchResultItem" + }, + { + "name": "SearchResultItemConnection" + }, + { + "name": "SearchResultItemEdge" + }, + { + "name": "SearchType" + }, + { + "name": "SecurityAdvisory" + }, + { + "name": "SecurityAdvisoryClassification" + }, + { + "name": "SecurityAdvisoryConnection" + }, + { + "name": "SecurityAdvisoryEcosystem" + }, + { + "name": "SecurityAdvisoryEdge" + }, + { + "name": "SecurityAdvisoryIdentifier" + }, + { + "name": "SecurityAdvisoryIdentifierFilter" + }, + { + "name": "SecurityAdvisoryIdentifierType" + }, + { + "name": "SecurityAdvisoryOrder" + }, + { + "name": "SecurityAdvisoryOrderField" + }, + { + "name": "SecurityAdvisoryPackage" + }, + { + "name": "SecurityAdvisoryPackageVersion" + }, + { + "name": "SecurityAdvisoryReference" + }, + { + "name": "SecurityAdvisorySeverity" + }, + { + "name": "SecurityVulnerability" + }, + { + "name": "SecurityVulnerabilityConnection" + }, + { + "name": "SecurityVulnerabilityEdge" + }, + { + "name": "SecurityVulnerabilityOrder" + }, + { + "name": "SecurityVulnerabilityOrderField" + }, + { + "name": "SetEnterpriseIdentityProviderInput" + }, + { + "name": "SetEnterpriseIdentityProviderPayload" + }, + { + "name": "SetOrganizationInteractionLimitInput" + }, + { + "name": "SetOrganizationInteractionLimitPayload" + }, + { + "name": "SetRepositoryInteractionLimitInput" + }, + { + "name": "SetRepositoryInteractionLimitPayload" + }, + { + "name": "SetUserInteractionLimitInput" + }, + { + "name": "SetUserInteractionLimitPayload" + }, + { + "name": "SmimeSignature" + }, + { + "name": "SocialAccount" + }, + { + "name": "SocialAccountConnection" + }, + { + "name": "SocialAccountEdge" + }, + { + "name": "SocialAccountProvider" + }, + { + "name": "Sponsor" + }, + { + "name": "SponsorAndLifetimeValue" + }, + { + "name": "SponsorAndLifetimeValueConnection" + }, + { + "name": "SponsorAndLifetimeValueEdge" + }, + { + "name": "SponsorAndLifetimeValueOrder" + }, + { + "name": "SponsorAndLifetimeValueOrderField" + }, + { + "name": "SponsorConnection" + }, + { + "name": "SponsorEdge" + }, + { + "name": "SponsorOrder" + }, + { + "name": "SponsorOrderField" + }, + { + "name": "Sponsorable" + }, + { + "name": "SponsorableItem" + }, + { + "name": "SponsorableItemConnection" + }, + { + "name": "SponsorableItemEdge" + }, + { + "name": "SponsorableOrder" + }, + { + "name": "SponsorableOrderField" + }, + { + "name": "SponsorsActivity" + }, + { + "name": "SponsorsActivityAction" + }, + { + "name": "SponsorsActivityConnection" + }, + { + "name": "SponsorsActivityEdge" + }, + { + "name": "SponsorsActivityOrder" + }, + { + "name": "SponsorsActivityOrderField" + }, + { + "name": "SponsorsActivityPeriod" + }, + { + "name": "SponsorsCountryOrRegionCode" + }, + { + "name": "SponsorsGoal" + }, + { + "name": "SponsorsGoalKind" + }, + { + "name": "SponsorsListing" + }, + { + "name": "SponsorsListingFeatureableItem" + }, + { + "name": "SponsorsListingFeaturedItem" + }, + { + "name": "SponsorsListingFeaturedItemFeatureableType" + }, + { + "name": "SponsorsTier" + }, + { + "name": "SponsorsTierAdminInfo" + }, + { + "name": "SponsorsTierConnection" + }, + { + "name": "SponsorsTierEdge" + }, + { + "name": "SponsorsTierOrder" + }, + { + "name": "SponsorsTierOrderField" + }, + { + "name": "Sponsorship" + }, + { + "name": "SponsorshipConnection" + }, + { + "name": "SponsorshipEdge" + }, + { + "name": "SponsorshipNewsletter" + }, + { + "name": "SponsorshipNewsletterConnection" + }, + { + "name": "SponsorshipNewsletterEdge" + }, + { + "name": "SponsorshipNewsletterOrder" + }, + { + "name": "SponsorshipNewsletterOrderField" + }, + { + "name": "SponsorshipOrder" + }, + { + "name": "SponsorshipOrderField" + }, + { + "name": "SponsorshipPaymentSource" + }, + { + "name": "SponsorshipPrivacy" + }, + { + "name": "SquashMergeCommitMessage" + }, + { + "name": "SquashMergeCommitTitle" + }, + { + "name": "SshSignature" + }, + { + "name": "StarOrder" + }, + { + "name": "StarOrderField" + }, + { + "name": "StargazerConnection" + }, + { + "name": "StargazerEdge" + }, + { + "name": "Starrable" + }, + { + "name": "StarredRepositoryConnection" + }, + { + "name": "StarredRepositoryEdge" + }, + { + "name": "StartOrganizationMigrationInput" + }, + { + "name": "StartOrganizationMigrationPayload" + }, + { + "name": "StartRepositoryMigrationInput" + }, + { + "name": "StartRepositoryMigrationPayload" + }, + { + "name": "Status" + }, + { + "name": "StatusCheckConfiguration" + }, + { + "name": "StatusCheckConfigurationInput" + }, + { + "name": "StatusCheckRollup" + }, + { + "name": "StatusCheckRollupContext" + }, + { + "name": "StatusCheckRollupContextConnection" + }, + { + "name": "StatusCheckRollupContextEdge" + }, + { + "name": "StatusContext" + }, + { + "name": "StatusContextStateCount" + }, + { + "name": "StatusState" + }, + { + "name": "String" + }, + { + "name": "StripeConnectAccount" + }, + { + "name": "SubIssueAddedEvent" + }, + { + "name": "SubIssueRemovedEvent" + }, + { + "name": "SubIssuesSummary" + }, + { + "name": "SubmitPullRequestReviewInput" + }, + { + "name": "SubmitPullRequestReviewPayload" + }, + { + "name": "Submodule" + }, + { + "name": "SubmoduleConnection" + }, + { + "name": "SubmoduleEdge" + }, + { + "name": "Subscribable" + }, + { + "name": "SubscribableThread" + }, + { + "name": "SubscribedEvent" + }, + { + "name": "SubscriptionState" + }, + { + "name": "SuggestedReviewer" + }, + { + "name": "Tag" + }, + { + "name": "TagNamePatternParameters" + }, + { + "name": "TagNamePatternParametersInput" + }, + { + "name": "Team" + }, + { + "name": "TeamAddMemberAuditEntry" + }, + { + "name": "TeamAddRepositoryAuditEntry" + }, + { + "name": "TeamAuditEntryData" + }, + { + "name": "TeamChangeParentTeamAuditEntry" + }, + { + "name": "TeamConnection" + }, + { + "name": "TeamDiscussion" + }, + { + "name": "TeamDiscussionComment" + }, + { + "name": "TeamDiscussionCommentConnection" + }, + { + "name": "TeamDiscussionCommentEdge" + }, + { + "name": "TeamDiscussionCommentOrder" + }, + { + "name": "TeamDiscussionCommentOrderField" + }, + { + "name": "TeamDiscussionConnection" + }, + { + "name": "TeamDiscussionEdge" + }, + { + "name": "TeamDiscussionOrder" + }, + { + "name": "TeamDiscussionOrderField" + }, + { + "name": "TeamEdge" + }, + { + "name": "TeamMemberConnection" + }, + { + "name": "TeamMemberEdge" + }, + { + "name": "TeamMemberOrder" + }, + { + "name": "TeamMemberOrderField" + }, + { + "name": "TeamMemberRole" + }, + { + "name": "TeamMembershipType" + }, + { + "name": "TeamNotificationSetting" + }, + { + "name": "TeamOrder" + }, + { + "name": "TeamOrderField" + }, + { + "name": "TeamPrivacy" + }, + { + "name": "TeamRemoveMemberAuditEntry" + }, + { + "name": "TeamRemoveRepositoryAuditEntry" + }, + { + "name": "TeamRepositoryConnection" + }, + { + "name": "TeamRepositoryEdge" + }, + { + "name": "TeamRepositoryOrder" + }, + { + "name": "TeamRepositoryOrderField" + }, + { + "name": "TeamReviewAssignmentAlgorithm" + }, + { + "name": "TeamRole" + }, + { + "name": "TextMatch" + }, + { + "name": "TextMatchHighlight" + }, + { + "name": "ThreadSubscriptionFormAction" + }, + { + "name": "ThreadSubscriptionState" + }, + { + "name": "Topic" + }, + { + "name": "TopicAuditEntryData" + }, + { + "name": "TopicSuggestionDeclineReason" + }, + { + "name": "TrackedIssueStates" + }, + { + "name": "TransferEnterpriseOrganizationInput" + }, + { + "name": "TransferEnterpriseOrganizationPayload" + }, + { + "name": "TransferIssueInput" + }, + { + "name": "TransferIssuePayload" + }, + { + "name": "TransferredEvent" + }, + { + "name": "Tree" + }, + { + "name": "TreeEntry" + }, + { + "name": "TwoFactorCredentialSecurityType" + }, + { + "name": "URI" + }, + { + "name": "UnarchiveProjectV2ItemInput" + }, + { + "name": "UnarchiveProjectV2ItemPayload" + }, + { + "name": "UnarchiveRepositoryInput" + }, + { + "name": "UnarchiveRepositoryPayload" + }, + { + "name": "UnassignedEvent" + }, + { + "name": "UnfollowOrganizationInput" + }, + { + "name": "UnfollowOrganizationPayload" + }, + { + "name": "UnfollowUserInput" + }, + { + "name": "UnfollowUserPayload" + }, + { + "name": "UniformResourceLocatable" + }, + { + "name": "UnknownSignature" + }, + { + "name": "UnlabeledEvent" + }, + { + "name": "UnlinkProjectV2FromRepositoryInput" + }, + { + "name": "UnlinkProjectV2FromRepositoryPayload" + }, + { + "name": "UnlinkProjectV2FromTeamInput" + }, + { + "name": "UnlinkProjectV2FromTeamPayload" + }, + { + "name": "UnlinkRepositoryFromProjectInput" + }, + { + "name": "UnlinkRepositoryFromProjectPayload" + }, + { + "name": "UnlockLockableInput" + }, + { + "name": "UnlockLockablePayload" + }, + { + "name": "UnlockedEvent" + }, + { + "name": "UnmarkDiscussionCommentAsAnswerInput" + }, + { + "name": "UnmarkDiscussionCommentAsAnswerPayload" + }, + { + "name": "UnmarkFileAsViewedInput" + }, + { + "name": "UnmarkFileAsViewedPayload" + }, + { + "name": "UnmarkIssueAsDuplicateInput" + }, + { + "name": "UnmarkIssueAsDuplicatePayload" + }, + { + "name": "UnmarkProjectV2AsTemplateInput" + }, + { + "name": "UnmarkProjectV2AsTemplatePayload" + }, + { + "name": "UnmarkedAsDuplicateEvent" + }, + { + "name": "UnminimizeCommentInput" + }, + { + "name": "UnminimizeCommentPayload" + }, + { + "name": "UnpinIssueInput" + }, + { + "name": "UnpinIssuePayload" + }, + { + "name": "UnpinnedEvent" + }, + { + "name": "UnresolveReviewThreadInput" + }, + { + "name": "UnresolveReviewThreadPayload" + }, + { + "name": "UnsubscribedEvent" + }, + { + "name": "Updatable" + }, + { + "name": "UpdatableComment" + }, + { + "name": "UpdateBranchProtectionRuleInput" + }, + { + "name": "UpdateBranchProtectionRulePayload" + }, + { + "name": "UpdateCheckRunInput" + }, + { + "name": "UpdateCheckRunPayload" + }, + { + "name": "UpdateCheckSuitePreferencesInput" + }, + { + "name": "UpdateCheckSuitePreferencesPayload" + }, + { + "name": "UpdateDiscussionCommentInput" + }, + { + "name": "UpdateDiscussionCommentPayload" + }, + { + "name": "UpdateDiscussionInput" + }, + { + "name": "UpdateDiscussionPayload" + }, + { + "name": "UpdateEnterpriseAdministratorRoleInput" + }, + { + "name": "UpdateEnterpriseAdministratorRolePayload" + }, + { + "name": "UpdateEnterpriseAllowPrivateRepositoryForkingSettingInput" + }, + { + "name": "UpdateEnterpriseAllowPrivateRepositoryForkingSettingPayload" + }, + { + "name": "UpdateEnterpriseDefaultRepositoryPermissionSettingInput" + }, + { + "name": "UpdateEnterpriseDefaultRepositoryPermissionSettingPayload" + }, + { + "name": "UpdateEnterpriseDeployKeySettingInput" + }, + { + "name": "UpdateEnterpriseDeployKeySettingPayload" + }, + { + "name": "UpdateEnterpriseMembersCanChangeRepositoryVisibilitySettingInput" + }, + { + "name": "UpdateEnterpriseMembersCanChangeRepositoryVisibilitySettingPayload" + }, + { + "name": "UpdateEnterpriseMembersCanCreateRepositoriesSettingInput" + }, + { + "name": "UpdateEnterpriseMembersCanCreateRepositoriesSettingPayload" + }, + { + "name": "UpdateEnterpriseMembersCanDeleteIssuesSettingInput" + }, + { + "name": "UpdateEnterpriseMembersCanDeleteIssuesSettingPayload" + }, + { + "name": "UpdateEnterpriseMembersCanDeleteRepositoriesSettingInput" + }, + { + "name": "UpdateEnterpriseMembersCanDeleteRepositoriesSettingPayload" + }, + { + "name": "UpdateEnterpriseMembersCanInviteCollaboratorsSettingInput" + }, + { + "name": "UpdateEnterpriseMembersCanInviteCollaboratorsSettingPayload" + }, + { + "name": "UpdateEnterpriseMembersCanMakePurchasesSettingInput" + }, + { + "name": "UpdateEnterpriseMembersCanMakePurchasesSettingPayload" + }, + { + "name": "UpdateEnterpriseMembersCanUpdateProtectedBranchesSettingInput" + }, + { + "name": "UpdateEnterpriseMembersCanUpdateProtectedBranchesSettingPayload" + }, + { + "name": "UpdateEnterpriseMembersCanViewDependencyInsightsSettingInput" + }, + { + "name": "UpdateEnterpriseMembersCanViewDependencyInsightsSettingPayload" + }, + { + "name": "UpdateEnterpriseOrganizationProjectsSettingInput" + }, + { + "name": "UpdateEnterpriseOrganizationProjectsSettingPayload" + }, + { + "name": "UpdateEnterpriseOwnerOrganizationRoleInput" + }, + { + "name": "UpdateEnterpriseOwnerOrganizationRolePayload" + }, + { + "name": "UpdateEnterpriseProfileInput" + }, + { + "name": "UpdateEnterpriseProfilePayload" + }, + { + "name": "UpdateEnterpriseRepositoryProjectsSettingInput" + }, + { + "name": "UpdateEnterpriseRepositoryProjectsSettingPayload" + }, + { + "name": "UpdateEnterpriseTeamDiscussionsSettingInput" + }, + { + "name": "UpdateEnterpriseTeamDiscussionsSettingPayload" + }, + { + "name": "UpdateEnterpriseTwoFactorAuthenticationDisallowedMethodsSettingInput" + }, + { + "name": "UpdateEnterpriseTwoFactorAuthenticationDisallowedMethodsSettingPayload" + }, + { + "name": "UpdateEnterpriseTwoFactorAuthenticationRequiredSettingInput" + }, + { + "name": "UpdateEnterpriseTwoFactorAuthenticationRequiredSettingPayload" + }, + { + "name": "UpdateEnvironmentInput" + }, + { + "name": "UpdateEnvironmentPayload" + }, + { + "name": "UpdateIpAllowListEnabledSettingInput" + }, + { + "name": "UpdateIpAllowListEnabledSettingPayload" + }, + { + "name": "UpdateIpAllowListEntryInput" + }, + { + "name": "UpdateIpAllowListEntryPayload" + }, + { + "name": "UpdateIpAllowListForInstalledAppsEnabledSettingInput" + }, + { + "name": "UpdateIpAllowListForInstalledAppsEnabledSettingPayload" + }, + { + "name": "UpdateIssueCommentInput" + }, + { + "name": "UpdateIssueCommentPayload" + }, + { + "name": "UpdateIssueInput" + }, + { + "name": "UpdateIssuePayload" + }, + { + "name": "UpdateLabelInput" + }, + { + "name": "UpdateLabelPayload" + }, + { + "name": "UpdateNotificationRestrictionSettingInput" + }, + { + "name": "UpdateNotificationRestrictionSettingPayload" + }, + { + "name": "UpdateOrganizationAllowPrivateRepositoryForkingSettingInput" + }, + { + "name": "UpdateOrganizationAllowPrivateRepositoryForkingSettingPayload" + }, + { + "name": "UpdateOrganizationWebCommitSignoffSettingInput" + }, + { + "name": "UpdateOrganizationWebCommitSignoffSettingPayload" + }, + { + "name": "UpdateParameters" + }, + { + "name": "UpdateParametersInput" + }, + { + "name": "UpdatePatreonSponsorabilityInput" + }, + { + "name": "UpdatePatreonSponsorabilityPayload" + }, + { + "name": "UpdateProjectCardInput" + }, + { + "name": "UpdateProjectCardPayload" + }, + { + "name": "UpdateProjectColumnInput" + }, + { + "name": "UpdateProjectColumnPayload" + }, + { + "name": "UpdateProjectInput" + }, + { + "name": "UpdateProjectPayload" + }, + { + "name": "UpdateProjectV2CollaboratorsInput" + }, + { + "name": "UpdateProjectV2CollaboratorsPayload" + }, + { + "name": "UpdateProjectV2DraftIssueInput" + }, + { + "name": "UpdateProjectV2DraftIssuePayload" + }, + { + "name": "UpdateProjectV2FieldInput" + }, + { + "name": "UpdateProjectV2FieldPayload" + }, + { + "name": "UpdateProjectV2Input" + }, + { + "name": "UpdateProjectV2ItemFieldValueInput" + }, + { + "name": "UpdateProjectV2ItemFieldValuePayload" + }, + { + "name": "UpdateProjectV2ItemPositionInput" + }, + { + "name": "UpdateProjectV2ItemPositionPayload" + }, + { + "name": "UpdateProjectV2Payload" + }, + { + "name": "UpdateProjectV2StatusUpdateInput" + }, + { + "name": "UpdateProjectV2StatusUpdatePayload" + }, + { + "name": "UpdatePullRequestBranchInput" + }, + { + "name": "UpdatePullRequestBranchPayload" + }, + { + "name": "UpdatePullRequestInput" + }, + { + "name": "UpdatePullRequestPayload" + }, + { + "name": "UpdatePullRequestReviewCommentInput" + }, + { + "name": "UpdatePullRequestReviewCommentPayload" + }, + { + "name": "UpdatePullRequestReviewInput" + }, + { + "name": "UpdatePullRequestReviewPayload" + }, + { + "name": "UpdateRefInput" + }, + { + "name": "UpdateRefPayload" + }, + { + "name": "UpdateRefsInput" + }, + { + "name": "UpdateRefsPayload" + }, + { + "name": "UpdateRepositoryInput" + }, + { + "name": "UpdateRepositoryPayload" + }, + { + "name": "UpdateRepositoryRulesetInput" + }, + { + "name": "UpdateRepositoryRulesetPayload" + }, + { + "name": "UpdateRepositoryWebCommitSignoffSettingInput" + }, + { + "name": "UpdateRepositoryWebCommitSignoffSettingPayload" + }, + { + "name": "UpdateSponsorshipPreferencesInput" + }, + { + "name": "UpdateSponsorshipPreferencesPayload" + }, + { + "name": "UpdateSubscriptionInput" + }, + { + "name": "UpdateSubscriptionPayload" + }, + { + "name": "UpdateTeamDiscussionCommentInput" + }, + { + "name": "UpdateTeamDiscussionCommentPayload" + }, + { + "name": "UpdateTeamDiscussionInput" + }, + { + "name": "UpdateTeamDiscussionPayload" + }, + { + "name": "UpdateTeamReviewAssignmentInput" + }, + { + "name": "UpdateTeamReviewAssignmentPayload" + }, + { + "name": "UpdateTeamsRepositoryInput" + }, + { + "name": "UpdateTeamsRepositoryPayload" + }, + { + "name": "UpdateTopicsInput" + }, + { + "name": "UpdateTopicsPayload" + }, + { + "name": "UpdateUserListInput" + }, + { + "name": "UpdateUserListPayload" + }, + { + "name": "UpdateUserListsForItemInput" + }, + { + "name": "UpdateUserListsForItemPayload" + }, + { + "name": "User" + }, + { + "name": "UserBlockDuration" + }, + { + "name": "UserBlockedEvent" + }, + { + "name": "UserConnection" + }, + { + "name": "UserContentEdit" + }, + { + "name": "UserContentEditConnection" + }, + { + "name": "UserContentEditEdge" + }, + { + "name": "UserEdge" + }, + { + "name": "UserEmailMetadata" + }, + { + "name": "UserList" + }, + { + "name": "UserListConnection" + }, + { + "name": "UserListEdge" + }, + { + "name": "UserListItems" + }, + { + "name": "UserListItemsConnection" + }, + { + "name": "UserListItemsEdge" + }, + { + "name": "UserListSuggestion" + }, + { + "name": "UserStatus" + }, + { + "name": "UserStatusConnection" + }, + { + "name": "UserStatusEdge" + }, + { + "name": "UserStatusOrder" + }, + { + "name": "UserStatusOrderField" + }, + { + "name": "UserViewType" + }, + { + "name": "VerifiableDomain" + }, + { + "name": "VerifiableDomainConnection" + }, + { + "name": "VerifiableDomainEdge" + }, + { + "name": "VerifiableDomainOrder" + }, + { + "name": "VerifiableDomainOrderField" + }, + { + "name": "VerifiableDomainOwner" + }, + { + "name": "VerifyVerifiableDomainInput" + }, + { + "name": "VerifyVerifiableDomainPayload" + }, + { + "name": "ViewerHovercardContext" + }, + { + "name": "Votable" + }, + { + "name": "Workflow" + }, + { + "name": "WorkflowFileReference" + }, + { + "name": "WorkflowFileReferenceInput" + }, + { + "name": "WorkflowRun" + }, + { + "name": "WorkflowRunConnection" + }, + { + "name": "WorkflowRunEdge" + }, + { + "name": "WorkflowRunFile" + }, + { + "name": "WorkflowRunOrder" + }, + { + "name": "WorkflowRunOrderField" + }, + { + "name": "WorkflowState" + }, + { + "name": "WorkflowsParameters" + }, + { + "name": "WorkflowsParametersInput" + }, + { + "name": "X509Certificate" + }, + { + "name": "__Directive" + }, + { + "name": "__DirectiveLocation" + }, + { + "name": "__EnumValue" + }, + { + "name": "__Field" + }, + { + "name": "__InputValue" + }, + { + "name": "__Schema" + }, + { + "name": "__Type" + }, + { + "name": "__TypeKind" + } + ] + } +} \ No newline at end of file diff --git a/Examples/GetSchemaTypes.gql b/Examples/GetSchemaTypes.gql new file mode 100644 index 0000000..f7d0149 --- /dev/null +++ b/Examples/GetSchemaTypes.gql @@ -0,0 +1,16 @@ +query { + __schema { + types { + name + kind + description + fields { + name + type { + name + } + description + } + } + } +} diff --git a/Examples/GetTypeFields.gql b/Examples/GetTypeFields.gql new file mode 100644 index 0000000..09415bc --- /dev/null +++ b/Examples/GetTypeFields.gql @@ -0,0 +1,8 @@ +query getTypeField($typeName: String!){ + __type(name:$typeName) { + fields { + name + description + } + } +} diff --git a/Examples/GitDiscussion.gql b/Examples/GitDiscussion.gql new file mode 100644 index 0000000..459014d --- /dev/null +++ b/Examples/GitDiscussion.gql @@ -0,0 +1,52 @@ +query getDiscussions($owner: String !, $repo: String !, $number: Int !){ + repository(owner: $owner, name: $repo) { + discussion(number: $number) { + # type: Discussion + number + title + publishedAt + author { + login + url + } + editor { + login + url + } + body + bodyHTML + bodyText + category { + createdAt + name + emoji + emojiHTML + slug + updatedAt + } + closed + closedAt + createdAt + createdViaEmail + isAnswered + answerChosenBy { + login + url + } + locked + publishedAt + poll { + question + options(first: 10) { + nodes { + id + option + totalVoteCount + } + } + } + + url + } + } +} diff --git a/Examples/GitDiscussions.gql b/Examples/GitDiscussions.gql new file mode 100644 index 0000000..a9738b6 --- /dev/null +++ b/Examples/GitDiscussions.gql @@ -0,0 +1,24 @@ +query getDiscussions($owner: String !, $repo: String !, $first: Int = 100){ + repository(owner: $owner, name: $repo) { + discussions(first: $first) { + # type: DiscussionConnection + totalCount # Int! + edges { + # type: DiscussionEdge + cursor + node { + # type: Discussion + number + title + updatedAt + url + } + } + + nodes { + # type: Discussion + id + } + } + } +} diff --git a/Examples/GitGraphTypes.gql.ps1 b/Examples/GitGraphTypes.gql.ps1 new file mode 100644 index 0000000..43e966f --- /dev/null +++ b/Examples/GitGraphTypes.gql.ps1 @@ -0,0 +1,12 @@ +#requires -Module GQL +if (-not $env:ReadOnlyToken) { + Write-Warning "No ReadOnlyToken found." + return +} + +Push-Location $PSScriptRoot + +# First, let's get the query +gql -Query ./GetSchemaTypeNames.gql -PersonalAccessToken $env:ReadOnlyToken -Cache -OutputPath ./GetSchemaTypeNames.json + +Pop-Location \ No newline at end of file diff --git a/Examples/GitMyIssueTotals.gql b/Examples/GitMyIssueTotals.gql new file mode 100644 index 0000000..d25e889 --- /dev/null +++ b/Examples/GitMyIssueTotals.gql @@ -0,0 +1,13 @@ +query { + viewer { + issues { + totalCount + } + open: issues(states:OPEN) { + totalCount + } + closed: issues(states:CLOSED) { + totalCount + } + } +} diff --git a/Examples/GitMyPullRequestTotals.gql b/Examples/GitMyPullRequestTotals.gql new file mode 100644 index 0000000..aed4541 --- /dev/null +++ b/Examples/GitMyPullRequestTotals.gql @@ -0,0 +1,16 @@ +query { + viewer { + pullRequests { + totalCount + } + open: pullRequests(states:OPEN) { + totalCount + } + merged: pullRequests(states: MERGED) { + totalCount + } + closed: pullRequests(states:CLOSED) { + totalCount + } + } +} diff --git a/Examples/GitSponsors.gql b/Examples/GitSponsors.gql new file mode 100644 index 0000000..35a1745 --- /dev/null +++ b/Examples/GitSponsors.gql @@ -0,0 +1,28 @@ +query { + viewer { + ... on Sponsorable { + sponsors(first: 100) { + totalCount + nodes { + ... on User { + login + } + ... on Organization { + login + } + } + } + sponsoring(first: 100) { + totalCount + nodes { + ... on User { + login + } + ... on Organization { + login + } + } + } + } + } +} diff --git a/Examples/GitSponsorshipTiers.gql b/Examples/GitSponsorshipTiers.gql new file mode 100644 index 0000000..279a725 --- /dev/null +++ b/Examples/GitSponsorshipTiers.gql @@ -0,0 +1,19 @@ +query getTiers($login: String!) { + user(login: $login) { + sponsorsListing { + tiers(first: 10) { + nodes { + name + description + descriptionHTML + id + isCustomAmount + isOneTime + monthlyPriceInCents + monthlyPriceInDollars + updatedAt + } + } + } + } +} \ No newline at end of file diff --git a/GQL.ps.psm1 b/GQL.ps.psm1 new file mode 100644 index 0000000..562e155 --- /dev/null +++ b/GQL.ps.psm1 @@ -0,0 +1,26 @@ +$commandsPath = Join-Path $PSScriptRoot Commands +[include('*-*')]$commandsPath + +$myModule = $MyInvocation.MyCommand.ScriptBlock.Module +$ExecutionContext.SessionState.PSVariable.Set($myModule.Name, $myModule) +$myModule.pstypenames.insert(0, $myModule.Name) + +New-PSDrive -Name $MyModule.Name -PSProvider FileSystem -Scope Global -Root $PSScriptRoot -ErrorAction Ignore + +if ($home) { + $MyModuleProfileDirectory = Join-Path ([Environment]::GetFolderPath("LocalApplicationData")) $MyModule.Name + if (-not (Test-Path $MyModuleProfileDirectory)) { + $null = New-Item -ItemType Directory -Path $MyModuleProfileDirectory -Force + } + New-PSDrive -Name "My$($MyModule.Name)" -PSProvider FileSystem -Scope Global -Root $MyModuleProfileDirectory -ErrorAction Ignore +} + +# Set a script variable of this, set to the module +# (so all scripts in this scope default to the correct `$this`) +$script:this = $myModule + +#region Custom +#endregion Custom + +Export-ModuleMember -Alias * -Function * -Variable $myModule.Name + diff --git a/GQL.psd1 b/GQL.psd1 new file mode 100644 index 0000000..746ca7d --- /dev/null +++ b/GQL.psd1 @@ -0,0 +1,28 @@ +@{ + ModuleVersion = '0.1' + RootModule = 'GQL.psm1' + Guid = '9bf5c922-9f36-4c52-a7b6-d435837d4fa9' + Author = 'James Brundage' + CompanyName = 'Start-Automating' + Description = 'Get GraphQL in PowerShell' + Copyright = '2024 Start-Automating' + PrivateData = @{ + PSData = @{ + Tags = @('GraphQL','GraphAPI','GraphQueryLanguage','PowerShellWeb') + ProjectURI = 'https://github.com/PowerShellWeb/GQL' + LicenseURI = 'https://github.com/PowerShellWeb/GQL/blob/main/LICENSE' + ReleaseNotes = @' +## GQL 0.1 + +* Initial Release of GQL +* One Simple Command for GraphQL: `Get-GQL` (or `GQL`) +* Container and GitHub action included! + +--- + +> Like It? [Star It](https://github.com/PowerShellWeb/WebSocket) +> Love It? [Support It](https://github.com/sponsors/StartAutomating) +'@ + } + } +} diff --git a/GQL.psm1 b/GQL.psm1 new file mode 100644 index 0000000..41a1efb --- /dev/null +++ b/GQL.psm1 @@ -0,0 +1,36 @@ +$commandsPath = Join-Path $PSScriptRoot Commands +:ToIncludeFiles foreach ($file in (Get-ChildItem -Path "$commandsPath" -Filter "*-*" -Recurse)) { + if ($file.Extension -ne '.ps1') { continue } # Skip if the extension is not .ps1 + foreach ($exclusion in '\.[^\.]+\.ps1$') { + if (-not $exclusion) { continue } + if ($file.Name -match $exclusion) { + continue ToIncludeFiles # Skip excluded files + } + } + . $file.FullName +} + +$myModule = $MyInvocation.MyCommand.ScriptBlock.Module +$ExecutionContext.SessionState.PSVariable.Set($myModule.Name, $myModule) +$myModule.pstypenames.insert(0, $myModule.Name) + +New-PSDrive -Name $MyModule.Name -PSProvider FileSystem -Scope Global -Root $PSScriptRoot -ErrorAction Ignore + +if ($home) { + $MyModuleProfileDirectory = Join-Path ([Environment]::GetFolderPath("LocalApplicationData")) $MyModule.Name + if (-not (Test-Path $MyModuleProfileDirectory)) { + $null = New-Item -ItemType Directory -Path $MyModuleProfileDirectory -Force + } + New-PSDrive -Name "My$($MyModule.Name)" -PSProvider FileSystem -Scope Global -Root $MyModuleProfileDirectory -ErrorAction Ignore +} + +# Set a script variable of this, set to the module +# (so all scripts in this scope default to the correct `$this`) +$script:this = $myModule + +#region Custom +#endregion Custom + +Export-ModuleMember -Alias * -Function * -Variable $myModule.Name + + diff --git a/README.md b/README.md index f45ff11..561b8ac 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,52 @@ +

+ GQL Logo (Animated) +
+ # GQL -Get GraphQL in PowerShell + +Get Graph Query Language with PowerShell. + +GQL is a small PowerShell module for GraphQL. + +It is designed to provide a simple GraphQL client in PowerShell. + +We can use this as a direct client to GraphQL, without having to involve any other layer. + + +## GQL Container + +You can use the GQL module within a container: + +~~~powershell +docker pull ghcr.io/powershellweb/gql +docker run -it ghcr.io/powershellweb/gql +~~~ + +### Installing and Importing + +~~~PowerShell +Install-Module GQL -Scope CurrentUser -Force +Import-Module GQL -Force -PassThru +~~~ + +### Get-GQL + +To connect to a GQL and get results, use [Get-GQL](Get-GQL.md), or, simply `GQL`. + +(like all functions in PowerShell, it is case-insensitive) + +### More Examples + +#### Get-GQL Example 1 + +~~~powershell +# Getting git sponsorship information from GitHub GraphQL. +# **To use this example, we'll need to provide `$MyPat` with a Personal Access Token.** +Get-GQL -Query ./Examples/GitSponsors.gql -PersonalAccessToken $myPat +~~~ + #### Get-GQL Example 2 + +~~~powershell +# We can decorate graph object results to customize them. +~~~ + diff --git a/README.ps.md b/README.ps.md new file mode 100644 index 0000000..ae90b74 --- /dev/null +++ b/README.ps.md @@ -0,0 +1,56 @@ +
+ GQL Logo (Animated) +
+ +# GQL + +Get Graph Query Language with PowerShell. + +GQL is a small PowerShell module for GraphQL. + +It is designed to provide a simple GraphQL client in PowerShell. + +We can use this as a direct client to GraphQL, without having to involve any other layer. + + +## GQL Container + +You can use the GQL module within a container: + +~~~powershell +docker pull ghcr.io/powershellweb/gql +docker run -it ghcr.io/powershellweb/gql +~~~ + +### Installing and Importing + +~~~PowerShell +Install-Module GQL -Scope CurrentUser -Force +Import-Module GQL -Force -PassThru +~~~ + +### Get-GQL + +To connect to a GQL and get results, use [Get-GQL](Get-GQL.md), or, simply `GQL`. + +(like all functions in PowerShell, it is case-insensitive) + +### More Examples + +~~~PipeScript{ +Import-Module .\ +Get-Help Get-GQL | + %{ $_.Examples.Example.code} | + % -Begin { $exampleCount = 0 } -Process { + $exampleCount++ + @( + "#### Get-GQL Example $exampleCount" + '' + "~~~powershell" + $_ + "~~~" + '' + ) -join [Environment]::Newline + } +} +~~~ \ No newline at end of file diff --git a/action.yml b/action.yml new file mode 100644 index 0000000..f1bfbd1 --- /dev/null +++ b/action.yml @@ -0,0 +1,442 @@ + +name: GetGQL +description: Get GraphQL with PowerShell +inputs: + Run: + required: false + description: | + A PowerShell Script that uses GQL. + Any files outputted from the script will be added to the repository. + If those files have a .Message attached to them, they will be committed with that message. + SkipScriptFile: + required: false + description: 'If set, will not process any files named *.GQL.ps1' + InstallModule: + required: false + description: A list of modules to be installed from the PowerShell gallery before scripts run. + CommitMessage: + required: false + description: If provided, will commit any remaining changes made to the workspace with this commit message. + TargetBranch: + required: false + description: | + If provided, will checkout a new branch before making the changes. + If not provided, will use the current branch. + ActionScript: + required: false + description: The name of one or more scripts to run, from this action's path. + GitHubToken: + required: false + default: '{{ secrets.GITHUB_TOKEN }}' + description: The github token to use for requests. + UserEmail: + required: false + description: The user email associated with a git commit. If this is not provided, it will be set to the username@noreply.github.com. + UserName: + required: false + description: The user name associated with a git commit. + NoPush: + required: false + description: | + If set, will not push any changes made to the repository. + (they will still be committed unless `-NoCommit` is passed) + NoCommit: + required: false + description: | + If set, will not commit any changes made to the repository. + (this also implies `-NoPush`) +branding: + icon: chevron-right + color: blue +runs: + using: composite + steps: + - name: GQLAction + id: GQLAction + shell: pwsh + env: + Run: ${{inputs.Run}} + TargetBranch: ${{inputs.TargetBranch}} + CommitMessage: ${{inputs.CommitMessage}} + UserEmail: ${{inputs.UserEmail}} + ActionScript: ${{inputs.ActionScript}} + NoPush: ${{inputs.NoPush}} + NoCommit: ${{inputs.NoCommit}} + SkipScriptFile: ${{inputs.SkipScriptFile}} + UserName: ${{inputs.UserName}} + InstallModule: ${{inputs.InstallModule}} + GitHubToken: ${{inputs.GitHubToken}} + run: | + $Parameters = @{} + $Parameters.Run = ${env:Run} + $Parameters.SkipScriptFile = ${env:SkipScriptFile} + $Parameters.SkipScriptFile = $parameters.SkipScriptFile -match 'true'; + $Parameters.InstallModule = ${env:InstallModule} + $Parameters.InstallModule = $parameters.InstallModule -split ';' -replace '^[''"]' -replace '[''"]$' + $Parameters.CommitMessage = ${env:CommitMessage} + $Parameters.TargetBranch = ${env:TargetBranch} + $Parameters.ActionScript = ${env:ActionScript} + $Parameters.ActionScript = $parameters.ActionScript -split ';' -replace '^[''"]' -replace '[''"]$' + $Parameters.GitHubToken = ${env:GitHubToken} + $Parameters.UserEmail = ${env:UserEmail} + $Parameters.UserName = ${env:UserName} + $Parameters.NoPush = ${env:NoPush} + $Parameters.NoPush = $parameters.NoPush -match 'true'; + $Parameters.NoCommit = ${env:NoCommit} + $Parameters.NoCommit = $parameters.NoCommit -match 'true'; + foreach ($k in @($parameters.Keys)) { + if ([String]::IsNullOrEmpty($parameters[$k])) { + $parameters.Remove($k) + } + } + Write-Host "::debug:: GQLAction $(@(foreach ($p in $Parameters.GetEnumerator()) {'-' + $p.Key + ' ' + $p.Value}) -join ' ')" + & {<# + .Synopsis + GitHub Action for GQL + .Description + GitHub Action for GQL. This will: + + * Import GQL + * If `-Run` is provided, run that script + * Otherwise, unless `-SkipScriptFile` is passed, run all *.GQL.ps1 files beneath the workflow directory + * If any `-ActionScript` was provided, run scripts from the action path that match a wildcard pattern. + + If you will be making changes using the GitHubAPI, you should provide a -GitHubToken + If none is provided, and ENV:GITHUB_TOKEN is set, this will be used instead. + Any files changed can be outputted by the script, and those changes can be checked back into the repo. + Make sure to use the "persistCredentials" option with checkout. + #> + + param( + # A PowerShell Script that uses GQL. + # Any files outputted from the script will be added to the repository. + # If those files have a .Message attached to them, they will be committed with that message. + [string] + $Run, + + # If set, will not process any files named *.GQL.ps1 + [switch] + $SkipScriptFile, + + # A list of modules to be installed from the PowerShell gallery before scripts run. + [string[]] + $InstallModule, + + # If provided, will commit any remaining changes made to the workspace with this commit message. + [string] + $CommitMessage, + + # If provided, will checkout a new branch before making the changes. + # If not provided, will use the current branch. + [string] + $TargetBranch, + + # The name of one or more scripts to run, from this action's path. + [string[]] + $ActionScript, + + # The github token to use for requests. + [string] + $GitHubToken = '{{ secrets.GITHUB_TOKEN }}', + + # The user email associated with a git commit. If this is not provided, it will be set to the username@noreply.github.com. + [string] + $UserEmail, + + # The user name associated with a git commit. + [string] + $UserName, + + # If set, will not push any changes made to the repository. + # (they will still be committed unless `-NoCommit` is passed) + [switch] + $NoPush, + + # If set, will not commit any changes made to the repository. + # (this also implies `-NoPush`) + [switch] + $NoCommit + ) + + $ErrorActionPreference = 'continue' + "::group::Parameters" | Out-Host + [PSCustomObject]$PSBoundParameters | Format-List | Out-Host + "::endgroup::" | Out-Host + + $gitHubEventJson = [IO.File]::ReadAllText($env:GITHUB_EVENT_PATH) + $gitHubEvent = + if ($env:GITHUB_EVENT_PATH) { + $gitHubEventJson | ConvertFrom-Json + } else { $null } + "::group::Parameters" | Out-Host + $gitHubEvent | Format-List | Out-Host + "::endgroup::" | Out-Host + + + $anyFilesChanged = $false + $ActionModuleName = 'GQL' + $actorInfo = $null + + + $checkDetached = git symbolic-ref -q HEAD + if ($LASTEXITCODE) { + "::warning::On detached head, skipping action" | Out-Host + exit 0 + } + + function InstallActionModule { + param([string]$ModuleToInstall) + $moduleInWorkspace = Get-ChildItem -Path $env:GITHUB_WORKSPACE -Recurse -File | + Where-Object Name -eq "$($moduleToInstall).psd1" | + Where-Object { + $(Get-Content $_.FullName -Raw) -match 'ModuleVersion' + } + if (-not $moduleInWorkspace) { + $availableModules = Get-Module -ListAvailable + if ($availableModules.Name -notcontains $moduleToInstall) { + Install-Module $moduleToInstall -Scope CurrentUser -Force -AcceptLicense -AllowClobber + } + Import-Module $moduleToInstall -Force -PassThru | Out-Host + } else { + Import-Module $moduleInWorkspace.FullName -Force -PassThru | Out-Host + } + } + function ImportActionModule { + #region -InstallModule + if ($InstallModule) { + "::group::Installing Modules" | Out-Host + foreach ($moduleToInstall in $InstallModule) { + InstallActionModule -ModuleToInstall $moduleToInstall + } + "::endgroup::" | Out-Host + } + #endregion -InstallModule + + if ($env:GITHUB_ACTION_PATH) { + $LocalModulePath = Join-Path $env:GITHUB_ACTION_PATH "$ActionModuleName.psd1" + if (Test-path $LocalModulePath) { + Import-Module $LocalModulePath -Force -PassThru | Out-String + } else { + throw "Module '$ActionModuleName' not found" + } + } elseif (-not (Get-Module $ActionModuleName)) { + throw "Module '$ActionModuleName' not found" + } + + "::notice title=ModuleLoaded::$ActionModuleName Loaded from Path - $($LocalModulePath)" | Out-Host + if ($env:GITHUB_STEP_SUMMARY) { + "# $($ActionModuleName)" | + Out-File -Append -FilePath $env:GITHUB_STEP_SUMMARY + } + } + function InitializeAction { + #region Custom + #endregion Custom + + # Configure git based on the $env:GITHUB_ACTOR + if (-not $UserName) { $UserName = $env:GITHUB_ACTOR } + if (-not $actorID) { $actorID = $env:GITHUB_ACTOR_ID } + $actorInfo = + if ($GitHubToken -notmatch '^\{{2}' -and $GitHubToken -notmatch '\}{2}$') { + Invoke-RestMethod -Uri "https://api.github.com/user/$actorID" -Headers @{ Authorization = "token $GitHubToken" } + } else { + Invoke-RestMethod -Uri "https://api.github.com/user/$actorID" + } + + if (-not $UserEmail) { $UserEmail = "$UserName@noreply.github.com" } + git config --global user.email $UserEmail + git config --global user.name $actorInfo.name + + # Pull down any changes + git pull | Out-Host + + if ($TargetBranch) { + "::notice title=Expanding target branch string $targetBranch" | Out-Host + $TargetBranch = $ExecutionContext.SessionState.InvokeCommand.ExpandString($TargetBranch) + "::notice title=Checking out target branch::$targetBranch" | Out-Host + git checkout -b $TargetBranch | Out-Host + git pull | Out-Host + } + } + + function InvokeActionModule { + $myScriptStart = [DateTime]::Now + $myScript = $ExecutionContext.SessionState.PSVariable.Get("Run").Value + if ($myScript) { + Invoke-Expression -Command $myScript | + . ProcessOutput | + Out-Host + return + } + $myScriptTook = [Datetime]::Now - $myScriptStart + $MyScriptFilesStart = [DateTime]::Now + + $myScriptList = @() + $shouldSkip = $ExecutionContext.SessionState.PSVariable.Get("SkipScriptFile").Value + if ($shouldSkip) { + return + } + $scriptFiles = @( + Get-ChildItem -Recurse -Path $env:GITHUB_WORKSPACE | + Where-Object Name -Match "\.$($ActionModuleName)\.ps1$" + if ($ActionScript) { + if ($ActionScript -match '^\s{0,}/' -and $ActionScript -match '/\s{0,}$') { + $ActionScriptPattern = $ActionScript.Trim('/').Trim() -as [regex] + if ($ActionScriptPattern) { + $ActionScriptPattern = [regex]::new($ActionScript.Trim('/').Trim(), 'IgnoreCase,IgnorePatternWhitespace', [timespan]::FromSeconds(0.5)) + Get-ChildItem -Recurse -Path $env:GITHUB_ACTION_PATH | + Where-Object { $_.Name -Match "\.$($ActionModuleName)\.ps1$" -and $_.FullName -match $ActionScriptPattern } + } + } else { + Get-ChildItem -Recurse -Path $env:GITHUB_ACTION_PATH | + Where-Object Name -Match "\.$($ActionModuleName)\.ps1$" | + Where-Object FullName -Like $ActionScript + } + } + ) | Select-Object -Unique + $scriptFiles | + ForEach-Object -Begin { + if ($env:GITHUB_STEP_SUMMARY) { + "## $ActionModuleName Scripts" | + Out-File -Append -FilePath $env:GITHUB_STEP_SUMMARY + } + } -Process { + $myScriptList += $_.FullName.Replace($env:GITHUB_WORKSPACE, '').TrimStart('/') + $myScriptCount++ + $scriptFile = $_ + if ($env:GITHUB_STEP_SUMMARY) { + "### $($scriptFile.Fullname -replace [Regex]::Escape($env:GITHUB_WORKSPACE))" | + Out-File -Append -FilePath $env:GITHUB_STEP_SUMMARY + } + $scriptCmd = $ExecutionContext.SessionState.InvokeCommand.GetCommand($scriptFile.FullName, 'ExternalScript') + foreach ($requiredModule in $CommandInfo.ScriptBlock.Ast.ScriptRequirements.RequiredModules) { + if ($requiredModule.Name -and + (-not $requiredModule.MaximumVersion) -and + (-not $requiredModule.RequiredVersion) + ) { + InstallActionModule $requiredModule.Name + } + } + $scriptFileOutputs = . $scriptCmd + $scriptFileOutputs | + . ProcessOutput | + Out-Host + } + + $MyScriptFilesTook = [Datetime]::Now - $MyScriptFilesStart + $SummaryOfMyScripts = "$myScriptCount $ActionModuleName scripts took $($MyScriptFilesTook.TotalSeconds) seconds" + $SummaryOfMyScripts | + Out-Host + if ($env:GITHUB_STEP_SUMMARY) { + $SummaryOfMyScripts | + Out-File -Append -FilePath $env:GITHUB_STEP_SUMMARY + } + #region Custom + #endregion Custom + } + + function OutError { + $anyRuntimeExceptions = $false + foreach ($err in $error) { + $errParts = @( + "::error " + @( + if ($err.InvocationInfo.ScriptName) { + "file=$($err.InvocationInfo.ScriptName)" + } + if ($err.InvocationInfo.ScriptLineNumber -ge 1) { + "line=$($err.InvocationInfo.ScriptLineNumber)" + if ($err.InvocationInfo.OffsetInLine -ge 1) { + "col=$($err.InvocationInfo.OffsetInLine)" + } + } + if ($err.CategoryInfo.Activity) { + "title=$($err.CategoryInfo.Activity)" + } + ) -join ',' + "::" + $err.Exception.Message + if ($err.CategoryInfo.Category -eq 'OperationStopped' -and + $err.CategoryInfo.Reason -eq 'RuntimeException') { + $anyRuntimeExceptions = $true + } + ) -join '' + $errParts | Out-Host + if ($anyRuntimeExceptions) { + exit 1 + } + } + } + + function PushActionOutput { + if ($anyFilesChanged) { + "::notice::$($anyFilesChanged) Files Changed" | Out-Host + } + if ($CommitMessage -or $anyFilesChanged) { + if ($CommitMessage) { + Get-ChildItem $env:GITHUB_WORKSPACE -Recurse | + ForEach-Object { + $gitStatusOutput = git status $_.Fullname -s + if ($gitStatusOutput) { + git add $_.Fullname + } + } + + git commit -m $ExecutionContext.SessionState.InvokeCommand.ExpandString($CommitMessage) + } + + $checkDetached = git symbolic-ref -q HEAD + if (-not $LASTEXITCODE -and -not $NoPush -and -not $noCommit) { + if ($TargetBranch -and $anyFilesChanged) { + "::notice::Pushing Changes to $targetBranch" | Out-Host + git push --set-upstream origin $TargetBranch + } elseif ($anyFilesChanged) { + "::notice::Pushing Changes" | Out-Host + git push + } + "Git Push Output: $($gitPushed | Out-String)" + } else { + "::notice::Not pushing changes (on detached head)" | Out-Host + $LASTEXITCODE = 0 + exit 0 + } + } + } + + filter ProcessOutput { + $out = $_ + $outItem = Get-Item -Path $out -ErrorAction Ignore + if (-not $outItem -and $out -is [string]) { + $out | Out-Host + if ($env:GITHUB_STEP_SUMMARY) { + "> $out" | Out-File -Append -FilePath $env:GITHUB_STEP_SUMMARY + } + return + } + $fullName, $shouldCommit = + if ($out -is [IO.FileInfo]) { + $out.FullName, (git status $out.Fullname -s) + } elseif ($outItem) { + $outItem.FullName, (git status $outItem.Fullname -s) + } + if ($shouldCommit -and -not $NoCommit) { + "$fullName has changed, and should be committed" | Out-Host + git add $fullName + if ($out.Message) { + git commit -m "$($out.Message)" | Out-Host + } elseif ($out.CommitMessage) { + git commit -m "$($out.CommitMessage)" | Out-Host + } elseif ($gitHubEvent.head_commit.message) { + git commit -m "$($gitHubEvent.head_commit.message)" | Out-Host + } + $anyFilesChanged = $true + } + $out + } + + . ImportActionModule + . InitializeAction + . InvokeActionModule + . PushActionOutput + . OutError} @Parameters + diff --git a/docs/Assets/GQL-Animated.svg b/docs/Assets/GQL-Animated.svg new file mode 100644 index 0000000..fa52af2 --- /dev/null +++ b/docs/Assets/GQL-Animated.svg @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + GQL + diff --git a/docs/Assets/GQL.svg b/docs/Assets/GQL.svg new file mode 100644 index 0000000..34dbfb3 --- /dev/null +++ b/docs/Assets/GQL.svg @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + + GQL + diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md new file mode 100644 index 0000000..057389e --- /dev/null +++ b/docs/CHANGELOG.md @@ -0,0 +1,10 @@ +## GQL 0.1 + +* Initial Release of GQL +* One Simple Command for GraphQL: `Get-GQL` (or `GQL`) +* Container and GitHub action included! + +--- + +> Like It? [Star It](https://github.com/PowerShellWeb/WebSocket) +> Love It? [Support It](https://github.com/sponsors/StartAutomating) diff --git a/docs/CODE_OF_CONDUCT.md b/docs/CODE_OF_CONDUCT.md new file mode 100644 index 0000000..a132093 --- /dev/null +++ b/docs/CODE_OF_CONDUCT.md @@ -0,0 +1,9 @@ +# Code of Conduct + +We have a simple subjective code of conduct: + +1. Be Respectful +2. Be Helpful +3. Do No Harm + +Failure to follow the code of conduct may result in blocks or banishment. diff --git a/docs/CONTRIBUTING.md b/docs/CONTRIBUTING.md new file mode 100644 index 0000000..9a5c057 --- /dev/null +++ b/docs/CONTRIBUTING.md @@ -0,0 +1,7 @@ +# Contibuting + +We welcome suggestions and careful contributions. + +To suggest something, please [open an issue](https://github.com/PowerShellWeb/GQL/issues) or start a [discussion](https://github.com/PowerShellWeb/GQL/discussion) + +To add a feature, please open an issue and create a pull request. diff --git a/docs/Get-GQL.md b/docs/Get-GQL.md new file mode 100644 index 0000000..e87e91d --- /dev/null +++ b/docs/Get-GQL.md @@ -0,0 +1,130 @@ +Get-GQL +------- + +### Synopsis +Gets a GraphQL query. + +--- + +### Description + +Gets a GraphQL query and returns the results as a PowerShell object. + +--- + +### Examples +Getting git sponsorship information from GitHub GraphQL. +**To use this example, we'll need to provide `$MyPat` with a Personal Access Token.** + +```PowerShell +Get-GQL -Query ./Examples/GitSponsors.gql -PersonalAccessToken $myPat +``` +We can decorate graph object results to customize them. +Let's add a Sponsors property to the output object that returns the sponsor nodes. + +```PowerShell +Update-TypeData -TypeName 'GitSponsors' -MemberName 'Sponsors' -MemberType ScriptProperty -Value { + $this.viewer.sponsors.nodes +} -Force + +# And let's add a Sponsoring property to the output object that returns the sponsoring nodes. +Update-TypeData -TypeName 'GitSponsors' -MemberName 'Sponsoring' -MemberType ScriptProperty -Value { + $this.viewer.sponsoring.nodes +} -Force + +# And let's display sponsoring and sponsors by default +Update-TypeData -TypeName 'GitSponsors' -DefaultDisplayPropertySet 'Sponsors','Sponsoring' -Force + +# Now we can run the query and get the results. +Get-GQL -Query ./Examples/GitSponsors.gql -PersonalAccessToken $myPat -PSTypeName 'GitSponsors' | + Select-Object -Property Sponsors,Sponsoring +``` + +--- + +### Parameters +#### **Query** +One or more queries to run. + +|Type |Required|Position|PipelineInput |Aliases | +|------------|--------|--------|---------------------|--------| +|`[String[]]`|false |1 |true (ByPropertyName)|FullName| + +#### **PersonalAccessToken** +The Personal Access Token to use for the query. + +|Type |Required|Position|PipelineInput |Aliases | +|----------|--------|--------|---------------------|-----------------------------| +|`[String]`|false |2 |true (ByPropertyName)|Token
PAT
AccessToken| + +#### **GraphQLUri** +The GraphQL endpoint to query. + +|Type |Required|Position|PipelineInput |Aliases| +|-------|--------|--------|---------------------|-------| +|`[Uri]`|false |3 |true (ByPropertyName)|uri | + +#### **Parameter** +Any variables or parameters to provide to the query. + +|Type |Required|Position|PipelineInput |Aliases | +|---------------|--------|--------|---------------------|-------------------------------------| +|`[IDictionary]`|false |4 |true (ByPropertyName)|Parameters
Variable
Variables| + +#### **Header** +Any additional headers to include in the request + +|Type |Required|Position|PipelineInput|Aliases| +|---------------|--------|--------|-------------|-------| +|`[IDictionary]`|false |5 |false |Headers| + +#### **PSTypeName** +Adds PSTypeName(s) to use for the output object, making it a decorated object. +By decorating an object with one or more typenames, we can: +* Add additional properties and methods to the object +* Format the output object any way we want + +|Type |Required|Position|PipelineInput|Aliases | +|------------|--------|--------|-------------|---------------------------------------------------------------------------| +|`[String[]]`|false |6 |false |Decorate
Decoration
PSTypeNames
TypeName
TypeNames
Type| + +#### **Cache** +If set, will cache the results of the query. +This can be useful for queries that would be run frequently, but change infrequently. + +|Type |Required|Position|PipelineInput | +|----------|--------|--------|---------------------| +|`[Switch]`|false |named |true (ByPropertyName)| + +#### **Refresh** +If set, will refresh the cache. +This can be useful to force an update of cached information. +`-Refresh` implies `-Cache` (it just will not return an uncached value). + +|Type |Required|Position|PipelineInput | +|----------|--------|--------|---------------------| +|`[Switch]`|false |named |true (ByPropertyName)| + +#### **OutputPath** + +|Type |Required|Position|PipelineInput | +|------------|--------|--------|---------------------| +|`[String[]]`|false |7 |true (ByPropertyName)| + +#### **WhatIf** +-WhatIf is an automatic variable that is created when a command has ```[CmdletBinding(SupportsShouldProcess)]```. +-WhatIf is used to see what would happen, or return operations without executing them +#### **Confirm** +-Confirm is an automatic variable that is created when a command has ```[CmdletBinding(SupportsShouldProcess)]```. +-Confirm is used to -Confirm each operation. + +If you pass ```-Confirm:$false``` you will not be prompted. + +If the command sets a ```[ConfirmImpact("Medium")]``` which is lower than ```$confirmImpactPreference```, you will not be prompted unless -Confirm is passed. + +--- + +### Syntax +```PowerShell +Get-GQL [[-Query] ] [[-PersonalAccessToken] ] [[-GraphQLUri] ] [[-Parameter] ] [[-Header] ] [[-PSTypeName] ] [-Cache] [-Refresh] [[-OutputPath] ] [-WhatIf] [-Confirm] [] +``` diff --git a/docs/README.md b/docs/README.md new file mode 100644 index 0000000..5989d74 --- /dev/null +++ b/docs/README.md @@ -0,0 +1,51 @@ +
+ GQL Logo (Animated) +
+ +# GQL + +Get Graph Query Language with PowerShell. + +GQL is a small PowerShell module for GraphQL. + +It is designed to provide a simple GraphQL client in PowerShell. + +We can use this as a direct client to GraphQL, without having to involve any other layer. + + +## GQL Container + +You can use the GQL module within a container: + +~~~powershell +docker pull ghcr.io/powershellweb/gql +docker run -it ghcr.io/powershellweb/gql +~~~ + +### Installing and Importing + +~~~PowerShell +Install-Module GQL -Scope CurrentUser -Force +Import-Module GQL -Force -PassThru +~~~ + +### Get-GQL + +To connect to a GQL and get results, use [Get-GQL](Get-GQL.md), or, simply `GQL`. + +(like all functions in PowerShell, it is case-insensitive) + +### More Examples + +#### Get-GQL Example 1 + +~~~powershell +# Getting git sponsorship information from GitHub GraphQL. +# **To use this example, we'll need to provide `$MyPat` with a Personal Access Token.** +Get-GQL -Query ./Examples/GitSponsors.gql -PersonalAccessToken $myPat +~~~ + #### Get-GQL Example 2 + +~~~powershell +# We can decorate graph object results to customize them. +~~~ diff --git a/docs/_data/Help/Get-GQL.json b/docs/_data/Help/Get-GQL.json new file mode 100644 index 0000000..876754a --- /dev/null +++ b/docs/_data/Help/Get-GQL.json @@ -0,0 +1,44 @@ +{ + "Synopsis": "Gets a GraphQL query.", + "Description": "Gets a GraphQL query and returns the results as a PowerShell object.", + "Parameters": [ + { + "Name": null, + "Type": null, + "Description": "", + "Required": false, + "Position": 0, + "Aliases": null, + "DefaultValue": null, + "Globbing": false, + "PipelineInput": null, + "variableLength": false + } + ], + "Notes": [ + null + ], + "CommandType": "Function", + "Component": [ + null + ], + "Inputs": [ + null + ], + "Outputs": [ + null + ], + "Links": [], + "Examples": [ + { + "Title": "EXAMPLE 1", + "Markdown": "Getting git sponsorship information from GitHub GraphQL.\n**To use this example, we'll need to provide `$MyPat` with a Personal Access Token.** ", + "Code": "Get-GQL -Query ./Examples/GitSponsors.gql -PersonalAccessToken $myPat" + }, + { + "Title": "EXAMPLE 2", + "Markdown": "We can decorate graph object results to customize them.\nLet's add a Sponsors property to the output object that returns the sponsor nodes.", + "Code": "Update-TypeData -TypeName 'GitSponsors' -MemberName 'Sponsors' -MemberType ScriptProperty -Value {\n $this.viewer.sponsors.nodes\n} -Force\n\n# And let's add a Sponsoring property to the output object that returns the sponsoring nodes.\nUpdate-TypeData -TypeName 'GitSponsors' -MemberName 'Sponsoring' -MemberType ScriptProperty -Value {\n $this.viewer.sponsoring.nodes\n} -Force\n\n# And let's display sponsoring and sponsors by default\nUpdate-TypeData -TypeName 'GitSponsors' -DefaultDisplayPropertySet 'Sponsors','Sponsoring' -Force\n\n# Now we can run the query and get the results.\nGet-GQL -Query ./Examples/GitSponsors.gql -PersonalAccessToken $myPat -PSTypeName 'GitSponsors' | \n Select-Object -Property Sponsors,Sponsoring" + } + ] +} \ No newline at end of file