Show-GraphQLVoyager.ps1
<#PSScriptInfo
.VERSION 0.0.3 .AUTHOR Roman Kuzmin .COPYRIGHT (c) Roman Kuzmin .TAGS GraphQL Voyager .GUID 9308d778-bfa3-4301-9ef8-db273bda2357 .LICENSEURI http://www.apache.org/licenses/LICENSE-2.0 .PROJECTURI https://github.com/nightroman/PowerShelf #> <# .Synopsis Shows GraphQL schema using https://github.com/graphql-kit/graphql-voyager .Description This command generates and opens HTML which renders GraphQL Voyager with the specified GraphQL API URL and several display options. The GraphQL Voyager .css and .js files are downloaded once to the cache. Remove them in order to get the latest versions. The cache directory: $HOME/.PowerShelf/Show-GraphQLVoyager .Parameter ApiUrl Specifies the GraphQL API URL for introspection. .Parameter RootType The root type name. Default: Query .Parameter Output The output HTML file. The default is in the temp directory. .Parameter HideDocs Tells to hide the docs sidebar. .Parameter HideLeafFields Tells to hide all scalars and enums. .Parameter HideSettings Tells to hide the settings panel. .Parameter HideRoot Tells to hide the root type. .Parameter ShowDeprecated Tells to show deprecated entities. .Parameter ShowRelay Tells to show relay related types as is. .Parameter SortByAlphabet Tells to sort fields on graph by alphabet. .Link https://github.com/nightroman/PowerShelf #> [CmdletBinding()] param( [Parameter(Position=0, Mandatory=1)] [Uri]$ApiUrl , [Parameter(Position=1)] [string]$RootType = 'Query' , [string]$Output , [switch]$HideDocs , [switch]$HideLeafFields , [switch]$HideSettings , [switch]$HideRoot , [switch]$ShowDeprecated , [switch]$ShowRelay , [switch]$SortByAlphabet ) $ErrorActionPreference = 1 $ProgressPreference = 0 if ($RootType -notmatch '^\w+$') { Write-Error "Invalid parameter RootType: $RootType" } ### resolve output if ($Output) { $Output = $PSCmdlet.GetUnresolvedProviderPathFromPSPath($Output) } else { $Output = [System.IO.Path]::GetTempPath() + "GraphQLVoyager-$RootType.html" } ### cache resources $cache = "$HOME/.PowerShelf/Show-GraphQLVoyager" $null = mkdir $cache -Force $css = "$cache/voyager.css" if (![System.IO.File]::Exists($css)) { Write-Host "Downloading $css" Invoke-WebRequest -Uri https://cdn.jsdelivr.net/npm/graphql-voyager/dist/voyager.css -OutFile $css } $js = "$cache/voyager.standalone.js" if (![System.IO.File]::Exists($js)) { Write-Host "Downloading $js" Invoke-WebRequest -Uri https://cdn.jsdelivr.net/npm/graphql-voyager/dist/voyager.standalone.js -OutFile $js } ### make HTML function Get-FileUrl([string]$Path) { 'file:///' + $Path.Replace('\', '/') } function Get-Boolean($Value) { if ($Value) {'true'} else {'false'} } $html = @" <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>$RootType $ApiUrl</title> <style> body { height: 100%; margin: 0; width: 100%; overflow: hidden; } #voyager { height: 100vh; } </style> <link rel="stylesheet" href="$(Get-FileUrl $css)"> <script src="$(Get-FileUrl $js)"></script> </head> <body> <div id="voyager">Loading...</div> <script type="module"> const { voyagerIntrospectionQuery: query } = GraphQLVoyager; const response = await fetch( '$ApiUrl', { method: 'post', headers: { Accept: 'application/json', 'Content-Type': 'application/json', }, body: JSON.stringify({ query }), credentials: 'omit', }, ); const introspection = await response.json(); GraphQLVoyager.renderVoyager(document.getElementById('voyager'), { introspection, hideDocs: $(Get-Boolean $HideDocs), hideSettings: $(Get-Boolean $HideSettings), displayOptions: { rootType: "$RootType", hideRoot: $(Get-Boolean $HideRoot), showLeafFields: $(Get-Boolean (!$HideLeafFields)), skipDeprecated: $(Get-Boolean (!$ShowDeprecated)), skipRelay: $(Get-Boolean (!$ShowRelay)), sortByAlphabet: $(Get-Boolean $SortByAlphabet) }, }); </script> </body> </html> "@ ### save and open HTML [System.IO.File]::WriteAllText($Output, $html) Invoke-Item -LiteralPath $Output |