diff --git a/.github/workflows/BuildWebSocket.yml b/.github/workflows/BuildWebSocket.yml new file mode 100644 index 0000000..2f67fd1 --- /dev/null +++ b/.github/workflows/BuildWebSocket.yml @@ -0,0 +1,552 @@ + +name: Build WebSocket Module +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 + BuildWebSocket: + 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: Use PSJekyll Action + uses: PowerShellWeb/PSJekyll@main + id: PSJekyll + - 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 }} +env: + REGISTRY: ghcr.io + IMAGE_NAME: ${{ github.repository }} diff --git a/Assets/WebSocket-Animated.svg b/Assets/WebSocket-Animated.svg new file mode 100644 index 0000000..3542af9 --- /dev/null +++ b/Assets/WebSocket-Animated.svg @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + || + || + WebSocket + diff --git a/Assets/WebSocket.svg b/Assets/WebSocket.svg new file mode 100644 index 0000000..6974911 --- /dev/null +++ b/Assets/WebSocket.svg @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + || + || + WebSocket + diff --git a/Build/GitHub/Jobs/BuildWebSocket.psd1 b/Build/GitHub/Jobs/BuildWebSocket.psd1 new file mode 100644 index 0000000..fa581af --- /dev/null +++ b/Build/GitHub/Jobs/BuildWebSocket.psd1 @@ -0,0 +1,39 @@ +@{ + "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 = 'Use PSJekyll Action' + uses = 'PowerShellWeb/PSJekyll@main' + id = 'PSJekyll' + }, + <#@{ + name = 'Run WebSocket (on branch)' + if = '${{github.ref_name != ''main''}}' + uses = './' + id = 'WebSocketAction' + },#> + '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/WebSocket.GitHubWorkflow.PSDevOps.ps1 b/Build/WebSocket.GitHubWorkflow.PSDevOps.ps1 new file mode 100644 index 0000000..b6303d7 --- /dev/null +++ b/Build/WebSocket.GitHubWorkflow.PSDevOps.ps1 @@ -0,0 +1,15 @@ +#requires -Module PSDevOps +Import-BuildStep -SourcePath ( + Join-Path $PSScriptRoot 'GitHub' +) -BuildSystem GitHubWorkflow + +Push-Location ($PSScriptRoot | Split-Path) +New-GitHubWorkflow -Name "Build WebSocket Module" -On Push, + PullRequest, + Demand -Job TestPowerShellOnLinux, + TagReleaseAndPublish, BuildWebSocket -Environment ([Ordered]@{ + REGISTRY = 'ghcr.io' + IMAGE_NAME = '${{ github.repository }}' + }) -OutputPath .\.github\workflows\BuildWebSocket.yml + +Pop-Location \ No newline at end of file diff --git a/Build/WebSocket.HelpOut.ps1 b/Build/WebSocket.HelpOut.ps1 new file mode 100644 index 0000000..34be7dc --- /dev/null +++ b/Build/WebSocket.HelpOut.ps1 @@ -0,0 +1,14 @@ +#requires -Module HelpOut + +#region Load the Module +$ModuleName = 'WebSocket' +Push-Location ($PSScriptRoot | Split-Path) +if (-not (Get-Module $ModuleName)) { + Import-Module .\ -Global -PassThru | Out-Host +} +#endregion Load the Module + +# This will save the MarkdownHelp to the docs folder, and output all of the files created. +Save-MarkdownHelp -PassThru -Module $ModuleName -ExcludeCommandType Alias + +Pop-Location \ No newline at end of file diff --git a/Build/WebSocket.PSJekyll.ps1 b/Build/WebSocket.PSJekyll.ps1 new file mode 100644 index 0000000..6131344 --- /dev/null +++ b/Build/WebSocket.PSJekyll.ps1 @@ -0,0 +1,119 @@ +$sitePath = Join-Path ($PSScriptRoot | Split-Path) 'docs' + +$sourceModule = Get-Module PSJekyll +if (-not $sourceModule) { + $sourceModule = Import-Module ($PSScriptRoot | Split-Path) -PassThru +} + + +Push-Location $sitePath +$PSJekyll.CurrentSite.Domain = "websocket.powershellweb.com" +$PSJekyll.CurrentSite.Data = @{LastDateBuilt = [datetime]::UtcNow.Date.ToString('yyyy-MM-dd')} +$PSJekyll.CurrentSite.Data = @{ + "PSModule/Info" = $sourceModule | + Select-Object -Property Name, + Version, + Description, + Copyright, + CompanyName, + Author, + @{ + Name = 'Tags' + Expression = { @($_.PrivateData.PSData.Tags | Select-Object -Unique)} + } + "PSModule/Exports" = @( + foreach ($command in $sourceModule.ExportedCommands.Values) { + [Ordered]@{ + Name = $command.Name + CommandType = $command.CommandType + Definition = $command.Definition + ParameterName = $command.Parameters.Keys + Parameter = @( + $command.Parameters.Values | + Select-Object -Property Name, + @{ + Name='ParameterType' + Expression = { $_.ParameterType.ToString() } + }, + Position, + Mandatory, + ValueFromPipeline, + ValueFromPipelineByPropertyName, + ValueFromRemainingArguments, + HelpMessage + ) + } + } + ) + + "PSModule/FunctionNames" = $sourceModule.ExportedFunctions.Keys + "PSModule/CmdletNames" = $sourceModule.ExportedCmdlets.Keys + "PSModule/AliasNames" = $sourceModule.ExportedAliases.Keys + "PSModule/Aliases" = @($sourceModule.ExportedAliases.Values | + ForEach-Object { [Ordered]@{Name=$_.Name;Definition=$_.Definition} }) + + "PSModule/VariableNames" = $sourceModule.ExportedVariables.Keys + "PSModule/TypeNames" = $sourceModule.ExportedTypeFiles | + ForEach-Object { (Select-Xml -XPath //Types/Type -Path $_).Node.Name } + +} +$PSJekyll.CurrentSite.Data +# It is important to use [Ordered], otherwise, the order of the keys will be random. +# (this will generate more changes than necessary in the git repository, and will be noisier than desired) +$PSJekyll.CurrentSite.Config = [Ordered]@{ + title = "WebSocket" + description = "Work with WebSockets in PowerShell" + url = "https://websocket.powershellweb.com" + permalink = 'pretty' + palette = 'Konsolas' + analyticsId = 'G-R5C30737B2' + googleFont = 'Noto Sans' + stylesheet = 'https://cdnjs.cloudflare.com/ajax/libs/animate.css/4.1.1/animate.min.css' + defaults = @([Ordered]@{ + values = @{layout='Default'} + }) +} +$PSJekyll.CurrentSite.Config + +foreach ($templateMember in $PSJekyll.Template.psobject.Members) { + if ($templateMember.Name -notmatch '^(?>layout|include)\p{P}{0,}') { + continue + } + $templateFileType = $matches.0 -replace '\p{P}{0,}$' + $templateFileName = $templateMember.Name -replace "^$([Regex]::Escape($templateFileType))\p{P}{0,}" + + if ($templateMember.Name -notmatch '\.([^\.]+?)$') { + $templateFileName += '.html' + } + $templateOut = + if ($templateMember.Invoke) { + $templateMember.Invoke() + } else { + $templateMember.Value + } + try { + $PSJekyll.CurrentSite.$templateFileType = $templateFileName, $templateOut + } catch { + $err = $_ + Write-Error -Message "Failed to set $templateFileName of $templateFileType : $err" + } +} + +$PSJekyll.CurrentSite.Page = 'Tree', "{% include SiteTree.html %}" +$PSJekyll.CurrentSite.Page = 'Repos', "{% include Repos.md %}" +$PSJekyll.CurrentSite.Page = 'Releases', "{% include Releases.md %}" +$PSJekyll.CurrentSite.Page = 'Contibutors', "{% include Contributor.md %}" +$PSJekyll.CurrentSite.Page = 'Members', "{% include OrgMember.md %}" +$PSJekyll.CurrentSite.Page = 'Function', "{% include PSFunctions.md %}" +$PSJekyll.CurrentSite.Page = 'Functions', "{% include PSFunctions.md %}" +$PSJekyll.CurrentSite.Page = 'Alias', "{% include PSAlias.md %}" +$PSJekyll.CurrentSite.Page = 'Aliases', "{% include PSAlias.md %}" +$PSJekyll.CurrentSite.Page = 'Cmdlet', "{% include PSCmdlet.md %}" +$PSJekyll.CurrentSite.Page = 'Cmdlets', "{% include PSCmdlet.md %}" +$PSJekyll.CurrentSite.Page = 'PSTag', "{% include PSTag.md %}" +$PSJekyll.CurrentSite.Page = 'PSTypeName', "{% include PSTypeName.md %}" +$PSJekyll.CurrentSite.Layout +$PSJekyll.CurrentSite.Include +$PSJekyll.CurrentSite.Page + +Pop-Location diff --git a/Build/WebSocket.PSSVG.ps1 b/Build/WebSocket.PSSVG.ps1 new file mode 100644 index 0000000..b29c434 --- /dev/null +++ b/Build/WebSocket.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 29% @fillParameters -Height 42% + ) -ViewBox 0, 0, 200, 200 -TransformOrigin 50%, 50% + ) + + $TextSplat = [Ordered]@{ + FontFamily=$fontName + FontSize='4.2em' + Style="font-family:`"$fontName`",sans-serif" + Fill='#4488FF' + Class='foreground-fill' + DominantBaseline='middle' + } + + svg -Content @( + SVG.GoogleFont -FontName $fontName + $symbolDefinition + SVG.Use -Href '#PowerShellWeb' -Height 60% -Width 60% -X 20% -Y 20% + SVG.Text -X 42% -Y 50% @TextSplat -Content '||' + SVG.Text -X 54% -Y 50% @TextSplat -Content '||' + SVG.text -X 50% -Y 80% @TextSplat -Content 'WebSocket' -TextAnchor 'middle' + ) -OutputPath $outputPath -ViewBox 0, 0, 1080, 1080 +} diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..abb0512 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,11 @@ +## WebSocket 0.1 + +> Like It? [Star It](https://github.com/PowerShellWeb/WebSocket) +> Love It? [Support It](https://github.com/sponsors/StartAutomating) + +* Initial Release of WebSocket module + * Get-WebSocket gets content from a WebSocket + * Docker container for WebSocket + * Build Workflow + * WebSocket Logo + * WebSocket website \ 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..ff18c8f --- /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/WebSocket/issues) or start a [discussion](https://github.com/PowerShellWeb/WebSocket/discussion) + +To add a feature, please open an issue and create a pull request. diff --git a/Commands/Get-WebSocket.ps1 b/Commands/Get-WebSocket.ps1 new file mode 100644 index 0000000..3723f81 --- /dev/null +++ b/Commands/Get-WebSocket.ps1 @@ -0,0 +1,227 @@ +function Get-WebSocket { + <# + .SYNOPSIS + WebSockets in PowerShell. + .DESCRIPTION + Get-WebSocket allows you to connect to a websocket and handle the output. + .EXAMPLE + # Create a WebSocket job that connects to a WebSocket and outputs the results. + Get-WebSocket -WebSocketUri "wss://localhost:9669" + .EXAMPLE + # Get is the default verb, so we can just say WebSocket. + websocket wss://jetstream2.us-east.bsky.network/subscribe?wantedCollections=app.bsky.feed.post + .EXAMPLE + websocket jetstream2.us-east.bsky.network/subscribe?wantedCollections=app.bsky.feed.post -Tail | + Foreach-Object { + $in = $_ + if ($in.commit.record.text -match '[\p{IsHighSurrogates}\p{IsLowSurrogates}]+') { + Write-Host $matches.0 -NoNewline + } + } + .EXAMPLE + $emojiPattern = '[\p{IsHighSurrogates}\p{IsLowSurrogates}\p{IsVariationSelectors}\p{IsCombiningHalfMarks}]+)' + websocket jetstream2.us-east.bsky.network/subscribe?wantedCollections=app.bsky.feed.post -Tail | + Foreach-Object { + $in = $_ + if ($in.commit.record.text -match "(?>(?:$emojiPattern|\#\w+)") { + Write-Host $matches.0 -NoNewline + } + } + #> + [CmdletBinding(PositionalBinding=$false)] + param( + # The Uri of the WebSocket to connect to. + [Parameter(Position=0,ValueFromPipelineByPropertyName)] + [Alias('Url','Uri')] + [uri]$WebSocketUri, + + # A ScriptBlock that will handle the output of the WebSocket. + [ScriptBlock] + $Handler, + + # Any variables to declare in the WebSocket job. + [Collections.IDictionary] + $Variable = @{}, + + # The name of the WebSocket job. + [string] + $Name, + + # The script to run when the WebSocket job starts. + [ScriptBlock] + $InitializationScript = {}, + + # The buffer size. Defaults to 16kb. + [int] + $BufferSize = 16kb, + + # The ScriptBlock to run after connection to a websocket. + # This can be useful for making any initial requests. + [ScriptBlock] + $OnConnect, + + # The ScriptBlock to run when an error occurs. + [ScriptBlock] + $OnError, + + # The ScriptBlock to run when the WebSocket job outputs an object. + [ScriptBlock] + $OnOutput, + + # The Scriptblock to run when the WebSocket job produces a warning. + [ScriptBlock] + $OnWarning, + + # If set, will watch the output of the WebSocket job, outputting results continuously instead of outputting a websocket job. + [Alias('Tail')] + [switch] + $Watch, + + # The maximum time to wait for a connection to be established. + # By default, this is 7 seconds. + [TimeSpan] + $ConnectionTimeout = '00:00:07', + + # The Runspace where the handler should run. + # Runspaces allow you to limit the scope of the handler. + [Runspace] + $Runspace, + + # The RunspacePool where the handler should run. + # RunspacePools allow you to limit the scope of the handler to a pool of runspaces. + [Management.Automation.Runspaces.RunspacePool] + [Alias('Pool')] + $RunspacePool + ) + + begin { + $SocketJob = { + param([Collections.IDictionary]$Variable) + + foreach ($keyValue in $variable.GetEnumerator()) { + $ExecutionContext.SessionState.PSVariable.Set($keyValue.Key, $keyValue.Value) + } + + if ((-not $WebSocketUri) -or $webSocket) { + throw "No WebSocketUri" + } + + if (-not $WebSocketUri.Scheme) { + $WebSocketUri = [uri]"wss://$WebSocketUri" + } + + if (-not $BufferSize) { + $BufferSize = 16kb + } + + $CT = [Threading.CancellationToken]::None + + if (-not $webSocket) { + $ws = [Net.WebSockets.ClientWebSocket]::new() + $null = $ws.ConnectAsync($WebSocketUri, $CT).Wait() + } else { + $ws = $WebSocket + } + + $Variable.WebSocket = $ws + + + while ($true) { + if ($ws.State -ne 'Open') {break } + $Buf = [byte[]]::new($BufferSize) + $Seg = [ArraySegment[byte]]::new($Buf) + $null = $ws.ReceiveAsync($Seg, $CT).Wait() + $JS = $OutputEncoding.GetString($Buf, 0, $Buf.Count) + if ([string]::IsNullOrWhitespace($JS)) { continue } + try { + $webSocketMessage = ConvertFrom-Json $JS + if ($handler) { + $psCmd = + if ($runspace.LanguageMode -eq 'NoLanguage' -or + $runspacePool.InitialSessionState.LanguageMode -eq 'NoLanguage') { + $handler.GetPowerShell() + } elseif ($Runspace -or $RunspacePool) { + [PowerShell]::Create().AddScript($handler) + } + if ($psCmd) { + if ($Runspace) { + $psCmd.Runspace = $Runspace + } elseif ($RunspacePool) { + $psCmd.RunspacePool = $RunspacePool + } + } else { + $webSocketMessage | . $handler + } + + } else { + $webSocketMessage + } + } catch { + Write-Error $_ + } + } + } + } + + process { + foreach ($keyValuePair in $PSBoundParameters.GetEnumerator()) { + $Variable[$keyValuePair.Key] = $keyValuePair.Value + } + $webSocketJob = + if ($WebSocketUri) { + if (-not $name) { + $Name = $WebSocketUri + } + + Start-ThreadJob -ScriptBlock $SocketJob -Name $Name -InitializationScript $InitializationScript -ArgumentList $Variable + } elseif ($WebSocket) { + if (-not $name) { + $name = "websocket" + } + Start-ThreadJob -ScriptBlock $SocketJob -Name $Name -InitializationScript $InitializationScript -ArgumentList $Variable + } + + $subscriptionSplat = @{ + EventName = 'DataAdded' + MessageData = $webSocketJob + SupportEvent = $true + } + $eventSubscriptions = @( + if ($OnOutput) { + Register-ObjectEvent @subscriptionSplat -InputObject $webSocketJob.Output -Action $OnOutput + } + if ($OnError) { + Register-ObjectEvent @subscriptionSplat -InputObject $webSocketJob.Error -Action $OnError + } + if ($OnWarning) { + Register-ObjectEvent @subscriptionSplat -InputObject $webSocketJob.Warning -Action $OnWarning + } + ) + if ($eventSubscriptions) { + $variable['EventSubscriptions'] = $eventSubscriptions + } + + $webSocketConnectTimeout = [DateTime]::Now + $ConnectionTimeout + while (-not $variable['WebSocket'] -and + ([DateTime]::Now -lt $webSocketConnectTimeout)) { + Start-Sleep -Milliseconds 0 + } + + foreach ($keyValuePair in $Variable.GetEnumerator()) { + $webSocketJob.psobject.properties.add( + [psnoteproperty]::new($keyValuePair.Key, $keyValuePair.Value), $true + ) + } + $webSocketJob.pstypenames.insert(0, 'WebSocketJob') + if ($Watch) { + do { + $webSocketJob | Receive-Job + Start-Sleep -Milliseconds ( + 7, 11, 13, 17, 19, 23 | Get-Random + ) + } while ($webSocketJob.State -in 'Running','NotStarted') + } else { + $webSocketJob + } + } +} diff --git a/Container.init.ps1 b/Container.init.ps1 new file mode 100644 index 0000000..352fe81 --- /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..dd49394 --- /dev/null +++ b/Container.start.ps1 @@ -0,0 +1,73 @@ +<# +.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/websocket' + +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 + else + { + + } + #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..edb66db --- /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 WebSocket!" | Out-Host diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..6df5630 --- /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=WebSocket +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/README.md b/README.md index 0fea519..5b5b4f2 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,33 @@ +

+ WebSocket Logo (Animated) +
+ # WebSocket + Work with WebSockets in PowerShell + +WebSocket is a small PowerShell module that helps you work with WebSockets. + +It has a single command: Get-WebSocket. + +Because `Get` is the default verb in PowerShell, you can just call it `WebSocket`. + + +### Installing and Importing + +~~~PowerShell +Install-Module WebSocket -Scope CurrentUser -Force +Import-Module WebSocket -Force -PassThru +~~~ + +### Get-WebSocket + +To connect to a websocket and start listening for results, use [Get-WebSocket](Get-WebSocket.md) + +~~~PowerShell +# Because get is the default verb, we can just say `WebSocket` +# The `-Watch` parameter will continually watch for results +websocket wss://jetstream2.us-east.bsky.network/subscribe?wantedCollections=app.bsky.feed.post -Watch +~~~ + +To stop watching a websocket, simply stop the background job. \ No newline at end of file diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 0000000..2b6cad9 --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,20 @@ +# Security + +We take security seriously. If you believe you have discovered a vulnerability, please [file an issue](https://github.com/PowerShellWeb/WebSocket/issues). + +## Special Security Considerations + +WebSockets are not inherantly dangerous, but what comes out of them might well be. + +In order to avoid data poisoning attacks, please _never_ directly run any code from the internet that you do not trust. + +Please also assume all WebSockets are untrustworthy. + +There are a few easy ways to do this. + +WebSocket responses should never: + +1. Be piped into `Invoke-Expression` +2. Be expanded with `.ExpandString` +3. Be directly placed into a `SQL` query + diff --git a/WebSocket.ps.psm1 b/WebSocket.ps.psm1 new file mode 100644 index 0000000..562e155 --- /dev/null +++ b/WebSocket.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/WebSocket.psd1 b/WebSocket.psd1 new file mode 100644 index 0000000..8cdbd37 --- /dev/null +++ b/WebSocket.psd1 @@ -0,0 +1,29 @@ +@{ + ModuleVersion = '0.1' + RootModule = 'WebSocket.psm1' + Guid = '75c70c8b-e5eb-4a60-982e-a19110a1185d' + Author = 'James Brundage' + CompanyName = 'StartAutomating' + Copyright = '2024 StartAutomating' + Description = 'Work with WebSockets in PowerShell' + PrivateData = @{ + PSData = @{ + Tags = @('WebSocket', 'WebSockets', 'Networking', 'Web') + ProjectURI = 'https://github.com/PowerShellWeb/WebSocket' + LicenseURI = 'https://github.com/PowerShellWeb/WebSocket/blob/main/LICENSE' + ReleaseNotes = @' +## WebSocket 0.1 + +> Like It? [Star It](https://github.com/PowerShellWeb/WebSocket) +> Love It? [Support It](https://github.com/sponsors/StartAutomating) + +* Initial Release of WebSocket module + * Get-WebSocket gets content from a WebSocket + * Docker container for WebSocket + * Build Workflow + * WebSocket Logo + * WebSocket website +'@ + } + } +} \ No newline at end of file diff --git a/WebSocket.psm1 b/WebSocket.psm1 new file mode 100644 index 0000000..41a1efb --- /dev/null +++ b/WebSocket.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/_config.yml b/_config.yml new file mode 100644 index 0000000..f894bca --- /dev/null +++ b/_config.yml @@ -0,0 +1,12 @@ + +title: WebSocket +description: Work with WebSockets in PowerShell +url: https://websocket.powershellweb.com +permalink: pretty +palette: Konsolas +analyticsId: G-R5C30737B2 +googleFont: Noto Sans +stylesheet: https://cdnjs.cloudflare.com/ajax/libs/animate.css/4.1.1/animate.min.css +defaults: + - values: + layout: Default diff --git a/_layouts/Default.html b/_layouts/Default.html new file mode 100644 index 0000000..9d96e1c --- /dev/null +++ b/_layouts/Default.html @@ -0,0 +1,27 @@ +--- + +title: Default.html +--- + + + + + + + {% include GoogleAnalytics.html %} + {% include ImportMap.html %} + {% include OpenGraph.html %} + {% include GoogleFont.html %} + {% include 4bitcss.html %} + {% include Margin.html %} + {% include Stylesheet.html %} + {% include Htmx.html %} + + + +{% include Menu.html %} + +{{content}} + +{% include Footer.html %} + \ No newline at end of file diff --git a/docs/Alias.md b/docs/Alias.md new file mode 100644 index 0000000..9d034b3 --- /dev/null +++ b/docs/Alias.md @@ -0,0 +1,5 @@ +--- + +title: Alias +--- +{% include PSAlias.md %} diff --git a/docs/Aliases.md b/docs/Aliases.md new file mode 100644 index 0000000..a63be11 --- /dev/null +++ b/docs/Aliases.md @@ -0,0 +1,5 @@ +--- + +title: Aliases +--- +{% include PSAlias.md %} diff --git a/docs/Assets/WebSocket-Animated.svg b/docs/Assets/WebSocket-Animated.svg new file mode 100644 index 0000000..3542af9 --- /dev/null +++ b/docs/Assets/WebSocket-Animated.svg @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + || + || + WebSocket + diff --git a/docs/Assets/WebSocket.svg b/docs/Assets/WebSocket.svg new file mode 100644 index 0000000..6974911 --- /dev/null +++ b/docs/Assets/WebSocket.svg @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + || + || + WebSocket + diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md new file mode 100644 index 0000000..7aeb592 --- /dev/null +++ b/docs/CHANGELOG.md @@ -0,0 +1,11 @@ +## WebSocket 0.1 + +> Like It? [Star It](https://github.com/PowerShellWeb/WebSocket) +> Love It? [Support It](https://github.com/sponsors/StartAutomating) + +* Initial Release of WebSocket module + * Get-WebSocket gets content from a WebSocket + * Docker container for WebSocket + * Build Workflow + * WebSocket Logo + * WebSocket website diff --git a/docs/CNAME b/docs/CNAME new file mode 100644 index 0000000..ae753c0 --- /dev/null +++ b/docs/CNAME @@ -0,0 +1 @@ +websocket.powershellweb.com \ No newline at end of file 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..ff18c8f --- /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/WebSocket/issues) or start a [discussion](https://github.com/PowerShellWeb/WebSocket/discussion) + +To add a feature, please open an issue and create a pull request. diff --git a/docs/Cmdlet.md b/docs/Cmdlet.md new file mode 100644 index 0000000..e4787bb --- /dev/null +++ b/docs/Cmdlet.md @@ -0,0 +1,5 @@ +--- + +title: Cmdlet +--- +{% include PSCmdlet.md %} diff --git a/docs/Cmdlets.md b/docs/Cmdlets.md new file mode 100644 index 0000000..e358037 --- /dev/null +++ b/docs/Cmdlets.md @@ -0,0 +1,5 @@ +--- + +title: Cmdlets +--- +{% include PSCmdlet.md %} diff --git a/docs/Contibutors.md b/docs/Contibutors.md new file mode 100644 index 0000000..094e77a --- /dev/null +++ b/docs/Contibutors.md @@ -0,0 +1,5 @@ +--- + +title: Contibutors +--- +{% include Contributor.md %} diff --git a/docs/Function.md b/docs/Function.md new file mode 100644 index 0000000..b922567 --- /dev/null +++ b/docs/Function.md @@ -0,0 +1,5 @@ +--- + +title: Function +--- +{% include PSFunctions.md %} diff --git a/docs/Functions.md b/docs/Functions.md new file mode 100644 index 0000000..0ac3c89 --- /dev/null +++ b/docs/Functions.md @@ -0,0 +1,5 @@ +--- + +title: Functions +--- +{% include PSFunctions.md %} diff --git a/docs/Get-WebSocket.md b/docs/Get-WebSocket.md new file mode 100644 index 0000000..a867234 --- /dev/null +++ b/docs/Get-WebSocket.md @@ -0,0 +1,160 @@ +Get-WebSocket +------------- + +### Synopsis +WebSockets in PowerShell. + +--- + +### Description + +Get-WebSocket allows you to connect to a websocket and handle the output. + +--- + +### Examples +Create a WebSocket job that connects to a WebSocket and outputs the results. + +```PowerShell +Get-WebSocket -WebSocketUri "wss://localhost:9669" +``` +Get is the default verb, so we can just say WebSocket. + +```PowerShell +websocket wss://jetstream2.us-east.bsky.network/subscribe?wantedCollections=app.bsky.feed.post +``` +> EXAMPLE 3 + +```PowerShell +websocket jetstream2.us-east.bsky.network/subscribe?wantedCollections=app.bsky.feed.post -Tail | + Foreach-Object { + $in = $_ + if ($in.commit.record.text -match '[\p{IsHighSurrogates}\p{IsLowSurrogates}]+') { + Write-Host $matches.0 -NoNewline + } + } +``` +> EXAMPLE 4 + +```PowerShell +$emojiPattern = '[\p{IsHighSurrogates}\p{IsLowSurrogates}\p{IsVariationSelectors}\p{IsCombiningHalfMarks}]+)' +websocket jetstream2.us-east.bsky.network/subscribe?wantedCollections=app.bsky.feed.post -Tail | + Foreach-Object { + $in = $_ + if ($in.commit.record.text -match "(?>(?:$emojiPattern|\#\w+)") { + Write-Host $matches.0 -NoNewline + } + } +``` + +--- + +### Parameters +#### **WebSocketUri** +The Uri of the WebSocket to connect to. + +|Type |Required|Position|PipelineInput |Aliases | +|-------|--------|--------|---------------------|-----------| +|`[Uri]`|false |1 |true (ByPropertyName)|Url
Uri| + +#### **Handler** +A ScriptBlock that will handle the output of the WebSocket. + +|Type |Required|Position|PipelineInput| +|---------------|--------|--------|-------------| +|`[ScriptBlock]`|false |named |false | + +#### **Variable** +Any variables to declare in the WebSocket job. + +|Type |Required|Position|PipelineInput| +|---------------|--------|--------|-------------| +|`[IDictionary]`|false |named |false | + +#### **Name** +The name of the WebSocket job. + +|Type |Required|Position|PipelineInput| +|----------|--------|--------|-------------| +|`[String]`|false |named |false | + +#### **InitializationScript** +The script to run when the WebSocket job starts. + +|Type |Required|Position|PipelineInput| +|---------------|--------|--------|-------------| +|`[ScriptBlock]`|false |named |false | + +#### **BufferSize** +The buffer size. Defaults to 16kb. + +|Type |Required|Position|PipelineInput| +|---------|--------|--------|-------------| +|`[Int32]`|false |named |false | + +#### **OnConnect** +The ScriptBlock to run after connection to a websocket. +This can be useful for making any initial requests. + +|Type |Required|Position|PipelineInput| +|---------------|--------|--------|-------------| +|`[ScriptBlock]`|false |named |false | + +#### **OnError** +The ScriptBlock to run when an error occurs. + +|Type |Required|Position|PipelineInput| +|---------------|--------|--------|-------------| +|`[ScriptBlock]`|false |named |false | + +#### **OnOutput** +The ScriptBlock to run when the WebSocket job outputs an object. + +|Type |Required|Position|PipelineInput| +|---------------|--------|--------|-------------| +|`[ScriptBlock]`|false |named |false | + +#### **OnWarning** +The Scriptblock to run when the WebSocket job produces a warning. + +|Type |Required|Position|PipelineInput| +|---------------|--------|--------|-------------| +|`[ScriptBlock]`|false |named |false | + +#### **Watch** +If set, will watch the output of the WebSocket job, outputting results continuously instead of outputting a websocket job. + +|Type |Required|Position|PipelineInput|Aliases| +|----------|--------|--------|-------------|-------| +|`[Switch]`|false |named |false |Tail | + +#### **ConnectionTimeout** +The maximum time to wait for a connection to be established. +By default, this is 7 seconds. + +|Type |Required|Position|PipelineInput| +|------------|--------|--------|-------------| +|`[TimeSpan]`|false |named |false | + +#### **Runspace** +The Runspace where the handler should run. +Runspaces allow you to limit the scope of the handler. + +|Type |Required|Position|PipelineInput| +|------------|--------|--------|-------------| +|`[Runspace]`|false |named |false | + +#### **RunspacePool** +The RunspacePool where the handler should run. +RunspacePools allow you to limit the scope of the handler to a pool of runspaces. + +|Type |Required|Position|PipelineInput|Aliases| +|----------------|--------|--------|-------------|-------| +|`[RunspacePool]`|false |named |false |Pool | + +--- + +### Syntax +```PowerShell +Get-WebSocket [[-WebSocketUri] ] [-Handler ] [-Variable ] [-Name ] [-InitializationScript ] [-BufferSize ] [-OnConnect ] [-OnError ] [-OnOutput ] [-OnWarning ] [-Watch] [-ConnectionTimeout ] [-Runspace ] [-RunspacePool ] [] +``` diff --git a/docs/Members.md b/docs/Members.md new file mode 100644 index 0000000..a9cac94 --- /dev/null +++ b/docs/Members.md @@ -0,0 +1,5 @@ +--- + +title: Members +--- +{% include OrgMember.md %} diff --git a/docs/PSTag.md b/docs/PSTag.md new file mode 100644 index 0000000..d2de97f --- /dev/null +++ b/docs/PSTag.md @@ -0,0 +1,5 @@ +--- + +title: PSTag +--- +{% include PSTag.md %} diff --git a/docs/PSTypeName.md b/docs/PSTypeName.md new file mode 100644 index 0000000..d0744b3 --- /dev/null +++ b/docs/PSTypeName.md @@ -0,0 +1,5 @@ +--- + +title: PSTypeName +--- +{% include PSTypeName.md %} diff --git a/docs/README.md b/docs/README.md new file mode 100644 index 0000000..f263805 --- /dev/null +++ b/docs/README.md @@ -0,0 +1,33 @@ +
+ WebSocket Logo (Animated) +
+ +# WebSocket + +Work with WebSockets in PowerShell + +WebSocket is a small PowerShell module that helps you work with WebSockets. + +It has a single command: Get-WebSocket. + +Because `Get` is the default verb in PowerShell, you can just call it `WebSocket`. + + +### Installing and Importing + +~~~PowerShell +Install-Module WebSocket -Scope CurrentUser -Force +Import-Module WebSocket -Force -PassThru +~~~ + +### Get-WebSocket + +To connect to a websocket and start listening for results, use [Get-WebSocket](Get-WebSocket.md) + +~~~PowerShell +# Because get is the default verb, we can just say `WebSocket` +# The `-Watch` parameter will continually watch for results +websocket wss://jetstream2.us-east.bsky.network/subscribe?wantedCollections=app.bsky.feed.post -Watch +~~~ + +To stop watching a websocket, simply stop the background job. diff --git a/docs/Releases.md b/docs/Releases.md new file mode 100644 index 0000000..cda6703 --- /dev/null +++ b/docs/Releases.md @@ -0,0 +1,5 @@ +--- + +title: Releases +--- +{% include Releases.md %} diff --git a/docs/Repos.md b/docs/Repos.md new file mode 100644 index 0000000..6eef525 --- /dev/null +++ b/docs/Repos.md @@ -0,0 +1,5 @@ +--- + +title: Repos +--- +{% include Repos.md %} diff --git a/docs/SECURITY.md b/docs/SECURITY.md new file mode 100644 index 0000000..d713011 --- /dev/null +++ b/docs/SECURITY.md @@ -0,0 +1,19 @@ +# Security + +We take security seriously. If you believe you have discovered a vulnerability, please [file an issue](https://github.com/PowerShellWeb/WebSocket/issues). + +## Special Security Considerations + +WebSockets are not inherantly dangerous, but what comes out of them might well be. + +In order to avoid data poisoning attacks, please _never_ directly run any code from the internet that you do not trust. + +Please also assume all WebSockets are untrustworthy. + +There are a few easy ways to do this. + +WebSocket responses should never: + +1. Be piped into `Invoke-Expression` +2. Be expanded with `.ExpandString` +3. Be directly placed into a `SQL` query diff --git a/docs/Tree.md b/docs/Tree.md new file mode 100644 index 0000000..1ae2682 --- /dev/null +++ b/docs/Tree.md @@ -0,0 +1,5 @@ +--- + +title: Tree +--- +{% include SiteTree.html %} diff --git a/docs/_config.yml b/docs/_config.yml new file mode 100644 index 0000000..f894bca --- /dev/null +++ b/docs/_config.yml @@ -0,0 +1,12 @@ + +title: WebSocket +description: Work with WebSockets in PowerShell +url: https://websocket.powershellweb.com +permalink: pretty +palette: Konsolas +analyticsId: G-R5C30737B2 +googleFont: Noto Sans +stylesheet: https://cdnjs.cloudflare.com/ajax/libs/animate.css/4.1.1/animate.min.css +defaults: + - values: + layout: Default diff --git a/docs/_data/Help/Get-WebSocket.json b/docs/_data/Help/Get-WebSocket.json new file mode 100644 index 0000000..1d24148 --- /dev/null +++ b/docs/_data/Help/Get-WebSocket.json @@ -0,0 +1,54 @@ +{ + "Synopsis": "WebSockets in PowerShell.", + "Description": "Get-WebSocket allows you to connect to a websocket and handle the output.", + "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": "Create a WebSocket job that connects to a WebSocket and outputs the results.", + "Code": "Get-WebSocket -WebSocketUri \"wss://localhost:9669\"" + }, + { + "Title": "EXAMPLE 2", + "Markdown": "Get is the default verb, so we can just say WebSocket.", + "Code": "websocket wss://jetstream2.us-east.bsky.network/subscribe?wantedCollections=app.bsky.feed.post" + }, + { + "Title": "EXAMPLE 3", + "Markdown": "", + "Code": "websocket jetstream2.us-east.bsky.network/subscribe?wantedCollections=app.bsky.feed.post -Tail |\n Foreach-Object {\n $in = $_\n if ($in.commit.record.text -match '[\\p{IsHighSurrogates}\\p{IsLowSurrogates}]+') {\n Write-Host $matches.0 -NoNewline\n }\n }" + }, + { + "Title": "EXAMPLE 4", + "Markdown": "", + "Code": "$emojiPattern = '[\\p{IsHighSurrogates}\\p{IsLowSurrogates}\\p{IsVariationSelectors}\\p{IsCombiningHalfMarks}]+)'\nwebsocket jetstream2.us-east.bsky.network/subscribe?wantedCollections=app.bsky.feed.post -Tail |\n Foreach-Object {\n $in = $_\n if ($in.commit.record.text -match \"(?>(?:$emojiPattern|\\#\\w+)\") {\n Write-Host $matches.0 -NoNewline\n }\n }" + } + ] +} \ No newline at end of file diff --git a/docs/_data/LastDateBuilt.json b/docs/_data/LastDateBuilt.json new file mode 100644 index 0000000..96642b6 --- /dev/null +++ b/docs/_data/LastDateBuilt.json @@ -0,0 +1 @@ +"2024-11-27" \ No newline at end of file diff --git a/docs/_data/PSModule/AliasNames.json b/docs/_data/PSModule/AliasNames.json new file mode 100644 index 0000000..e775ae1 --- /dev/null +++ b/docs/_data/PSModule/AliasNames.json @@ -0,0 +1,7 @@ +[ + "New-Jekyll", + "Remove-Jekyll", + "Set-Jekyll", + "Start-Jekyll", + "Stop-Jekyll" +] \ No newline at end of file diff --git a/docs/_data/PSModule/Aliases.json b/docs/_data/PSModule/Aliases.json new file mode 100644 index 0000000..4579eb9 --- /dev/null +++ b/docs/_data/PSModule/Aliases.json @@ -0,0 +1,22 @@ +[ + { + "Name": "New-Jekyll", + "Definition": "New-PSJekyll" + }, + { + "Name": "Remove-Jekyll", + "Definition": "Remove-PSJekyll" + }, + { + "Name": "Set-Jekyll", + "Definition": "Set-PSJekyll" + }, + { + "Name": "Start-Jekyll", + "Definition": "Start-PSJekyll" + }, + { + "Name": "Stop-Jekyll", + "Definition": "Stop-PSJekyll" + } +] \ No newline at end of file diff --git a/docs/_data/PSModule/CmdletNames.json b/docs/_data/PSModule/CmdletNames.json new file mode 100644 index 0000000..ec747fa --- /dev/null +++ b/docs/_data/PSModule/CmdletNames.json @@ -0,0 +1 @@ +null \ No newline at end of file diff --git a/docs/_data/PSModule/Exports.json b/docs/_data/PSModule/Exports.json new file mode 100644 index 0000000..eaca875 --- /dev/null +++ b/docs/_data/PSModule/Exports.json @@ -0,0 +1,1874 @@ +[ + { + "Name": "New-PSJekyll", + "CommandType": 2, + "Definition": "\n <#\n .SYNOPSIS\n Creates a new Jekyll site.\n .DESCRIPTION\n Creates a new Jekyll site, using PowerShell.\n .LINK\n https://jekyllrb.com/\n #>\n [Alias('New-Jekyll')]\n param(\n # The name of the Jekyll site\n [string]\n $Name,\n\n # Creates scaffolding but with empty files\n [switch]\n $Blank,\n\n # Force creation even if PATH already exists\n [switch]\n $Force,\n\n # Safe mode\n [switch]\n $Safe,\n\n # Skip the bundle install\n [switch]\n $SkipBundle,\n\n # The path to the source files\n [string]\n $SourcePath,\n\n # The path to the destination files\n [string]\n $DestinationPath,\n\n # The path to the layout files\n [string]\n $LayoutPath,\n\n # The path to the plugin files\n [string[]]\n $PluginPath,\n\n # If set, will generate a liquid profile\n [switch]\n $LiquidProfile,\n\n # If set, will trace the execution\n [switch]\n $Trace\n )\n\n $jekyllSplat = @(\n $name\n if ($blank) { '--blank' }\n if ($force) { '--force' }\n if ($safe) { '--safe' }\n if ($skipBundle) { '--skip-bundle' }\n if ($sourcePath) {\"--source $sourcePath\"}\n if ($destinationPath) {\"--destination $destinationPath\"}\n if ($layoutPath) {\"--layouts $layoutPath\"}\n if ($pluginPath) {\"--plugins $($pluginPath -join ',')\"}\n if ($liquidProfile) {'--profile'}\n if ($trace) {'--trace'}\n )\n\n $newJekyllJob = jekyll new @jekyllSplat &\n $newJekyllJob.pstypenames.Insert(0,'PSJekyll.Job')\n $newJekyllJob.pstypenames.Insert(0,'PSJekyll.Job.New-PSJekyll')\n $newJekyllJob\n", + "ParameterName": [ + "Name", + "Blank", + "Force", + "Safe", + "SkipBundle", + "SourcePath", + "DestinationPath", + "LayoutPath", + "PluginPath", + "LiquidProfile", + "Trace" + ], + "Parameter": [ + { + "Name": "Name", + "ParameterType": "System.String", + "Position": null, + "Mandatory": null, + "ValueFromPipeline": null, + "ValueFromPipelineByPropertyName": null, + "ValueFromRemainingArguments": null, + "HelpMessage": null + }, + { + "Name": "Blank", + "ParameterType": "System.Management.Automation.SwitchParameter", + "Position": null, + "Mandatory": null, + "ValueFromPipeline": null, + "ValueFromPipelineByPropertyName": null, + "ValueFromRemainingArguments": null, + "HelpMessage": null + }, + { + "Name": "Force", + "ParameterType": "System.Management.Automation.SwitchParameter", + "Position": null, + "Mandatory": null, + "ValueFromPipeline": null, + "ValueFromPipelineByPropertyName": null, + "ValueFromRemainingArguments": null, + "HelpMessage": null + }, + { + "Name": "Safe", + "ParameterType": "System.Management.Automation.SwitchParameter", + "Position": null, + "Mandatory": null, + "ValueFromPipeline": null, + "ValueFromPipelineByPropertyName": null, + "ValueFromRemainingArguments": null, + "HelpMessage": null + }, + { + "Name": "SkipBundle", + "ParameterType": "System.Management.Automation.SwitchParameter", + "Position": null, + "Mandatory": null, + "ValueFromPipeline": null, + "ValueFromPipelineByPropertyName": null, + "ValueFromRemainingArguments": null, + "HelpMessage": null + }, + { + "Name": "SourcePath", + "ParameterType": "System.String", + "Position": null, + "Mandatory": null, + "ValueFromPipeline": null, + "ValueFromPipelineByPropertyName": null, + "ValueFromRemainingArguments": null, + "HelpMessage": null + }, + { + "Name": "DestinationPath", + "ParameterType": "System.String", + "Position": null, + "Mandatory": null, + "ValueFromPipeline": null, + "ValueFromPipelineByPropertyName": null, + "ValueFromRemainingArguments": null, + "HelpMessage": null + }, + { + "Name": "LayoutPath", + "ParameterType": "System.String", + "Position": null, + "Mandatory": null, + "ValueFromPipeline": null, + "ValueFromPipelineByPropertyName": null, + "ValueFromRemainingArguments": null, + "HelpMessage": null + }, + { + "Name": "PluginPath", + "ParameterType": "System.String[]", + "Position": null, + "Mandatory": null, + "ValueFromPipeline": null, + "ValueFromPipelineByPropertyName": null, + "ValueFromRemainingArguments": null, + "HelpMessage": null + }, + { + "Name": "LiquidProfile", + "ParameterType": "System.Management.Automation.SwitchParameter", + "Position": null, + "Mandatory": null, + "ValueFromPipeline": null, + "ValueFromPipelineByPropertyName": null, + "ValueFromRemainingArguments": null, + "HelpMessage": null + }, + { + "Name": "Trace", + "ParameterType": "System.Management.Automation.SwitchParameter", + "Position": null, + "Mandatory": null, + "ValueFromPipeline": null, + "ValueFromPipelineByPropertyName": null, + "ValueFromRemainingArguments": null, + "HelpMessage": null + } + ] + }, + { + "Name": "Remove-PSJekyll", + "CommandType": 2, + "Definition": " \n <#\n .SYNOPSIS\n Removes content from Jekyll\n .DESCRIPTION\n Removes files from Jekyll\n\n This is a slightly limited version of Remove-Item.\n #>\n [Alias('Remove-Jekyll')]\n param(\n # The path to the file.\n [Parameter(Mandatory,Position=0,ValueFromPipelineByPropertyName)] \n [ValidatePattern('^[\\\\/]')]\n [Alias('FullName')]\n [string]\n $Path\n )\n \n process {\n if (Test-Path $path) { \n Remove-Item -Path $path \n }\n } \n", + "ParameterName": [ + "Path", + "Verbose", + "Debug", + "ErrorAction", + "WarningAction", + "InformationAction", + "ProgressAction", + "ErrorVariable", + "WarningVariable", + "InformationVariable", + "OutVariable", + "OutBuffer", + "PipelineVariable" + ], + "Parameter": [ + { + "Name": "Path", + "ParameterType": "System.String", + "Position": null, + "Mandatory": null, + "ValueFromPipeline": null, + "ValueFromPipelineByPropertyName": null, + "ValueFromRemainingArguments": null, + "HelpMessage": null + }, + { + "Name": "Verbose", + "ParameterType": "System.Management.Automation.SwitchParameter", + "Position": null, + "Mandatory": null, + "ValueFromPipeline": null, + "ValueFromPipelineByPropertyName": null, + "ValueFromRemainingArguments": null, + "HelpMessage": null + }, + { + "Name": "Debug", + "ParameterType": "System.Management.Automation.SwitchParameter", + "Position": null, + "Mandatory": null, + "ValueFromPipeline": null, + "ValueFromPipelineByPropertyName": null, + "ValueFromRemainingArguments": null, + "HelpMessage": null + }, + { + "Name": "ErrorAction", + "ParameterType": "System.Management.Automation.ActionPreference", + "Position": null, + "Mandatory": null, + "ValueFromPipeline": null, + "ValueFromPipelineByPropertyName": null, + "ValueFromRemainingArguments": null, + "HelpMessage": null + }, + { + "Name": "WarningAction", + "ParameterType": "System.Management.Automation.ActionPreference", + "Position": null, + "Mandatory": null, + "ValueFromPipeline": null, + "ValueFromPipelineByPropertyName": null, + "ValueFromRemainingArguments": null, + "HelpMessage": null + }, + { + "Name": "InformationAction", + "ParameterType": "System.Management.Automation.ActionPreference", + "Position": null, + "Mandatory": null, + "ValueFromPipeline": null, + "ValueFromPipelineByPropertyName": null, + "ValueFromRemainingArguments": null, + "HelpMessage": null + }, + { + "Name": "ProgressAction", + "ParameterType": "System.Management.Automation.ActionPreference", + "Position": null, + "Mandatory": null, + "ValueFromPipeline": null, + "ValueFromPipelineByPropertyName": null, + "ValueFromRemainingArguments": null, + "HelpMessage": null + }, + { + "Name": "ErrorVariable", + "ParameterType": "System.String", + "Position": null, + "Mandatory": null, + "ValueFromPipeline": null, + "ValueFromPipelineByPropertyName": null, + "ValueFromRemainingArguments": null, + "HelpMessage": null + }, + { + "Name": "WarningVariable", + "ParameterType": "System.String", + "Position": null, + "Mandatory": null, + "ValueFromPipeline": null, + "ValueFromPipelineByPropertyName": null, + "ValueFromRemainingArguments": null, + "HelpMessage": null + }, + { + "Name": "InformationVariable", + "ParameterType": "System.String", + "Position": null, + "Mandatory": null, + "ValueFromPipeline": null, + "ValueFromPipelineByPropertyName": null, + "ValueFromRemainingArguments": null, + "HelpMessage": null + }, + { + "Name": "OutVariable", + "ParameterType": "System.String", + "Position": null, + "Mandatory": null, + "ValueFromPipeline": null, + "ValueFromPipelineByPropertyName": null, + "ValueFromRemainingArguments": null, + "HelpMessage": null + }, + { + "Name": "OutBuffer", + "ParameterType": "System.Int32", + "Position": null, + "Mandatory": null, + "ValueFromPipeline": null, + "ValueFromPipelineByPropertyName": null, + "ValueFromRemainingArguments": null, + "HelpMessage": null + }, + { + "Name": "PipelineVariable", + "ParameterType": "System.String", + "Position": null, + "Mandatory": null, + "ValueFromPipeline": null, + "ValueFromPipelineByPropertyName": null, + "ValueFromRemainingArguments": null, + "HelpMessage": null + } + ] + }, + { + "Name": "Set-PSJekyll", + "CommandType": 2, + "Definition": " \n <#\n .SYNOPSIS\n Sets the content of a file in Jekyll\n .DESCRIPTION\n Sets the content of a file in Jekyll.\n\n This is only slightly smarter than Set-Content. \n \n It will convert the content to JSON if the file ends in .json, and to CSV if the file ends in .csv or .tsv.\n\n Otherwise, it will create a YAML header and then set the content.\n #>\n [Alias('Set-Jekyll')]\n param(\n # The path to the file.\n [Parameter(Mandatory,Position=0)] \n [ValidatePattern('^[\\\\/]')]\n [Alias('FullName')]\n [string]\n $Path,\n \n # If set, will return the file object\n [switch]\n $PassThru,\n \n # The content to set\n [Parameter(ValueFromPipeline)]\n [object]\n $Content,\n\n # Any metadata to set. \n # This will create a YAML header, which is required for most files in Jekyll to be processed properly.\n [Alias('YamlHeader')]\n [Collections.IDictionary]\n $MetaData = [Ordered]@{}\n )\n \n $allInput = @($input)\n if ((-not $allInput) -and $Content) {\n $allInput = @($Content)\n }\n\n if (-not $allInput) { return }\n if (-not (Test-Path $path)) { \n New-Item -Path $path -Type File -Force | Out-Null\n if (-not $?) { return }\n }\n \n if ($path -match '\\.json$') {\n if ($allInput.Length -eq 1) { \n ConvertTo-Json -InputObject $allInput[0] -Depth $FormatEnumerationLimit | \n Set-Content -Path $path\n } else {\n ConvertTo-Json -InputObject $allInput -Depth $FormatEnumerationLimit | \n Set-Content -Path $path\n } \n } \n elseif ($path -match '\\.[ct]sv$') {\n $csvSplat = [Ordered]@{Path=$path}\n if ($path -match '\\.t') {\n $csvSplat.Delimiter = \"`t\"\n }\n $content | \n Export-Csv @csvSplat -NoTypeInformation \n }\n else {\n @(\n $metadata | & $psJekyll.FormatYaml.Script -YamlHeader\n $content\n ) | \n Set-Content -Path $path\n }\n if ($? -and $PassThru) {\n Get-Item -Path $path\n }\n", + "ParameterName": [ + "Path", + "PassThru", + "Content", + "MetaData", + "Verbose", + "Debug", + "ErrorAction", + "WarningAction", + "InformationAction", + "ProgressAction", + "ErrorVariable", + "WarningVariable", + "InformationVariable", + "OutVariable", + "OutBuffer", + "PipelineVariable" + ], + "Parameter": [ + { + "Name": "Path", + "ParameterType": "System.String", + "Position": null, + "Mandatory": null, + "ValueFromPipeline": null, + "ValueFromPipelineByPropertyName": null, + "ValueFromRemainingArguments": null, + "HelpMessage": null + }, + { + "Name": "PassThru", + "ParameterType": "System.Management.Automation.SwitchParameter", + "Position": null, + "Mandatory": null, + "ValueFromPipeline": null, + "ValueFromPipelineByPropertyName": null, + "ValueFromRemainingArguments": null, + "HelpMessage": null + }, + { + "Name": "Content", + "ParameterType": "System.Object", + "Position": null, + "Mandatory": null, + "ValueFromPipeline": null, + "ValueFromPipelineByPropertyName": null, + "ValueFromRemainingArguments": null, + "HelpMessage": null + }, + { + "Name": "MetaData", + "ParameterType": "System.Collections.IDictionary", + "Position": null, + "Mandatory": null, + "ValueFromPipeline": null, + "ValueFromPipelineByPropertyName": null, + "ValueFromRemainingArguments": null, + "HelpMessage": null + }, + { + "Name": "Verbose", + "ParameterType": "System.Management.Automation.SwitchParameter", + "Position": null, + "Mandatory": null, + "ValueFromPipeline": null, + "ValueFromPipelineByPropertyName": null, + "ValueFromRemainingArguments": null, + "HelpMessage": null + }, + { + "Name": "Debug", + "ParameterType": "System.Management.Automation.SwitchParameter", + "Position": null, + "Mandatory": null, + "ValueFromPipeline": null, + "ValueFromPipelineByPropertyName": null, + "ValueFromRemainingArguments": null, + "HelpMessage": null + }, + { + "Name": "ErrorAction", + "ParameterType": "System.Management.Automation.ActionPreference", + "Position": null, + "Mandatory": null, + "ValueFromPipeline": null, + "ValueFromPipelineByPropertyName": null, + "ValueFromRemainingArguments": null, + "HelpMessage": null + }, + { + "Name": "WarningAction", + "ParameterType": "System.Management.Automation.ActionPreference", + "Position": null, + "Mandatory": null, + "ValueFromPipeline": null, + "ValueFromPipelineByPropertyName": null, + "ValueFromRemainingArguments": null, + "HelpMessage": null + }, + { + "Name": "InformationAction", + "ParameterType": "System.Management.Automation.ActionPreference", + "Position": null, + "Mandatory": null, + "ValueFromPipeline": null, + "ValueFromPipelineByPropertyName": null, + "ValueFromRemainingArguments": null, + "HelpMessage": null + }, + { + "Name": "ProgressAction", + "ParameterType": "System.Management.Automation.ActionPreference", + "Position": null, + "Mandatory": null, + "ValueFromPipeline": null, + "ValueFromPipelineByPropertyName": null, + "ValueFromRemainingArguments": null, + "HelpMessage": null + }, + { + "Name": "ErrorVariable", + "ParameterType": "System.String", + "Position": null, + "Mandatory": null, + "ValueFromPipeline": null, + "ValueFromPipelineByPropertyName": null, + "ValueFromRemainingArguments": null, + "HelpMessage": null + }, + { + "Name": "WarningVariable", + "ParameterType": "System.String", + "Position": null, + "Mandatory": null, + "ValueFromPipeline": null, + "ValueFromPipelineByPropertyName": null, + "ValueFromRemainingArguments": null, + "HelpMessage": null + }, + { + "Name": "InformationVariable", + "ParameterType": "System.String", + "Position": null, + "Mandatory": null, + "ValueFromPipeline": null, + "ValueFromPipelineByPropertyName": null, + "ValueFromRemainingArguments": null, + "HelpMessage": null + }, + { + "Name": "OutVariable", + "ParameterType": "System.String", + "Position": null, + "Mandatory": null, + "ValueFromPipeline": null, + "ValueFromPipelineByPropertyName": null, + "ValueFromRemainingArguments": null, + "HelpMessage": null + }, + { + "Name": "OutBuffer", + "ParameterType": "System.Int32", + "Position": null, + "Mandatory": null, + "ValueFromPipeline": null, + "ValueFromPipelineByPropertyName": null, + "ValueFromRemainingArguments": null, + "HelpMessage": null + }, + { + "Name": "PipelineVariable", + "ParameterType": "System.String", + "Position": null, + "Mandatory": null, + "ValueFromPipeline": null, + "ValueFromPipelineByPropertyName": null, + "ValueFromRemainingArguments": null, + "HelpMessage": null + } + ] + }, + { + "Name": "Start-PSJekyll", + "CommandType": 2, + "Definition": "\n <#\n .SYNOPSIS\n Starts a Jekyll server\n .DESCRIPTION\n Starts a Jekyll server in a PowerShell job.\n .LINK\n https://jekyllrb.com/\n #>\n [Alias('Start-Jekyll')]\n [CmdletBinding()]\n param(\n # The name of the Jekyll site\n [string]\n $Name,\n\n # One or more config files to use\n [Alias('Configuration')]\n [string[]]\n $Config,\n\n # The source directory\n [string]\n $SourcePath,\n\n # The destination directory\n [string]\n $DestinationPath,\n \n # The host header\n [string]\n $HostHeader,\n\n # The port to listen on\n [uint]\n $Port,\n\n # The path to the plugin files\n [string[]]\n $PluginPath,\n\n # If set, will show a directory list.\n [switch]\n $ShowDirectoryList,\n\n # If set, will enable live reload.\n [switch]\n $LiveReload,\n\n # If set, will generate a liquid profile\n [switch]\n $LiquidProfile,\n\n # If set, will trace the execution\n [switch]\n $Trace, \n\n # Watch for changes and rebuild\n [switch]\n $Watch,\n\n # If set, will publish posts with a future date (previewing them).\n [switch]\n $PreviewFuture,\n\n # The base URL for the site\n [string]\n $BaseUrl,\n\n # If set, will detach the process\n [switch]\n $Detach,\n\n # Enable incremental rebuilds\n [switch]\n $Incremental\n )\n\n if ($env:IN_CONTAINER -and -not $HostHeader) {\n $HostHeader = '*'\n } \n\n $jekyllSplat = @( \n if ($force) { '--force' }\n if ($safe) { '--safe' }\n if ($Detach) { '--detach' }\n if ($PreviewFuture) { '--future' }\n if ($liveReload) {'--livereload'}\n if ($sourcePath) {\"--source\";\"$sourcePath\"}\n if ($destinationPath) {\"--destination\";\"$destinationPath\"}\n if ($BaseUrl) {\"--baseurl\";\"$BaseUrl\"}\n if ($Incremental) {'--incremental'}\n if ($HostHeader) {\"--host\"; \"$HostHeader\"}\n if ($Port) {\"--port\"; \"$Port\"}\n if ($ShowDirectoryList) {'--show-dir-list'}\n if ($layoutPath) {\"--layouts\"; \"$layoutPath\"}\n if ($pluginPath) {\"--plugins\"; \"$($pluginPath -join ',')\"}\n if ($liquidProfile) {'--profile'}\n if ($trace) {'--trace'}\n if ($watch) {'--watch'}\n\n )\n \n $startedAfter = [DateTime]::Now\n if ($jekyllSplat -notmatch '--watch') {\n $jekyllSplat += '--watch'\n }\n if ($jekyllSplat -notmatch '--incremental') {\n $jekyllSplat += '--incremental'\n }\n if ($jekyllSplat -notmatch '--trace') {\n $jekyllSplat += '--trace'\n }\n $isGemFilePresent = Test-Path -Path './Gemfile'\n if (-not $isGemFilePresent) {\n Write-Warning \"Gemfile not found in the current directory. Creating a default Gemfile.\"\n $gitRemote = git remote\n if ($gitRemote -isnot [string] -or $gitRemote -notmatch 'fatal') {\n $PSJekyll.Template.'GitHubPages.Gemfile'() > ./Gemfile\n } else {\n $PSJekyll.Template.MinGemFile() > ./Gemfile\n } \n }\n Write-Verbose \"Starting Jekyll server $jekyllSplat\"\n $jobName = if ($hostHeader) { \"PSJekyll.$hostHeader\" } else { \"Start-PSJekyll\" }\n $jekyllJob = \n Start-ThreadJob -ScriptBlock {\n if ($ExecutionContext.SessionState.InvokeCommand.GetCommand('sudo','application')) {\n sudo bundle install\n } else {\n bundle install\n }\n \n if ($args -match '^\\*$' -and $args -match '^--host$') {\n $otherArgs = @($args -notmatch '^(?>--host|\\*)$') \n bundle exec jekyll serve --host '*' @otherArgs\n } else {\n $promptLongForm = @('exec','jekyll','serve') + $args \n bundle @promptLongForm\n } \n } -ArgumentList $jekyllSplat -Name $jobName\n \n $jekyllProcesses = Get-Process *ruby* | Where-Object { $_.StartTime -ge $startedAfter }\n\n Register-EngineEvent -SourceIdentifier PowerShell.Exiting -Action {\n get-process ruby | Stop-Process -Force\n } | Out-Null\n \n $jekyllJob.pstypenames.insert(0,\"PSJekyll.JekyllJob\")\n $jekyllJob.psobject.properties.Add([psnoteproperty]::New(\"Processes\", $jekyllProcesses))\n $jekyllJob\n", + "ParameterName": [ + "Name", + "Config", + "SourcePath", + "DestinationPath", + "HostHeader", + "Port", + "PluginPath", + "ShowDirectoryList", + "LiveReload", + "LiquidProfile", + "Trace", + "Watch", + "PreviewFuture", + "BaseUrl", + "Detach", + "Incremental", + "Verbose", + "Debug", + "ErrorAction", + "WarningAction", + "InformationAction", + "ProgressAction", + "ErrorVariable", + "WarningVariable", + "InformationVariable", + "OutVariable", + "OutBuffer", + "PipelineVariable" + ], + "Parameter": [ + { + "Name": "Name", + "ParameterType": "System.String", + "Position": null, + "Mandatory": null, + "ValueFromPipeline": null, + "ValueFromPipelineByPropertyName": null, + "ValueFromRemainingArguments": null, + "HelpMessage": null + }, + { + "Name": "Config", + "ParameterType": "System.String[]", + "Position": null, + "Mandatory": null, + "ValueFromPipeline": null, + "ValueFromPipelineByPropertyName": null, + "ValueFromRemainingArguments": null, + "HelpMessage": null + }, + { + "Name": "SourcePath", + "ParameterType": "System.String", + "Position": null, + "Mandatory": null, + "ValueFromPipeline": null, + "ValueFromPipelineByPropertyName": null, + "ValueFromRemainingArguments": null, + "HelpMessage": null + }, + { + "Name": "DestinationPath", + "ParameterType": "System.String", + "Position": null, + "Mandatory": null, + "ValueFromPipeline": null, + "ValueFromPipelineByPropertyName": null, + "ValueFromRemainingArguments": null, + "HelpMessage": null + }, + { + "Name": "HostHeader", + "ParameterType": "System.String", + "Position": null, + "Mandatory": null, + "ValueFromPipeline": null, + "ValueFromPipelineByPropertyName": null, + "ValueFromRemainingArguments": null, + "HelpMessage": null + }, + { + "Name": "Port", + "ParameterType": "System.UInt32", + "Position": null, + "Mandatory": null, + "ValueFromPipeline": null, + "ValueFromPipelineByPropertyName": null, + "ValueFromRemainingArguments": null, + "HelpMessage": null + }, + { + "Name": "PluginPath", + "ParameterType": "System.String[]", + "Position": null, + "Mandatory": null, + "ValueFromPipeline": null, + "ValueFromPipelineByPropertyName": null, + "ValueFromRemainingArguments": null, + "HelpMessage": null + }, + { + "Name": "ShowDirectoryList", + "ParameterType": "System.Management.Automation.SwitchParameter", + "Position": null, + "Mandatory": null, + "ValueFromPipeline": null, + "ValueFromPipelineByPropertyName": null, + "ValueFromRemainingArguments": null, + "HelpMessage": null + }, + { + "Name": "LiveReload", + "ParameterType": "System.Management.Automation.SwitchParameter", + "Position": null, + "Mandatory": null, + "ValueFromPipeline": null, + "ValueFromPipelineByPropertyName": null, + "ValueFromRemainingArguments": null, + "HelpMessage": null + }, + { + "Name": "LiquidProfile", + "ParameterType": "System.Management.Automation.SwitchParameter", + "Position": null, + "Mandatory": null, + "ValueFromPipeline": null, + "ValueFromPipelineByPropertyName": null, + "ValueFromRemainingArguments": null, + "HelpMessage": null + }, + { + "Name": "Trace", + "ParameterType": "System.Management.Automation.SwitchParameter", + "Position": null, + "Mandatory": null, + "ValueFromPipeline": null, + "ValueFromPipelineByPropertyName": null, + "ValueFromRemainingArguments": null, + "HelpMessage": null + }, + { + "Name": "Watch", + "ParameterType": "System.Management.Automation.SwitchParameter", + "Position": null, + "Mandatory": null, + "ValueFromPipeline": null, + "ValueFromPipelineByPropertyName": null, + "ValueFromRemainingArguments": null, + "HelpMessage": null + }, + { + "Name": "PreviewFuture", + "ParameterType": "System.Management.Automation.SwitchParameter", + "Position": null, + "Mandatory": null, + "ValueFromPipeline": null, + "ValueFromPipelineByPropertyName": null, + "ValueFromRemainingArguments": null, + "HelpMessage": null + }, + { + "Name": "BaseUrl", + "ParameterType": "System.String", + "Position": null, + "Mandatory": null, + "ValueFromPipeline": null, + "ValueFromPipelineByPropertyName": null, + "ValueFromRemainingArguments": null, + "HelpMessage": null + }, + { + "Name": "Detach", + "ParameterType": "System.Management.Automation.SwitchParameter", + "Position": null, + "Mandatory": null, + "ValueFromPipeline": null, + "ValueFromPipelineByPropertyName": null, + "ValueFromRemainingArguments": null, + "HelpMessage": null + }, + { + "Name": "Incremental", + "ParameterType": "System.Management.Automation.SwitchParameter", + "Position": null, + "Mandatory": null, + "ValueFromPipeline": null, + "ValueFromPipelineByPropertyName": null, + "ValueFromRemainingArguments": null, + "HelpMessage": null + }, + { + "Name": "Verbose", + "ParameterType": "System.Management.Automation.SwitchParameter", + "Position": null, + "Mandatory": null, + "ValueFromPipeline": null, + "ValueFromPipelineByPropertyName": null, + "ValueFromRemainingArguments": null, + "HelpMessage": null + }, + { + "Name": "Debug", + "ParameterType": "System.Management.Automation.SwitchParameter", + "Position": null, + "Mandatory": null, + "ValueFromPipeline": null, + "ValueFromPipelineByPropertyName": null, + "ValueFromRemainingArguments": null, + "HelpMessage": null + }, + { + "Name": "ErrorAction", + "ParameterType": "System.Management.Automation.ActionPreference", + "Position": null, + "Mandatory": null, + "ValueFromPipeline": null, + "ValueFromPipelineByPropertyName": null, + "ValueFromRemainingArguments": null, + "HelpMessage": null + }, + { + "Name": "WarningAction", + "ParameterType": "System.Management.Automation.ActionPreference", + "Position": null, + "Mandatory": null, + "ValueFromPipeline": null, + "ValueFromPipelineByPropertyName": null, + "ValueFromRemainingArguments": null, + "HelpMessage": null + }, + { + "Name": "InformationAction", + "ParameterType": "System.Management.Automation.ActionPreference", + "Position": null, + "Mandatory": null, + "ValueFromPipeline": null, + "ValueFromPipelineByPropertyName": null, + "ValueFromRemainingArguments": null, + "HelpMessage": null + }, + { + "Name": "ProgressAction", + "ParameterType": "System.Management.Automation.ActionPreference", + "Position": null, + "Mandatory": null, + "ValueFromPipeline": null, + "ValueFromPipelineByPropertyName": null, + "ValueFromRemainingArguments": null, + "HelpMessage": null + }, + { + "Name": "ErrorVariable", + "ParameterType": "System.String", + "Position": null, + "Mandatory": null, + "ValueFromPipeline": null, + "ValueFromPipelineByPropertyName": null, + "ValueFromRemainingArguments": null, + "HelpMessage": null + }, + { + "Name": "WarningVariable", + "ParameterType": "System.String", + "Position": null, + "Mandatory": null, + "ValueFromPipeline": null, + "ValueFromPipelineByPropertyName": null, + "ValueFromRemainingArguments": null, + "HelpMessage": null + }, + { + "Name": "InformationVariable", + "ParameterType": "System.String", + "Position": null, + "Mandatory": null, + "ValueFromPipeline": null, + "ValueFromPipelineByPropertyName": null, + "ValueFromRemainingArguments": null, + "HelpMessage": null + }, + { + "Name": "OutVariable", + "ParameterType": "System.String", + "Position": null, + "Mandatory": null, + "ValueFromPipeline": null, + "ValueFromPipelineByPropertyName": null, + "ValueFromRemainingArguments": null, + "HelpMessage": null + }, + { + "Name": "OutBuffer", + "ParameterType": "System.Int32", + "Position": null, + "Mandatory": null, + "ValueFromPipeline": null, + "ValueFromPipelineByPropertyName": null, + "ValueFromRemainingArguments": null, + "HelpMessage": null + }, + { + "Name": "PipelineVariable", + "ParameterType": "System.String", + "Position": null, + "Mandatory": null, + "ValueFromPipeline": null, + "ValueFromPipelineByPropertyName": null, + "ValueFromRemainingArguments": null, + "HelpMessage": null + } + ] + }, + { + "Name": "Stop-PSJekyll", + "CommandType": 2, + "Definition": "\n <#\n .SYNOPSIS\n Stops a Jekyll server\n .DESCRIPTION\n Stops a Jekyll server in a PowerShell job.\n .LINK\n https://jekyllrb.com/\n #>\n [Alias('Stop-Jekyll')] \n param(\n # The name of the Jekyll job\n [Parameter(ValueFromPipelineByPropertyName)]\n [string]\n $Name = '*'\n )\n\n process {\n Get-Job -Name \"Jekyll.$Name\" | Stop-Job\n }\n", + "ParameterName": [ + "Name", + "Verbose", + "Debug", + "ErrorAction", + "WarningAction", + "InformationAction", + "ProgressAction", + "ErrorVariable", + "WarningVariable", + "InformationVariable", + "OutVariable", + "OutBuffer", + "PipelineVariable" + ], + "Parameter": [ + { + "Name": "Name", + "ParameterType": "System.String", + "Position": null, + "Mandatory": null, + "ValueFromPipeline": null, + "ValueFromPipelineByPropertyName": null, + "ValueFromRemainingArguments": null, + "HelpMessage": null + }, + { + "Name": "Verbose", + "ParameterType": "System.Management.Automation.SwitchParameter", + "Position": null, + "Mandatory": null, + "ValueFromPipeline": null, + "ValueFromPipelineByPropertyName": null, + "ValueFromRemainingArguments": null, + "HelpMessage": null + }, + { + "Name": "Debug", + "ParameterType": "System.Management.Automation.SwitchParameter", + "Position": null, + "Mandatory": null, + "ValueFromPipeline": null, + "ValueFromPipelineByPropertyName": null, + "ValueFromRemainingArguments": null, + "HelpMessage": null + }, + { + "Name": "ErrorAction", + "ParameterType": "System.Management.Automation.ActionPreference", + "Position": null, + "Mandatory": null, + "ValueFromPipeline": null, + "ValueFromPipelineByPropertyName": null, + "ValueFromRemainingArguments": null, + "HelpMessage": null + }, + { + "Name": "WarningAction", + "ParameterType": "System.Management.Automation.ActionPreference", + "Position": null, + "Mandatory": null, + "ValueFromPipeline": null, + "ValueFromPipelineByPropertyName": null, + "ValueFromRemainingArguments": null, + "HelpMessage": null + }, + { + "Name": "InformationAction", + "ParameterType": "System.Management.Automation.ActionPreference", + "Position": null, + "Mandatory": null, + "ValueFromPipeline": null, + "ValueFromPipelineByPropertyName": null, + "ValueFromRemainingArguments": null, + "HelpMessage": null + }, + { + "Name": "ProgressAction", + "ParameterType": "System.Management.Automation.ActionPreference", + "Position": null, + "Mandatory": null, + "ValueFromPipeline": null, + "ValueFromPipelineByPropertyName": null, + "ValueFromRemainingArguments": null, + "HelpMessage": null + }, + { + "Name": "ErrorVariable", + "ParameterType": "System.String", + "Position": null, + "Mandatory": null, + "ValueFromPipeline": null, + "ValueFromPipelineByPropertyName": null, + "ValueFromRemainingArguments": null, + "HelpMessage": null + }, + { + "Name": "WarningVariable", + "ParameterType": "System.String", + "Position": null, + "Mandatory": null, + "ValueFromPipeline": null, + "ValueFromPipelineByPropertyName": null, + "ValueFromRemainingArguments": null, + "HelpMessage": null + }, + { + "Name": "InformationVariable", + "ParameterType": "System.String", + "Position": null, + "Mandatory": null, + "ValueFromPipeline": null, + "ValueFromPipelineByPropertyName": null, + "ValueFromRemainingArguments": null, + "HelpMessage": null + }, + { + "Name": "OutVariable", + "ParameterType": "System.String", + "Position": null, + "Mandatory": null, + "ValueFromPipeline": null, + "ValueFromPipelineByPropertyName": null, + "ValueFromRemainingArguments": null, + "HelpMessage": null + }, + { + "Name": "OutBuffer", + "ParameterType": "System.Int32", + "Position": null, + "Mandatory": null, + "ValueFromPipeline": null, + "ValueFromPipelineByPropertyName": null, + "ValueFromRemainingArguments": null, + "HelpMessage": null + }, + { + "Name": "PipelineVariable", + "ParameterType": "System.String", + "Position": null, + "Mandatory": null, + "ValueFromPipeline": null, + "ValueFromPipelineByPropertyName": null, + "ValueFromRemainingArguments": null, + "HelpMessage": null + } + ] + }, + { + "Name": "New-Jekyll", + "CommandType": 1, + "Definition": "New-PSJekyll", + "ParameterName": [ + "Name", + "Blank", + "Force", + "Safe", + "SkipBundle", + "SourcePath", + "DestinationPath", + "LayoutPath", + "PluginPath", + "LiquidProfile", + "Trace" + ], + "Parameter": [ + { + "Name": "Name", + "ParameterType": "System.String", + "Position": null, + "Mandatory": null, + "ValueFromPipeline": null, + "ValueFromPipelineByPropertyName": null, + "ValueFromRemainingArguments": null, + "HelpMessage": null + }, + { + "Name": "Blank", + "ParameterType": "System.Management.Automation.SwitchParameter", + "Position": null, + "Mandatory": null, + "ValueFromPipeline": null, + "ValueFromPipelineByPropertyName": null, + "ValueFromRemainingArguments": null, + "HelpMessage": null + }, + { + "Name": "Force", + "ParameterType": "System.Management.Automation.SwitchParameter", + "Position": null, + "Mandatory": null, + "ValueFromPipeline": null, + "ValueFromPipelineByPropertyName": null, + "ValueFromRemainingArguments": null, + "HelpMessage": null + }, + { + "Name": "Safe", + "ParameterType": "System.Management.Automation.SwitchParameter", + "Position": null, + "Mandatory": null, + "ValueFromPipeline": null, + "ValueFromPipelineByPropertyName": null, + "ValueFromRemainingArguments": null, + "HelpMessage": null + }, + { + "Name": "SkipBundle", + "ParameterType": "System.Management.Automation.SwitchParameter", + "Position": null, + "Mandatory": null, + "ValueFromPipeline": null, + "ValueFromPipelineByPropertyName": null, + "ValueFromRemainingArguments": null, + "HelpMessage": null + }, + { + "Name": "SourcePath", + "ParameterType": "System.String", + "Position": null, + "Mandatory": null, + "ValueFromPipeline": null, + "ValueFromPipelineByPropertyName": null, + "ValueFromRemainingArguments": null, + "HelpMessage": null + }, + { + "Name": "DestinationPath", + "ParameterType": "System.String", + "Position": null, + "Mandatory": null, + "ValueFromPipeline": null, + "ValueFromPipelineByPropertyName": null, + "ValueFromRemainingArguments": null, + "HelpMessage": null + }, + { + "Name": "LayoutPath", + "ParameterType": "System.String", + "Position": null, + "Mandatory": null, + "ValueFromPipeline": null, + "ValueFromPipelineByPropertyName": null, + "ValueFromRemainingArguments": null, + "HelpMessage": null + }, + { + "Name": "PluginPath", + "ParameterType": "System.String[]", + "Position": null, + "Mandatory": null, + "ValueFromPipeline": null, + "ValueFromPipelineByPropertyName": null, + "ValueFromRemainingArguments": null, + "HelpMessage": null + }, + { + "Name": "LiquidProfile", + "ParameterType": "System.Management.Automation.SwitchParameter", + "Position": null, + "Mandatory": null, + "ValueFromPipeline": null, + "ValueFromPipelineByPropertyName": null, + "ValueFromRemainingArguments": null, + "HelpMessage": null + }, + { + "Name": "Trace", + "ParameterType": "System.Management.Automation.SwitchParameter", + "Position": null, + "Mandatory": null, + "ValueFromPipeline": null, + "ValueFromPipelineByPropertyName": null, + "ValueFromRemainingArguments": null, + "HelpMessage": null + } + ] + }, + { + "Name": "Remove-Jekyll", + "CommandType": 1, + "Definition": "Remove-PSJekyll", + "ParameterName": [ + "Path", + "Verbose", + "Debug", + "ErrorAction", + "WarningAction", + "InformationAction", + "ProgressAction", + "ErrorVariable", + "WarningVariable", + "InformationVariable", + "OutVariable", + "OutBuffer", + "PipelineVariable" + ], + "Parameter": [ + { + "Name": "Path", + "ParameterType": "System.String", + "Position": null, + "Mandatory": null, + "ValueFromPipeline": null, + "ValueFromPipelineByPropertyName": null, + "ValueFromRemainingArguments": null, + "HelpMessage": null + }, + { + "Name": "Verbose", + "ParameterType": "System.Management.Automation.SwitchParameter", + "Position": null, + "Mandatory": null, + "ValueFromPipeline": null, + "ValueFromPipelineByPropertyName": null, + "ValueFromRemainingArguments": null, + "HelpMessage": null + }, + { + "Name": "Debug", + "ParameterType": "System.Management.Automation.SwitchParameter", + "Position": null, + "Mandatory": null, + "ValueFromPipeline": null, + "ValueFromPipelineByPropertyName": null, + "ValueFromRemainingArguments": null, + "HelpMessage": null + }, + { + "Name": "ErrorAction", + "ParameterType": "System.Management.Automation.ActionPreference", + "Position": null, + "Mandatory": null, + "ValueFromPipeline": null, + "ValueFromPipelineByPropertyName": null, + "ValueFromRemainingArguments": null, + "HelpMessage": null + }, + { + "Name": "WarningAction", + "ParameterType": "System.Management.Automation.ActionPreference", + "Position": null, + "Mandatory": null, + "ValueFromPipeline": null, + "ValueFromPipelineByPropertyName": null, + "ValueFromRemainingArguments": null, + "HelpMessage": null + }, + { + "Name": "InformationAction", + "ParameterType": "System.Management.Automation.ActionPreference", + "Position": null, + "Mandatory": null, + "ValueFromPipeline": null, + "ValueFromPipelineByPropertyName": null, + "ValueFromRemainingArguments": null, + "HelpMessage": null + }, + { + "Name": "ProgressAction", + "ParameterType": "System.Management.Automation.ActionPreference", + "Position": null, + "Mandatory": null, + "ValueFromPipeline": null, + "ValueFromPipelineByPropertyName": null, + "ValueFromRemainingArguments": null, + "HelpMessage": null + }, + { + "Name": "ErrorVariable", + "ParameterType": "System.String", + "Position": null, + "Mandatory": null, + "ValueFromPipeline": null, + "ValueFromPipelineByPropertyName": null, + "ValueFromRemainingArguments": null, + "HelpMessage": null + }, + { + "Name": "WarningVariable", + "ParameterType": "System.String", + "Position": null, + "Mandatory": null, + "ValueFromPipeline": null, + "ValueFromPipelineByPropertyName": null, + "ValueFromRemainingArguments": null, + "HelpMessage": null + }, + { + "Name": "InformationVariable", + "ParameterType": "System.String", + "Position": null, + "Mandatory": null, + "ValueFromPipeline": null, + "ValueFromPipelineByPropertyName": null, + "ValueFromRemainingArguments": null, + "HelpMessage": null + }, + { + "Name": "OutVariable", + "ParameterType": "System.String", + "Position": null, + "Mandatory": null, + "ValueFromPipeline": null, + "ValueFromPipelineByPropertyName": null, + "ValueFromRemainingArguments": null, + "HelpMessage": null + }, + { + "Name": "OutBuffer", + "ParameterType": "System.Int32", + "Position": null, + "Mandatory": null, + "ValueFromPipeline": null, + "ValueFromPipelineByPropertyName": null, + "ValueFromRemainingArguments": null, + "HelpMessage": null + }, + { + "Name": "PipelineVariable", + "ParameterType": "System.String", + "Position": null, + "Mandatory": null, + "ValueFromPipeline": null, + "ValueFromPipelineByPropertyName": null, + "ValueFromRemainingArguments": null, + "HelpMessage": null + } + ] + }, + { + "Name": "Set-Jekyll", + "CommandType": 1, + "Definition": "Set-PSJekyll", + "ParameterName": [ + "Path", + "PassThru", + "Content", + "MetaData", + "Verbose", + "Debug", + "ErrorAction", + "WarningAction", + "InformationAction", + "ProgressAction", + "ErrorVariable", + "WarningVariable", + "InformationVariable", + "OutVariable", + "OutBuffer", + "PipelineVariable" + ], + "Parameter": [ + { + "Name": "Path", + "ParameterType": "System.String", + "Position": null, + "Mandatory": null, + "ValueFromPipeline": null, + "ValueFromPipelineByPropertyName": null, + "ValueFromRemainingArguments": null, + "HelpMessage": null + }, + { + "Name": "PassThru", + "ParameterType": "System.Management.Automation.SwitchParameter", + "Position": null, + "Mandatory": null, + "ValueFromPipeline": null, + "ValueFromPipelineByPropertyName": null, + "ValueFromRemainingArguments": null, + "HelpMessage": null + }, + { + "Name": "Content", + "ParameterType": "System.Object", + "Position": null, + "Mandatory": null, + "ValueFromPipeline": null, + "ValueFromPipelineByPropertyName": null, + "ValueFromRemainingArguments": null, + "HelpMessage": null + }, + { + "Name": "MetaData", + "ParameterType": "System.Collections.IDictionary", + "Position": null, + "Mandatory": null, + "ValueFromPipeline": null, + "ValueFromPipelineByPropertyName": null, + "ValueFromRemainingArguments": null, + "HelpMessage": null + }, + { + "Name": "Verbose", + "ParameterType": "System.Management.Automation.SwitchParameter", + "Position": null, + "Mandatory": null, + "ValueFromPipeline": null, + "ValueFromPipelineByPropertyName": null, + "ValueFromRemainingArguments": null, + "HelpMessage": null + }, + { + "Name": "Debug", + "ParameterType": "System.Management.Automation.SwitchParameter", + "Position": null, + "Mandatory": null, + "ValueFromPipeline": null, + "ValueFromPipelineByPropertyName": null, + "ValueFromRemainingArguments": null, + "HelpMessage": null + }, + { + "Name": "ErrorAction", + "ParameterType": "System.Management.Automation.ActionPreference", + "Position": null, + "Mandatory": null, + "ValueFromPipeline": null, + "ValueFromPipelineByPropertyName": null, + "ValueFromRemainingArguments": null, + "HelpMessage": null + }, + { + "Name": "WarningAction", + "ParameterType": "System.Management.Automation.ActionPreference", + "Position": null, + "Mandatory": null, + "ValueFromPipeline": null, + "ValueFromPipelineByPropertyName": null, + "ValueFromRemainingArguments": null, + "HelpMessage": null + }, + { + "Name": "InformationAction", + "ParameterType": "System.Management.Automation.ActionPreference", + "Position": null, + "Mandatory": null, + "ValueFromPipeline": null, + "ValueFromPipelineByPropertyName": null, + "ValueFromRemainingArguments": null, + "HelpMessage": null + }, + { + "Name": "ProgressAction", + "ParameterType": "System.Management.Automation.ActionPreference", + "Position": null, + "Mandatory": null, + "ValueFromPipeline": null, + "ValueFromPipelineByPropertyName": null, + "ValueFromRemainingArguments": null, + "HelpMessage": null + }, + { + "Name": "ErrorVariable", + "ParameterType": "System.String", + "Position": null, + "Mandatory": null, + "ValueFromPipeline": null, + "ValueFromPipelineByPropertyName": null, + "ValueFromRemainingArguments": null, + "HelpMessage": null + }, + { + "Name": "WarningVariable", + "ParameterType": "System.String", + "Position": null, + "Mandatory": null, + "ValueFromPipeline": null, + "ValueFromPipelineByPropertyName": null, + "ValueFromRemainingArguments": null, + "HelpMessage": null + }, + { + "Name": "InformationVariable", + "ParameterType": "System.String", + "Position": null, + "Mandatory": null, + "ValueFromPipeline": null, + "ValueFromPipelineByPropertyName": null, + "ValueFromRemainingArguments": null, + "HelpMessage": null + }, + { + "Name": "OutVariable", + "ParameterType": "System.String", + "Position": null, + "Mandatory": null, + "ValueFromPipeline": null, + "ValueFromPipelineByPropertyName": null, + "ValueFromRemainingArguments": null, + "HelpMessage": null + }, + { + "Name": "OutBuffer", + "ParameterType": "System.Int32", + "Position": null, + "Mandatory": null, + "ValueFromPipeline": null, + "ValueFromPipelineByPropertyName": null, + "ValueFromRemainingArguments": null, + "HelpMessage": null + }, + { + "Name": "PipelineVariable", + "ParameterType": "System.String", + "Position": null, + "Mandatory": null, + "ValueFromPipeline": null, + "ValueFromPipelineByPropertyName": null, + "ValueFromRemainingArguments": null, + "HelpMessage": null + } + ] + }, + { + "Name": "Start-Jekyll", + "CommandType": 1, + "Definition": "Start-PSJekyll", + "ParameterName": [ + "Name", + "Config", + "SourcePath", + "DestinationPath", + "HostHeader", + "Port", + "PluginPath", + "ShowDirectoryList", + "LiveReload", + "LiquidProfile", + "Trace", + "Watch", + "PreviewFuture", + "BaseUrl", + "Detach", + "Incremental", + "Verbose", + "Debug", + "ErrorAction", + "WarningAction", + "InformationAction", + "ProgressAction", + "ErrorVariable", + "WarningVariable", + "InformationVariable", + "OutVariable", + "OutBuffer", + "PipelineVariable" + ], + "Parameter": [ + { + "Name": "Name", + "ParameterType": "System.String", + "Position": null, + "Mandatory": null, + "ValueFromPipeline": null, + "ValueFromPipelineByPropertyName": null, + "ValueFromRemainingArguments": null, + "HelpMessage": null + }, + { + "Name": "Config", + "ParameterType": "System.String[]", + "Position": null, + "Mandatory": null, + "ValueFromPipeline": null, + "ValueFromPipelineByPropertyName": null, + "ValueFromRemainingArguments": null, + "HelpMessage": null + }, + { + "Name": "SourcePath", + "ParameterType": "System.String", + "Position": null, + "Mandatory": null, + "ValueFromPipeline": null, + "ValueFromPipelineByPropertyName": null, + "ValueFromRemainingArguments": null, + "HelpMessage": null + }, + { + "Name": "DestinationPath", + "ParameterType": "System.String", + "Position": null, + "Mandatory": null, + "ValueFromPipeline": null, + "ValueFromPipelineByPropertyName": null, + "ValueFromRemainingArguments": null, + "HelpMessage": null + }, + { + "Name": "HostHeader", + "ParameterType": "System.String", + "Position": null, + "Mandatory": null, + "ValueFromPipeline": null, + "ValueFromPipelineByPropertyName": null, + "ValueFromRemainingArguments": null, + "HelpMessage": null + }, + { + "Name": "Port", + "ParameterType": "System.UInt32", + "Position": null, + "Mandatory": null, + "ValueFromPipeline": null, + "ValueFromPipelineByPropertyName": null, + "ValueFromRemainingArguments": null, + "HelpMessage": null + }, + { + "Name": "PluginPath", + "ParameterType": "System.String[]", + "Position": null, + "Mandatory": null, + "ValueFromPipeline": null, + "ValueFromPipelineByPropertyName": null, + "ValueFromRemainingArguments": null, + "HelpMessage": null + }, + { + "Name": "ShowDirectoryList", + "ParameterType": "System.Management.Automation.SwitchParameter", + "Position": null, + "Mandatory": null, + "ValueFromPipeline": null, + "ValueFromPipelineByPropertyName": null, + "ValueFromRemainingArguments": null, + "HelpMessage": null + }, + { + "Name": "LiveReload", + "ParameterType": "System.Management.Automation.SwitchParameter", + "Position": null, + "Mandatory": null, + "ValueFromPipeline": null, + "ValueFromPipelineByPropertyName": null, + "ValueFromRemainingArguments": null, + "HelpMessage": null + }, + { + "Name": "LiquidProfile", + "ParameterType": "System.Management.Automation.SwitchParameter", + "Position": null, + "Mandatory": null, + "ValueFromPipeline": null, + "ValueFromPipelineByPropertyName": null, + "ValueFromRemainingArguments": null, + "HelpMessage": null + }, + { + "Name": "Trace", + "ParameterType": "System.Management.Automation.SwitchParameter", + "Position": null, + "Mandatory": null, + "ValueFromPipeline": null, + "ValueFromPipelineByPropertyName": null, + "ValueFromRemainingArguments": null, + "HelpMessage": null + }, + { + "Name": "Watch", + "ParameterType": "System.Management.Automation.SwitchParameter", + "Position": null, + "Mandatory": null, + "ValueFromPipeline": null, + "ValueFromPipelineByPropertyName": null, + "ValueFromRemainingArguments": null, + "HelpMessage": null + }, + { + "Name": "PreviewFuture", + "ParameterType": "System.Management.Automation.SwitchParameter", + "Position": null, + "Mandatory": null, + "ValueFromPipeline": null, + "ValueFromPipelineByPropertyName": null, + "ValueFromRemainingArguments": null, + "HelpMessage": null + }, + { + "Name": "BaseUrl", + "ParameterType": "System.String", + "Position": null, + "Mandatory": null, + "ValueFromPipeline": null, + "ValueFromPipelineByPropertyName": null, + "ValueFromRemainingArguments": null, + "HelpMessage": null + }, + { + "Name": "Detach", + "ParameterType": "System.Management.Automation.SwitchParameter", + "Position": null, + "Mandatory": null, + "ValueFromPipeline": null, + "ValueFromPipelineByPropertyName": null, + "ValueFromRemainingArguments": null, + "HelpMessage": null + }, + { + "Name": "Incremental", + "ParameterType": "System.Management.Automation.SwitchParameter", + "Position": null, + "Mandatory": null, + "ValueFromPipeline": null, + "ValueFromPipelineByPropertyName": null, + "ValueFromRemainingArguments": null, + "HelpMessage": null + }, + { + "Name": "Verbose", + "ParameterType": "System.Management.Automation.SwitchParameter", + "Position": null, + "Mandatory": null, + "ValueFromPipeline": null, + "ValueFromPipelineByPropertyName": null, + "ValueFromRemainingArguments": null, + "HelpMessage": null + }, + { + "Name": "Debug", + "ParameterType": "System.Management.Automation.SwitchParameter", + "Position": null, + "Mandatory": null, + "ValueFromPipeline": null, + "ValueFromPipelineByPropertyName": null, + "ValueFromRemainingArguments": null, + "HelpMessage": null + }, + { + "Name": "ErrorAction", + "ParameterType": "System.Management.Automation.ActionPreference", + "Position": null, + "Mandatory": null, + "ValueFromPipeline": null, + "ValueFromPipelineByPropertyName": null, + "ValueFromRemainingArguments": null, + "HelpMessage": null + }, + { + "Name": "WarningAction", + "ParameterType": "System.Management.Automation.ActionPreference", + "Position": null, + "Mandatory": null, + "ValueFromPipeline": null, + "ValueFromPipelineByPropertyName": null, + "ValueFromRemainingArguments": null, + "HelpMessage": null + }, + { + "Name": "InformationAction", + "ParameterType": "System.Management.Automation.ActionPreference", + "Position": null, + "Mandatory": null, + "ValueFromPipeline": null, + "ValueFromPipelineByPropertyName": null, + "ValueFromRemainingArguments": null, + "HelpMessage": null + }, + { + "Name": "ProgressAction", + "ParameterType": "System.Management.Automation.ActionPreference", + "Position": null, + "Mandatory": null, + "ValueFromPipeline": null, + "ValueFromPipelineByPropertyName": null, + "ValueFromRemainingArguments": null, + "HelpMessage": null + }, + { + "Name": "ErrorVariable", + "ParameterType": "System.String", + "Position": null, + "Mandatory": null, + "ValueFromPipeline": null, + "ValueFromPipelineByPropertyName": null, + "ValueFromRemainingArguments": null, + "HelpMessage": null + }, + { + "Name": "WarningVariable", + "ParameterType": "System.String", + "Position": null, + "Mandatory": null, + "ValueFromPipeline": null, + "ValueFromPipelineByPropertyName": null, + "ValueFromRemainingArguments": null, + "HelpMessage": null + }, + { + "Name": "InformationVariable", + "ParameterType": "System.String", + "Position": null, + "Mandatory": null, + "ValueFromPipeline": null, + "ValueFromPipelineByPropertyName": null, + "ValueFromRemainingArguments": null, + "HelpMessage": null + }, + { + "Name": "OutVariable", + "ParameterType": "System.String", + "Position": null, + "Mandatory": null, + "ValueFromPipeline": null, + "ValueFromPipelineByPropertyName": null, + "ValueFromRemainingArguments": null, + "HelpMessage": null + }, + { + "Name": "OutBuffer", + "ParameterType": "System.Int32", + "Position": null, + "Mandatory": null, + "ValueFromPipeline": null, + "ValueFromPipelineByPropertyName": null, + "ValueFromRemainingArguments": null, + "HelpMessage": null + }, + { + "Name": "PipelineVariable", + "ParameterType": "System.String", + "Position": null, + "Mandatory": null, + "ValueFromPipeline": null, + "ValueFromPipelineByPropertyName": null, + "ValueFromRemainingArguments": null, + "HelpMessage": null + } + ] + }, + { + "Name": "Stop-Jekyll", + "CommandType": 1, + "Definition": "Stop-PSJekyll", + "ParameterName": [ + "Name", + "Verbose", + "Debug", + "ErrorAction", + "WarningAction", + "InformationAction", + "ProgressAction", + "ErrorVariable", + "WarningVariable", + "InformationVariable", + "OutVariable", + "OutBuffer", + "PipelineVariable" + ], + "Parameter": [ + { + "Name": "Name", + "ParameterType": "System.String", + "Position": null, + "Mandatory": null, + "ValueFromPipeline": null, + "ValueFromPipelineByPropertyName": null, + "ValueFromRemainingArguments": null, + "HelpMessage": null + }, + { + "Name": "Verbose", + "ParameterType": "System.Management.Automation.SwitchParameter", + "Position": null, + "Mandatory": null, + "ValueFromPipeline": null, + "ValueFromPipelineByPropertyName": null, + "ValueFromRemainingArguments": null, + "HelpMessage": null + }, + { + "Name": "Debug", + "ParameterType": "System.Management.Automation.SwitchParameter", + "Position": null, + "Mandatory": null, + "ValueFromPipeline": null, + "ValueFromPipelineByPropertyName": null, + "ValueFromRemainingArguments": null, + "HelpMessage": null + }, + { + "Name": "ErrorAction", + "ParameterType": "System.Management.Automation.ActionPreference", + "Position": null, + "Mandatory": null, + "ValueFromPipeline": null, + "ValueFromPipelineByPropertyName": null, + "ValueFromRemainingArguments": null, + "HelpMessage": null + }, + { + "Name": "WarningAction", + "ParameterType": "System.Management.Automation.ActionPreference", + "Position": null, + "Mandatory": null, + "ValueFromPipeline": null, + "ValueFromPipelineByPropertyName": null, + "ValueFromRemainingArguments": null, + "HelpMessage": null + }, + { + "Name": "InformationAction", + "ParameterType": "System.Management.Automation.ActionPreference", + "Position": null, + "Mandatory": null, + "ValueFromPipeline": null, + "ValueFromPipelineByPropertyName": null, + "ValueFromRemainingArguments": null, + "HelpMessage": null + }, + { + "Name": "ProgressAction", + "ParameterType": "System.Management.Automation.ActionPreference", + "Position": null, + "Mandatory": null, + "ValueFromPipeline": null, + "ValueFromPipelineByPropertyName": null, + "ValueFromRemainingArguments": null, + "HelpMessage": null + }, + { + "Name": "ErrorVariable", + "ParameterType": "System.String", + "Position": null, + "Mandatory": null, + "ValueFromPipeline": null, + "ValueFromPipelineByPropertyName": null, + "ValueFromRemainingArguments": null, + "HelpMessage": null + }, + { + "Name": "WarningVariable", + "ParameterType": "System.String", + "Position": null, + "Mandatory": null, + "ValueFromPipeline": null, + "ValueFromPipelineByPropertyName": null, + "ValueFromRemainingArguments": null, + "HelpMessage": null + }, + { + "Name": "InformationVariable", + "ParameterType": "System.String", + "Position": null, + "Mandatory": null, + "ValueFromPipeline": null, + "ValueFromPipelineByPropertyName": null, + "ValueFromRemainingArguments": null, + "HelpMessage": null + }, + { + "Name": "OutVariable", + "ParameterType": "System.String", + "Position": null, + "Mandatory": null, + "ValueFromPipeline": null, + "ValueFromPipelineByPropertyName": null, + "ValueFromRemainingArguments": null, + "HelpMessage": null + }, + { + "Name": "OutBuffer", + "ParameterType": "System.Int32", + "Position": null, + "Mandatory": null, + "ValueFromPipeline": null, + "ValueFromPipelineByPropertyName": null, + "ValueFromRemainingArguments": null, + "HelpMessage": null + }, + { + "Name": "PipelineVariable", + "ParameterType": "System.String", + "Position": null, + "Mandatory": null, + "ValueFromPipeline": null, + "ValueFromPipelineByPropertyName": null, + "ValueFromRemainingArguments": null, + "HelpMessage": null + } + ] + } +] \ No newline at end of file diff --git a/docs/_data/PSModule/FunctionNames.json b/docs/_data/PSModule/FunctionNames.json new file mode 100644 index 0000000..1ddd5ff --- /dev/null +++ b/docs/_data/PSModule/FunctionNames.json @@ -0,0 +1,7 @@ +[ + "New-PSJekyll", + "Remove-PSJekyll", + "Set-PSJekyll", + "Start-PSJekyll", + "Stop-PSJekyll" +] \ No newline at end of file diff --git a/docs/_data/PSModule/Info.json b/docs/_data/PSModule/Info.json new file mode 100644 index 0000000..5738161 --- /dev/null +++ b/docs/_data/PSModule/Info.json @@ -0,0 +1,23 @@ +{ + "Name": "PSJekyll", + "Version": { + "Major": 0, + "Minor": 1, + "Build": -1, + "Revision": -1, + "MajorRevision": -1, + "MinorRevision": -1 + }, + "Description": "Scarily Simple Static Sites with Jekyll and PowerShell", + "Copyright": "2024", + "CompanyName": "PowerShellWeb", + "Author": "James Brundage", + "Tags": [ + "PowerShellWeb", + "Jekyll", + "Docker", + "Container", + "GitHubAction", + "StaticSite" + ] +} \ No newline at end of file diff --git a/docs/_data/PSModule/TypeNames.json b/docs/_data/PSModule/TypeNames.json new file mode 100644 index 0000000..bf2496d --- /dev/null +++ b/docs/_data/PSModule/TypeNames.json @@ -0,0 +1,5 @@ +[ + "PSJekyll", + "PSJekyll.Site", + "PSJekyll.Template" +] \ No newline at end of file diff --git a/docs/_data/PSModule/VariableNames.json b/docs/_data/PSModule/VariableNames.json new file mode 100644 index 0000000..d19c8e6 --- /dev/null +++ b/docs/_data/PSModule/VariableNames.json @@ -0,0 +1 @@ +"PSJekyll" \ No newline at end of file diff --git a/docs/_includes/4bitcss.html b/docs/_includes/4bitcss.html new file mode 100644 index 0000000..8d1ec76 --- /dev/null +++ b/docs/_includes/4bitcss.html @@ -0,0 +1,5 @@ +{% if page.palette %} + +{% elsif site.palette %} + +{% endif %} \ No newline at end of file diff --git a/docs/_includes/Contributor.md b/docs/_includes/Contributor.md new file mode 100644 index 0000000..e69de29 diff --git a/docs/_includes/Copyright.html b/docs/_includes/Copyright.html new file mode 100644 index 0000000..a160c7d --- /dev/null +++ b/docs/_includes/Copyright.html @@ -0,0 +1,9 @@ +© {% if page.copyright %} + {{page.copyright}} +{% elsif site.copyright %} + {{site.copyright}} +{% elsif site.data.PSModuleInfo.Copyright %} + {{site.data.PSModuleInfo.Copyright}} +{% else %} + {{ site.time | date: '%Y' }} {{ site.author }} +{% endif %} \ No newline at end of file diff --git a/docs/_includes/Footer.html b/docs/_includes/Footer.html new file mode 100644 index 0000000..4137469 --- /dev/null +++ b/docs/_includes/Footer.html @@ -0,0 +1,9 @@ +
+{% if page.footer %} + {{page.footer}} +{% elsif site.footer %} + {{site.footer}} +{% else %} + {% include Copyright.html %} +{% endif %} +
\ No newline at end of file diff --git a/docs/_includes/GitHubLink.html b/docs/_includes/GitHubLink.html new file mode 100644 index 0000000..3752c46 --- /dev/null +++ b/docs/_includes/GitHubLink.html @@ -0,0 +1,3 @@ +{% if site.github.repository_url %} +GitHub +{% endif %} \ No newline at end of file diff --git a/docs/_includes/GoogleAnalytics.html b/docs/_includes/GoogleAnalytics.html new file mode 100644 index 0000000..bde8fa8 --- /dev/null +++ b/docs/_includes/GoogleAnalytics.html @@ -0,0 +1,10 @@ +{% if site.analyticsId %} + + + +{% endif %} \ No newline at end of file diff --git a/docs/_includes/GoogleFont.html b/docs/_includes/GoogleFont.html new file mode 100644 index 0000000..eef46f2 --- /dev/null +++ b/docs/_includes/GoogleFont.html @@ -0,0 +1,20 @@ +{% if page.googleFont %} + + +{% elsif site.googleFont %} + + +{% else %} + + +{% endif %} +{% if page.codeFont %} + + +{% elsif site.codeFont %} + + +{% else %} + + +{% endif %} \ No newline at end of file diff --git a/docs/_includes/Htmx.html b/docs/_includes/Htmx.html new file mode 100644 index 0000000..a8cfa5b --- /dev/null +++ b/docs/_includes/Htmx.html @@ -0,0 +1,3 @@ +{% if page.htmx or site.htmx %} + +{% endif %} \ No newline at end of file diff --git a/docs/_includes/ImportMap.html b/docs/_includes/ImportMap.html new file mode 100644 index 0000000..af3a6ca --- /dev/null +++ b/docs/_includes/ImportMap.html @@ -0,0 +1,25 @@ +{% if page.imports %} + {% assign importMap = page.imports %} +{% elsif page.importMap %} + {% assign importMap = page.importMap %} +{% elsif site.imports %} + {% assign importMap = site.imports %} +{% elsif site.importMap %} + {% assign importMap = site.importMap %} +{% elsif site.data.imports %} + {% assign importMap = site.data.imports %} +{% elsif site.data.importMap %} + {% assign importMap = site.data.importMap %} +{% endif %} +{% if importMap %} + +{% endif %} \ No newline at end of file diff --git a/docs/_includes/Margin.html b/docs/_includes/Margin.html new file mode 100644 index 0000000..f5f3c60 --- /dev/null +++ b/docs/_includes/Margin.html @@ -0,0 +1,12 @@ +{% if page.margin %} + +{% elsif site.margin %} + +{% else %} + +{% endif %} \ No newline at end of file diff --git a/docs/_includes/Menu.html b/docs/_includes/Menu.html new file mode 100644 index 0000000..14a7574 --- /dev/null +++ b/docs/_includes/Menu.html @@ -0,0 +1,147 @@ +{% capture TopLeftMenu %} + {{page.menu.TopLeft}} + {{site.menu.TopLeft}} + {{site.data.menu.TopLeft}} +{% endcapture %} +{% assign TopLeftMenu = TopLeftMenu | strip %} + +{% capture TopRightMenu %} + {{page.menu.TopRight}} + {{site.menu.TopRight}} + {{site.data.menu.TopRight}} + {% unless site.NoGitHubLink or site.NoLink %} + {% include GitHubLink.html %} + {% endunless %} +{% endcapture %} +{% assign TopRightMenu = TopRightMenu | strip %} + +{% capture TopCenterMenu %} + {{page.menu.TopCenter}} + {{site.menu.TopCenter}} + {{site.data.menu.TopCenter}} +{% endcapture %} +{% assign TopCenterMenu = TopCenterMenu | strip %} + +{% capture BottomLeftMenu %} + {{page.menu.BottomLeft}} + {{site.menu.BottomLeft}} + {{site.data.menu.BottomLeft}} +{% endcapture %} +{% assign BottomLeftMenu = BottomLeftMenu | strip %} + +{% capture BottomRightMenu %} + {{page.menu.BottomRight}} + {{site.menu.BottomRight}} + {{site.data.menu.BottomRight}} +{% endcapture %} +{% assign BottomRightMenu = BottomRightMenu | strip %} + +{% capture BottomCenterMenu %} + {{page.menu.BottomCenter}} + {{site.menu.BottomCenter}} + {{site.data.menu.BottomCenter}} +{% endcapture %} +{% assign BottomCenterMenu = BottomCenterMenu | strip %} + +{% capture LeftCenterMenu %} + {{page.menu.LeftCenter}} + {{site.menu.LeftCenter}} + {{site.data.menu.LeftCenter}} +{% endcapture %} +{% assign LeftCenterMenu = LeftCenterMenu | strip %} + +{% capture RightCenterMenu %} + {{page.menu.RightCenter}} + {{site.menu.RightCenter}} + {{site.data.menu.RightCenter}} +{% endcapture %} +{% assign RightCenterMenu = RightCenterMenu | strip %} + +{% if TopLeftMenu or TopRightMenu or TopCenterMenu or BottomLeftMenu or BottomRightMenu or BottomCenterMenu or LeftCenterMenu or RightCenterMenu %} + +{% endif %} + +{% if TopLeftMenu != "" %} + + {{TopLeftMenu}} + +{% endif %} + +{% if TopRightMenu != "" %} + + {{TopRightMenu}} + +{% endif %} + +{% if TopCenterMenu != "" %} + + {{TopCenterMenu}} + +{% endif %} + +{% if BottomLeftMenu != "" %} + + {{BottomLeftMenu}} + +{% endif %} + +{% if BottomRightMenu != "" %} + + {{BottomRightMenu}} + +{% endif %} + +{% if BottomCenterMenu != "" %} + + {{BottomCenterMenu}} + +{% endif %} + +{% if LeftCenterMenu != "" %} + + {{LeftCenterMenu}} + +{% endif %} + +{% if RightCenterMenu != "" %} + + {{RightCenterMenu}} + +{% endif %} \ No newline at end of file diff --git a/docs/_includes/OpenGraph.html b/docs/_includes/OpenGraph.html new file mode 100644 index 0000000..c2a4fb5 --- /dev/null +++ b/docs/_includes/OpenGraph.html @@ -0,0 +1,44 @@ + +{% if page.title %} + +{% else %} + +{% endif %} +{% if page.type %} + +{% else %} + +{% endif %} +{% if page.description %} + + + +{% elsif content %} + + + + + +{% elsif site.description %} + + + +{% endif %} +{% if page.date %} + +{% endif %} +{% if page.url %} + + + +{% endif %} + +{% if page.image %} + + + +{% elsif site.image %} + + + +{% endif %} \ No newline at end of file diff --git a/docs/_includes/OrgMember.md b/docs/_includes/OrgMember.md new file mode 100644 index 0000000..e69de29 diff --git a/docs/_includes/PSAlias.md b/docs/_includes/PSAlias.md new file mode 100644 index 0000000..95c1c0d --- /dev/null +++ b/docs/_includes/PSAlias.md @@ -0,0 +1,4 @@ +| Alias | Command | +|:-|-:|{% for alias in site.data.PSModule.Aliases %} +|{{ alias.Name }}|[{{ alias.Definition }}](/{{alias.Definition}})| +{% endfor %} \ No newline at end of file diff --git a/docs/_includes/PSCmdlet.md b/docs/_includes/PSCmdlet.md new file mode 100644 index 0000000..15fafc4 --- /dev/null +++ b/docs/_includes/PSCmdlet.md @@ -0,0 +1,3 @@ +{% for cmdletName in site.data.PSModule.CmdletNames %} +* [{{ cmdletName }}](/{{cmdletName}}) +{% endfor %} \ No newline at end of file diff --git a/docs/_includes/PSFunctions.md b/docs/_includes/PSFunctions.md new file mode 100644 index 0000000..ac0680b --- /dev/null +++ b/docs/_includes/PSFunctions.md @@ -0,0 +1,3 @@ +{% for functionName in site.data.PSModule.FunctionNames %} +* [{{ functionName }}](/{{functionName}}) +{% endfor %} \ No newline at end of file diff --git a/docs/_includes/PSTag.md b/docs/_includes/PSTag.md new file mode 100644 index 0000000..391f486 --- /dev/null +++ b/docs/_includes/PSTag.md @@ -0,0 +1,3 @@ +{% for tagName in site.data.PSModule.Info.Tags %} +* [{{ tagName }}](https://www.powershellgallery.com/packages?q=Tags%3A%22{{tagName}}%22) +{% endfor %} \ No newline at end of file diff --git a/docs/_includes/PSTypeName.md b/docs/_includes/PSTypeName.md new file mode 100644 index 0000000..3bd71d8 --- /dev/null +++ b/docs/_includes/PSTypeName.md @@ -0,0 +1,3 @@ +{% for typeName in site.data.PSModule.TypeNames %} +* [{{ typeName }}](/{{typeName | replace: ".", "/"}}) +{% endfor %} \ No newline at end of file diff --git a/docs/_includes/Releases.md b/docs/_includes/Releases.md new file mode 100644 index 0000000..02b6831 --- /dev/null +++ b/docs/_includes/Releases.md @@ -0,0 +1,4 @@ +{% for release in site.github.releases %} +# [{{ release.tag_name }}]({{ release.html_url }}) +{{ release.body }} +{% endfor %} \ No newline at end of file diff --git a/docs/_includes/Repos.md b/docs/_includes/Repos.md new file mode 100644 index 0000000..fdc09e8 --- /dev/null +++ b/docs/_includes/Repos.md @@ -0,0 +1,3 @@ +{% for repository in site.github.public_repositories %} + * [{{ repository.name }}]({{ repository.html_url }}) +{% endfor %} \ No newline at end of file diff --git a/docs/_includes/SiteTree.html b/docs/_includes/SiteTree.html new file mode 100644 index 0000000..b64882c --- /dev/null +++ b/docs/_includes/SiteTree.html @@ -0,0 +1,20 @@ +{% assign pages_by_url = site.pages | sort: "url" %} +{% assign page_depth = 0 %} + +{% for page in pages_by_url %} + {% if page.title == nil %} + {% continue %} + {% endif %} + {% assign page_parts = page.url | split: "/" %} + {% if page_parts.size > page_depth %} + {% assign page_depth = page_parts.size %} +
    + {% endif %} + {% if page_parts.size < page_depth %} + {% assign page_depth = page_parts.size %} +
+ {% endif %} +
  • +{{ page.title }} +
  • +{% endfor %} \ No newline at end of file diff --git a/docs/_includes/Stylesheet.html b/docs/_includes/Stylesheet.html new file mode 100644 index 0000000..3a32d64 --- /dev/null +++ b/docs/_includes/Stylesheet.html @@ -0,0 +1,15 @@ +{% if site.data.stylesheet %} + {% for stylesheet in site.data.stylesheet %} + + {% endfor %} +{% endif %} +{% if page.stylesheet %} + {% for stylesheet in page.stylesheet %} + + {% endfor %} +{% endif %} +{% if include.stylesheet %} + {% for stylesheet in include.stylesheet %} + + {% endfor %} +{% endif %} \ No newline at end of file diff --git a/docs/_layouts/Default.html b/docs/_layouts/Default.html new file mode 100644 index 0000000..9d0f2cb --- /dev/null +++ b/docs/_layouts/Default.html @@ -0,0 +1,27 @@ +--- + +title: Default.html +--- + + + + + + + {% include GoogleAnalytics.html %} + {% include ImportMap.html %} + {% include OpenGraph.html %} + {% include GoogleFont.html %} + {% include 4bitcss.html %} + {% include Margin.html %} + {% include Stylesheet.html %} + {% include Htmx.html %} + + + +{% include Menu.html %} + +{{content}} + +{% include Footer.html %} +