Skip to content

Commit 2162022

Browse files
feat: Get-JSONLD improvement ( Fixes #12, Fixes #27 )
Aliasing to uri, handling direct JSON-LD links
1 parent 8ca2315 commit 2162022

1 file changed

Lines changed: 110 additions & 65 deletions

File tree

Commands/Get-JsonLD.ps1

Lines changed: 110 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ function Get-JsonLD {
2121
param(
2222
# The URL that may contain JSON-LD data
2323
[Parameter(Mandatory, ValueFromPipeline, ValueFromPipelineByPropertyName)]
24-
[Alias('href')]
24+
[Alias('href','uri')]
2525
[Uri]
2626
$Url,
2727

@@ -42,10 +42,8 @@ function Get-JsonLD {
4242
[string]
4343
$as = 'jsonld',
4444

45-
[switch]
46-
$RawHtml,
47-
4845
# If set, will force the request to be made even if the URL has already been cached.
46+
[Alias('IgnoreCache')]
4947
[switch]
5048
$Force
5149
)
@@ -71,53 +69,140 @@ application/ld\+json # The type that indicates linked d
7169
$script:Cache = [Ordered]@{}
7270
}
7371

72+
# Construct a filter to match and output
73+
filter matchAndOutput {
74+
75+
$contentToMatch = $_
76+
if ($contentToMatch -match '^\s{0,}\{') {
77+
$contentToMatch = "<script type='application/ld+json'>$($contentToMatch)</script>"
78+
}
79+
80+
if ($as -eq 'html') {
81+
return $contentToMatch
82+
}
83+
84+
# Find all linked data tags within the response
85+
foreach ($match in $linkedDataRegex.Matches("$($contentToMatch)")) {
86+
# If we want the result as xml
87+
if ($As -eq 'xml') {
88+
# try to cast it
89+
$matchXml ="$match" -as [xml]
90+
if ($matchXml) {
91+
# and output it if found.
92+
$matchXml
93+
continue
94+
} else {
95+
# otherwise, fall back to the `<script>` tag
96+
$As = 'script'
97+
}
98+
}
99+
100+
# If we want the tag, that should be the whole match
101+
if ($As -eq 'script') {
102+
"$match"
103+
continue
104+
}
105+
106+
# If we want it as json, we have a match group.
107+
if ($As -eq 'json') {
108+
$match.Groups['JsonContent'].Value
109+
continue
110+
}
111+
# Otherwise, we want it as linked data, so convert from the json
112+
foreach ($jsonObject in
113+
$match.Groups['JsonContent'].Value |
114+
ConvertFrom-Json
115+
) {
116+
# If there was a `@type` or `@graph` property
117+
if (
118+
$jsonObject.'@type' -or
119+
$jsonObject.'@graph'
120+
) {
121+
# output the object as jsonld
122+
$jsonObject | output
123+
continue
124+
}
125+
# If there is neither a `@type` or a `@graph`
126+
else {
127+
# just output the object.
128+
$jsonObject
129+
}
130+
}
131+
}
132+
133+
}
134+
135+
# Construct a filter to output out content
136+
74137
filter output {
138+
# We want JSON-LD types to become .pstypenames, and this should happen recursively.
75139
$in = $_
140+
# we can use `MyInvocation.MyCommand` to anonymously recurse
141+
# (this makes it easier if the name of this command changes)
76142
$mySelf = $MyInvocation.MyCommand
143+
144+
# Context could be a string or an object
145+
# When it is a string, it is a root type.
77146
if ($in.'@context' -is [string]) {
78-
$context = $in.'@context'
147+
$context = $in.'@context' # so set the context
148+
# ( this variable will leek down into lower scopes )
149+
# ( so we can reuse common contexts (like `schema.org` ))
79150
}
151+
152+
# If we have a graph of outputs
80153
if ($in.'@graph') {
154+
# decorate the entire graph as `application/ld+json`
81155
if ($in.pstypenames -ne 'application/ld+json') {
82156
$in.pstypenames.insert(0,'application/ld+json')
83157
}
158+
# and then call ourself
84159
foreach ($graphObject in $in.'@graph') {
160+
# (null the return so we only output the topmost object)
85161
$null = $graphObject |
86162
& $mySelf
87163
}
88164
}
165+
# If we have a single type of object
89166
elseif ($in.'@type') {
90-
167+
# combine it with the context to get our typename
91168
$typeName = if ($context) {
92169
$context, $in.'@type' -join '/'
93170
} else {
94171
$in.'@type'
95172
}
96173

174+
# Decorate the type as `application/ld+json`
97175
if ($in.pstypenames -ne 'application/ld+json') {
98176
$in.pstypenames.insert(0,'application/ld+json')
99177
}
178+
# and decocate the item as the `$typeName`
100179
if ($in.pstypenames -ne $typeName) {
101180
$in.pstypenames.insert(0,$typeName)
102181
}
103182

183+
# Then go over each property
104184
foreach ($property in $in.psobject.properties) {
185+
# if the property had a `@type`
105186
if ($property.value.'@type') {
187+
# call ourself on the value
188+
# (null the return so we only output the topmost object)
106189
$null = $property.value |
107190
& $mySelf
108-
}
109-
}
191+
}
192+
}
110193
}
194+
195+
# Now that we've finished decorating out graph or type
196+
# output our modified input.
111197
$in
112198
}
113199

200+
# Files will be treated as .json
114201
$foreachFile = {
115202
$inFile = $_.FullName
116-
try {
117-
203+
try {
118204
Get-Content -LiteralPath $_.FullName -Raw |
119-
ConvertFrom-Json |
120-
output
205+
matchAndOutput
121206
} catch {
122207
Write-Verbose "$($inFile.FullName) : $_"
123208
}
@@ -151,63 +236,23 @@ application/ld\+json # The type that indicates linked d
151236

152237
$restResponse =
153238
if ($Force -or -not $script:Cache[$url]) {
154-
$script:Cache[$url] = Invoke-RestMethod -Uri $Url
239+
$script:Cache[$url] = Invoke-WebRequest -Uri $Url
155240
$script:Cache[$url]
156241
} else {
157242
$script:Cache[$url]
158243
}
159-
160-
if ($as -eq 'html') {
161-
return $restResponse
162-
}
163244

164-
# Find all linked data tags within the response
165-
foreach ($match in $linkedDataRegex.Matches("$restResponse")) {
166-
# If we want the result as xml
167-
if ($As -eq 'xml') {
168-
# try to cast it
169-
$matchXml ="$match" -as [xml]
170-
if ($matchXml) {
171-
# and output it if found.
172-
$matchXml
173-
continue
174-
} else {
175-
# otherwise, fall back to the `<script>` tag
176-
$As = 'script'
177-
}
178-
}
179-
180-
# If we want the tag, that should be the whole match
181-
if ($As -eq 'script') {
182-
"$match"
183-
continue
184-
}
185-
186-
# If we want it as json, we have a match group.
187-
if ($As -eq 'json') {
188-
$match.Groups['JsonContent'].Value
189-
continue
190-
}
191-
# Otherwise, we want it as linked data, so convert from the json
192-
foreach ($jsonObject in
193-
$match.Groups['JsonContent'].Value |
194-
ConvertFrom-Json
195-
) {
196-
# If there was a `@type` or `@graph` property
197-
if (
198-
$jsonObject.'@type' -or
199-
$jsonObject.'@graph'
200-
) {
201-
# output the object as jsonld
202-
$jsonObject | output
203-
continue
204-
}
205-
# If there is neither a `@type` or a `@graph`
206-
else {
207-
# just output the object.
208-
$jsonObject
209-
}
210-
}
211-
}
245+
246+
if ($restResponse.Headers['Content-Type'] -match 'json') {
247+
if ($restResponse.Content -is [byte[]]) {
248+
[Text.Encoding]::UTF8.GetString($restResponse.Content) | matchAndOutput
249+
} else {
250+
$restResponse.Content | matchAndOutput
251+
}
252+
} elseif ($restResponse.Content -is [string]) {
253+
$restResponse.Content | matchAndOutput
254+
} else {
255+
""
256+
}
212257
}
213258
}

0 commit comments

Comments
 (0)