diff --git a/.github/workflows/JSON-LD-Build.yml b/.github/workflows/JSON-LD-Build.yml
index e9d134e..aa451c8 100644
--- a/.github/workflows/JSON-LD-Build.yml
+++ b/.github/workflows/JSON-LD-Build.yml
@@ -35,7 +35,7 @@ jobs:
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
+ uses: actions/checkout@v2
- name: RunPester
id: RunPester
shell: pwsh
@@ -92,6 +92,9 @@ jobs:
$result =
Invoke-Pester -PassThru -Verbose -OutputFile ".\$moduleName.TestResults.xml" -OutputFormat NUnitXml @codeCoverageParameters
+ "::set-output name=TotalCount::$($result.TotalCount)",
+ "::set-output name=PassedCount::$($result.PassedCount)",
+ "::set-output name=FailedCount::$($result.FailedCount)" | Out-Host
if ($result.FailedCount -gt 0) {
"::debug:: $($result.FailedCount) tests failed"
foreach ($r in $result.TestResult) {
@@ -491,20 +494,6 @@ jobs:
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
diff --git a/Build/GitHub/Jobs/JsonLD.psd1 b/Build/GitHub/Jobs/JsonLD.psd1
index 8c2f390..288a11f 100644
--- a/Build/GitHub/Jobs/JsonLD.psd1
+++ b/Build/GitHub/Jobs/JsonLD.psd1
@@ -5,28 +5,7 @@
@{
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'
}
+ 'RunEZOut'
)
}
\ No newline at end of file
diff --git a/Build/JSON-LD.ezout.ps1 b/Build/JSON-LD.ezout.ps1
new file mode 100644
index 0000000..6b9d2fa
--- /dev/null
+++ b/Build/JSON-LD.ezout.ps1
@@ -0,0 +1,39 @@
+#requires -Module EZOut
+# Install-Module EZOut or https://github.com/StartAutomating/EZOut
+$myFile = $MyInvocation.MyCommand.ScriptBlock.File
+$myModuleName = $MyInvocation.MyCommand.Name -replace '\.ezout.ps1$'
+$myRoot = $myFile | Split-Path | Split-Path
+Push-Location $myRoot
+$formatting = @(
+ # Add your own Write-FormatView here,
+ # or put them in a Formatting or Views directory
+ foreach ($potentialDirectory in 'Formatting','Views','Types') {
+ Join-Path $myRoot $potentialDirectory |
+ Get-ChildItem -ea ignore |
+ Import-FormatView -FilePath {$_.Fullname}
+ }
+)
+
+$destinationRoot = $myRoot
+
+if ($formatting) {
+ $myFormatFilePath = Join-Path $destinationRoot "$myModuleName.format.ps1xml"
+ # You can also output to multiple paths by passing a hashtable to -OutputPath.
+ $formatting | Out-FormatData -Module $MyModuleName -OutputPath $myFormatFilePath
+}
+
+$types = @(
+ # Add your own Write-TypeView statements here
+ # or declare them in the 'Types' directory
+ Join-Path $myRoot Types |
+ Get-Item -ea ignore |
+ Import-TypeView
+
+)
+
+if ($types) {
+ $myTypesFilePath = Join-Path $destinationRoot "$myModuleName.types.ps1xml"
+ # You can also output to multiple paths by passing a hashtable to -OutputPath.
+ $types | Out-TypeData -OutputPath $myTypesFilePath
+}
+Pop-Location
diff --git a/CHANGELOG.md b/CHANGELOG.md
index f3830db..049b0d5 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,10 +1,32 @@
-> Like It? [Star It](https://github.com/PowerShellWeb/JSON-LD)
-> Love It? [Support It](https://github.com/sponsors/StartAutomating)
+Please:
+
+* [Like, Share, and Subscribe](https://github.com/PowerShellWeb/JSON-LD)
+* [Support Us](https://github.com/sponsors/StartAutomating)
+
+---
+
+## JSON-LD 0.1.1
+
+* Updating Examples (#13)
+* Simplfiying module scaffolding (#15)
+* Building types with EZOut (#5)
+* Supporting file input (#23)
+* `Get-JSONLD -as`
+ * `Get-JSONLD -as json` (#16)
+ * `Get-JSONLD -as html` (#17)
+ * `Get-JSONLD -as script` (#18)
+ * `Get-JSONLD -as xml` (#19)
+* Adding conversion to JsonSchema (#21)
+* Adding conversion to At Protocol Lexicons (#22)
+
+---
## JSON-LD 0.1
Caching JSON-LD requests
+---
+
## JSON-LD 0.0.1
Get Linked Data from any page
diff --git a/Commands/Get-JsonLD.ps1 b/Commands/Get-JsonLD.ps1
index c69504e..a7a5b71 100644
--- a/Commands/Get-JsonLD.ps1
+++ b/Commands/Get-JsonLD.ps1
@@ -8,7 +8,7 @@ function Get-JsonLD {
This is a format used by many websites to provide structured data about their content.
.EXAMPLE
# Want to get information about a movie? Linked Data to the rescue!
- Get-JsonLD -Url https://www.imdb.com/title/tt0211915/
+ Get-JsonLD -Url https://letterboxd.com/film/amelie/
.EXAMPLE
# Want information about an article? Lots of news sites use this format.
Get-JsonLD https://www.thebulwark.com/p/mahmoud-khalil-immigration-detention-first-amendment-free-speech-rights
@@ -21,9 +21,30 @@ function Get-JsonLD {
param(
# The URL that may contain JSON-LD data
[Parameter(Mandatory, ValueFromPipeline, ValueFromPipelineByPropertyName)]
+ [Alias('href')]
[Uri]
$Url,
+ <#
+
+ If set, will the output as:
+
+ |as|is|
+ |-|-|
+ |html|the response as text|
+ |json|the match as json|
+ |*jsonld`|ld`|linkedData*|the match as linked data|'
+ |script|the script tag|
+ |xml|the script tag, as xml|
+
+ #>
+ [ValidateSet('html', 'json', 'jsonld', 'ld', 'linkedData', 'script', 'xml')]
+ [string]
+ $as = 'jsonld',
+
+ [switch]
+ $RawHtml,
+
# If set, will force the request to be made even if the URL has already been cached.
[switch]
$Force
@@ -46,39 +67,146 @@ application/ld\+json # The type that indicates linked d
'@, 'IgnoreCase,IgnorePatternWhitespace','00:00:00.1')
# Initialize the cache for JSON-LD requests
- if (-not $script:JsonLDRequestCache) {
- $script:JsonLDRequestCache = [Ordered]@{}
+ if (-not $script:Cache) {
+ $script:Cache = [Ordered]@{}
+ }
+
+ filter output {
+ $in = $_
+ $mySelf = $MyInvocation.MyCommand
+ if ($in.'@context' -is [string]) {
+ $context = $in.'@context'
+ }
+ if ($in.'@graph') {
+ if ($in.pstypenames -ne 'application/ld+json') {
+ $in.pstypenames.insert(0,'application/ld+json')
+ }
+ foreach ($graphObject in $in.'@graph') {
+ $null = $graphObject |
+ & $mySelf
+ }
+ }
+ elseif ($in.'@type') {
+
+ $typeName = if ($context) {
+ $context, $in.'@type' -join '/'
+ } else {
+ $in.'@type'
+ }
+
+ if ($in.pstypenames -ne 'application/ld+json') {
+ $in.pstypenames.insert(0,'application/ld+json')
+ }
+ if ($in.pstypenames -ne $typeName) {
+ $in.pstypenames.insert(0,$typeName)
+ }
+
+ foreach ($property in $in.psobject.properties) {
+ if ($property.value.'@type') {
+ $null = $property.value |
+ & $mySelf
+ }
+ }
+ }
+ $in
+ }
+
+ $foreachFile = {
+ $inFile = $_.FullName
+ try {
+
+ Get-Content -LiteralPath $_.FullName -Raw |
+ ConvertFrom-Json |
+ output
+ } catch {
+ Write-Verbose "$($inFile.FullName) : $_"
+ }
}
}
process {
+ if ($url.IsFile -or
+ -not $url.AbsoluteUri
+ ) {
+ if (Test-Path $url.OriginalString) {
+ Get-ChildItem $url.OriginalString -File |
+ Foreach-Object $foreachFile
+ } elseif ($MyInvocation.MyCommand.Module -and
+ (Test-Path (
+ Join-Path (
+ $MyInvocation.MyCommand.Module | Split-Path
+ ) $url.OriginalString
+ ))
+ ) {
+ Get-ChildItem -Path (
+ Join-Path (
+ $MyInvocation.MyCommand.Module | Split-Path
+ ) $url.OriginalString
+ ) -File |
+ Foreach-Object $foreachFile
+ }
+
+ return
+ }
+
$restResponse =
- if ($Force -or -not $script:JsonLDRequestCache[$url]) {
- $script:JsonLDRequestCache[$url] = Invoke-RestMethod -Uri $Url
- $script:JsonLDRequestCache[$url]
+ if ($Force -or -not $script:Cache[$url]) {
+ $script:Cache[$url] = Invoke-RestMethod -Uri $Url
+ $script:Cache[$url]
} else {
- $script:JsonLDRequestCache[$url]
+ $script:Cache[$url]
}
+
+ if ($as -eq 'html') {
+ return $restResponse
+ }
+
+ # Find all linked data tags within the response
foreach ($match in $linkedDataRegex.Matches("$restResponse")) {
+ # If we want the result as xml
+ if ($As -eq 'xml') {
+ # try to cast it
+ $matchXml ="$match" -as [xml]
+ if ($matchXml) {
+ # and output it if found.
+ $matchXml
+ continue
+ } else {
+ # otherwise, fall back to the `
+
+
+ GetLexicon
+
+
+
+
+
\ No newline at end of file
diff --git a/README.md b/README.md
index 77845e0..02d222d 100644
--- a/README.md
+++ b/README.md
@@ -15,7 +15,7 @@ This information can be useful in any number of fun and useful PowerShell scenar
For example, let's get information about a movie.
~~~PowerShell
-Get-JsonLD https://www.imdb.com/title/tt0211915/
+Get-JsonLD -Url https://letterboxd.com/film/amelie/
~~~
Let's take things a step further, and get the information we can know about any movie:
diff --git a/Types/JsonLD/GetJsonSchema.ps1 b/Types/JsonLD/GetJsonSchema.ps1
new file mode 100644
index 0000000..782898d
--- /dev/null
+++ b/Types/JsonLD/GetJsonSchema.ps1
@@ -0,0 +1,95 @@
+
+param($graph = $this)
+
+if (-not $graph.'@graph') {
+ if ($graph.'@context' -is [string] -and
+ $graph.'@type' -is [string]) {
+ $gotGraph = Get-JsonLD -Url (
+ $graph.'@context', $graph.'@type' -join '/' -replace '^http:', 'https:'
+ )
+ if ($gotGraph.'@graph') {
+ $graph = $gotGraph
+ }
+ }
+}
+
+if (-not $graph.'@graph') { return }
+
+$graphTypes = $graph.'@graph' | Group-Object '@type' -AsHashTable
+
+$classes = $graphTypes['rdfs:class']
+if (-not $classes) {
+ return
+}
+
+$baseType = $classes |
+ Where-Object 'rdfs:label' -eq 'thing'
+
+if (-not $baseType) {
+ return
+}
+
+$ClassHierarchy = @(
+ $baseType
+ do {
+ $parentType = $classes |
+ Where-Object {
+ $_.'rdfs:subClassOf'.'@id' -eq $baseType.'@id'
+ }
+ if ($parentType) {
+ $parentType
+ $baseType = $parentType
+ }
+ } while ($parentType)
+)
+
+if (-not $ClassHierarchy) { return }
+
+$classInfo = $ClassHierarchy[-1]
+
+$jsonSchema = [Ordered]@{
+ '$id' = "`$$($classInfo.'@id' -replace 'schema:', 'schema.org/')"
+ title = $($classInfo.'@id' -replace 'schema:', 'https://schema.org/')
+ description = $classInfo.'rdfs:comment'
+ properties = [Ordered]@{}
+}
+
+foreach ($rdfProperty in $graphTypes['rdf:property']) {
+ $propertyInfo = [Ordered]@{}
+ switch -regex ($rdfProperty.'@id') {
+ '(?>date|time)$' {
+ $propertyInfo['type'] = 'string'
+ $propertyInfo['format'] = 'date-time'
+ }
+ 'url$' {
+ $propertyInfo['type'] = 'string'
+ $propertyInfo['format'] = 'url'
+ }
+ '(?>name|description)$' {
+ $propertyInfo['type'] = 'string'
+ }
+ default {
+ $propertyInfo['type'] = 'object'
+ }
+ }
+ if (@($rdfProperty.'schema:rangeIncludes').Count -eq 1) {
+ switch ($rdfProperty.'schema:rangeIncludes') {
+ schema:Boolean {
+ $propertyInfo['type'] = 'boolean'
+ }
+ schema:Integer {
+ $propertyInfo['type'] = 'integer'
+ }
+ schema:Number {
+ $propertyInfo['type'] = 'number'
+ }
+ }
+ }
+ if ($rdfProperty.'rdfs:comment') {
+ $propertyInfo['description'] = $rdfProperty.'rdfs:comment'
+ }
+ $propertyName = $rdfProperty.'@id' -replace '^schema:'
+ $jsonSchema.properties[$propertyName] = $propertyInfo
+}
+$jsonSchema
+
diff --git a/Types/JsonLD/GetLexicon.ps1 b/Types/JsonLD/GetLexicon.ps1
new file mode 100644
index 0000000..d875812
--- /dev/null
+++ b/Types/JsonLD/GetLexicon.ps1
@@ -0,0 +1,32 @@
+
+param($graph = $this)
+
+$jsonSchema = $this.GetJsonSchema($graph)
+if (-not $jsonSchema.'$id') {
+ throw "Missing $jsonSchema.$id"
+ return
+}
+
+$domain, $relativePath = $jsonSchema.'$id' -replace '^$' -split '/'
+if (-not $domain) { return}
+if (-not $relativePath ) { return }
+$domain = @($domain -split '\.')
+[Array]::Reverse($domain)
+$nsid = $domain, $relativePath -join '.'
+
+
+$jsonSchema.psobject.properties.Remove('$id')
+
+[Ordered]@{
+ lexicon = 1
+ id = $nsid
+ defs = [Ordered]@{
+ main = [Ordered]@{
+ type = 'record'
+ description = $jsonSchema.description
+ record = $jsonSchema
+ }
+ }
+}
+
+
diff --git a/Types/JsonLD/PSTypeName.txt b/Types/JsonLD/PSTypeName.txt
new file mode 100644
index 0000000..a24735f
--- /dev/null
+++ b/Types/JsonLD/PSTypeName.txt
@@ -0,0 +1 @@
+application/ld+json
\ No newline at end of file