Skip to content

Commit 0dd35c9

Browse files
author
James Brundage
committed
Adding http[s] transpiler (Fixes #169)
1 parent 4e06195 commit 0dd35c9

File tree

3 files changed

+216
-0
lines changed

3 files changed

+216
-0
lines changed
Lines changed: 166 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,166 @@
1+
<#
2+
.SYNOPSIS
3+
http protocol
4+
.DESCRIPTION
5+
Converts an http[s] protocol command to PowerShell.
6+
.EXAMPLE
7+
.> {
8+
https://api.github.com/repos/StartAutomating/PipeScript
9+
}
10+
.EXAMPLE
11+
{
12+
get https://api.github.com/repos/StartAutomating/PipeScript
13+
} | .>PipeScript
14+
.EXAMPLE
15+
Invoke-PipeScript {
16+
$GitHubApi = 'api.github.com'
17+
$UserName = 'StartAutomating'
18+
https://$GitHubApi/users/$UserName
19+
}
20+
.EXAMPLE
21+
.> -ScriptBlock {
22+
https://$GitHubApi/users/$UserName -GitHubApi api.github.com -UserName StartAutomating
23+
}
24+
.EXAMPLE
25+
.> -ScriptBlock {
26+
https://$GitHubApi/users/$UserName -GitHubApi api.github.com -UserName StartAutomating
27+
}
28+
.EXAMPLE
29+
.> -ScriptBlock {
30+
@(foreach ($repo in https://api.github.com/users/StartAutomating/repos?per_page=100) {
31+
$repo | .Name .Stars { $_.stargazers_count }
32+
}) | Sort-Object Stars -Descending
33+
}
34+
.EXAMPLE
35+
.> {
36+
http://text-processing.com/api/sentiment/ -Method POST -ContentType 'application/x-www-form-urlencoded' -Body "text=amazing!" |
37+
Select-Object -ExpandProperty Probability -Property Label
38+
}
39+
#>
40+
[ValidateScript({
41+
$commandAst = $_
42+
if (-not ($commandAst.CommandElements[0..1].Value -match '^https{0,1}://')) {
43+
return $false
44+
}
45+
return $true
46+
})]
47+
param(
48+
# The URI.
49+
[Parameter(Mandatory,ValueFromPipeline)]
50+
[uri]
51+
$CommandUri,
52+
53+
# The Command's Abstract Syntax Tree
54+
[Parameter(Mandatory)]
55+
[Management.Automation.Language.CommandAST]
56+
$CommandAst,
57+
58+
[string]
59+
$Method = 'GET'
60+
)
61+
62+
process {
63+
$commandArguments = @() + $CommandAst.ArgumentList
64+
$commandParameters = [Ordered]@{} + $CommandAst.Parameter
65+
66+
$method = ''
67+
$commandName =
68+
if ($CommandAst.CommandElements[0].Value -match '://') {
69+
$commandAst.CommandElements[0].Value
70+
} else {
71+
$method = $commandAst.CommandElements[0].Value
72+
$commandArguments = $commandArguments[2..($commandArguments.Count + 1)]
73+
$commandAst.CommandElements[1].Value
74+
}
75+
76+
$startIndex = 0
77+
$partsToJoin =
78+
@(
79+
foreach ($match in [Regex]::Matches(
80+
$commandName, '(?>
81+
(?<Variable>\$\w+\:\w+)
82+
|
83+
(?<Variable>\$\w+)
84+
)',
85+
'IgnoreCase, IgnorePatternWhitespace'
86+
)
87+
) {
88+
"'" +
89+
$commandName.Substring($startIndex, $match.Index - $startIndex).Replace("'", "''") +
90+
"'"
91+
$varMatch = $match.Groups["Variable"].Value
92+
$varName = $varMatch.TrimStart('$')
93+
if ($commandParameters[$varName]) {
94+
$varParameter = $commandParameters[$varName]
95+
$commandParameters.Remove($varName)
96+
if ($varParameter -is [string]) {
97+
"'" + $varParameter + "'"
98+
}
99+
elseif ($varParameter -is [ScriptBlock]) {
100+
"{$varParameter}"
101+
} else {
102+
$varParameter
103+
}
104+
} else {
105+
$varMatch
106+
}
107+
108+
$startIndex = $match.Index + $match.Length
109+
}
110+
"'" +
111+
$commandName.Substring($startIndex).Replace("'", "''") +
112+
"'"
113+
)
114+
115+
$invoker = "Invoke-RestMethod"
116+
if ($commandParameters.Invoker) {
117+
$invoker = "$($commandParameters.Invoker)"
118+
$commandParameters.Remove('Invoker')
119+
}
120+
121+
if ($method) {
122+
$commandParameters.Method = $method
123+
}
124+
125+
126+
$newScript =
127+
if ($partsToJoin.Count -gt 1) {
128+
"$Invoker ($($PartsToJoin -join ',') -join '') "
129+
} else {
130+
"$Invoker $PartsToJoin "
131+
}
132+
$newScript += @(
133+
foreach ($argument in $commandArguments) {
134+
if ($argument -is [string]) {
135+
"'" + $argument.Replace("'", "''") + "'"
136+
}
137+
elseif ($argument -is [scriptblock]) {
138+
"{" + $argument + "}"
139+
}
140+
}
141+
foreach ($param in $commandParameters.GetEnumerator()) {
142+
if ($param.Value -isnot [bool]) {
143+
"-$($param.Key)"
144+
}
145+
146+
if ($param.Value -is [string]) {
147+
"'" + $param.Value.Replace("'", "''") + "'"
148+
}
149+
elseif ($param.Value -is [ScriptBlock]) {
150+
"{" + $param.Value + "}"
151+
}
152+
elseif ($param.Value -is [bool]) {
153+
if ($param.Value) {
154+
"-$($param.Key)"
155+
} else {
156+
"-$($param.Key):`$false"
157+
}
158+
}
159+
else {
160+
$param.Value
161+
}
162+
}
163+
) -join ' '
164+
165+
[scriptblock]::Create($newScript)
166+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
describe 'http protocol' {
2+
it 'Runs http[s] commands' {
3+
.> https://api.github.com/repos/StartAutomating/PipeScript |
4+
Select-Object -ExpandProperty Name |
5+
Should -be PipeScript
6+
}
7+
8+
it 'Can include variables in the syntax' {
9+
.> {
10+
$userName, $repo = 'StartAutomating', 'PipeScript'
11+
https://api.github.com/repos/$userName/$repo |
12+
Select-Object -ExpandProperty Name |
13+
Should -be PipeScript
14+
}
15+
}
16+
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
PipeScript supports transpiling protocols.
2+
3+
To be considered a protocol transpiler, a transpiler must:
4+
5+
1. Accept a ```[uri]``` from the pipeline
6+
2. Have a parameter -CommandAST ```[Management.Automation.Language.CommandAST]```
7+
3. Be valid, given a ```[Management.Automation.Language.CommandAST]```
8+
9+
~~~PipeScript{
10+
[PSCustomObject]@{
11+
Table = Get-Transpiler -TranspilerPath $pwd |
12+
Select-Object DisplayName, Synopsis, @{
13+
Name='Link'
14+
Expression = { $_.Name }
15+
}
16+
}}
17+
~~~
18+
19+
20+
~~~PipeScript{
21+
@(foreach ($transpiler in Get-Transpiler -TranspilerPath $pwd) {
22+
$examples = @($transpiler.Examples)
23+
if (-not $examples) { continue }
24+
for ($exampleNumber = 1; $exampleNumber -le $examples.Length; $exampleNumber++) {
25+
@("## $($transpiler.DisplayName) Example $($exampleNumber)",
26+
[Environment]::Newline,
27+
"~~~PowerShell",
28+
$examples[$exampleNumber - 1],
29+
"~~~") -join [Environment]::Newline
30+
}
31+
}) -join ([Environment]::Newline * 2)
32+
}
33+
~~~
34+

0 commit comments

Comments
 (0)