api-tuner 0.6.0 → 0.6.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +25 -0
- package/lib/download-eye.js +15 -0
- package/package.json +5 -5
- package/rules/assertions.n3 +26 -2
- package/rules/curl-body.n3 +7 -1
- package/rules/files.n3 +1 -1
- package/rules/headers.n3 +19 -2
- package/rules/math.n3 +19 -0
- package/rules/queryParams.n3 +1 -1
- package/rules/requests.n3 +9 -4
package/README.md
CHANGED
|
@@ -188,6 +188,31 @@ Query parameters can be added to a request using `tuner:query`.
|
|
|
188
188
|
?req tuner:query ( "name" "value" ) .
|
|
189
189
|
```
|
|
190
190
|
|
|
191
|
+
#### Basic Authentication
|
|
192
|
+
|
|
193
|
+
Use `tuner:basicAuth` to add HTTP Basic Authentication to a request. It takes a list of `( username password )` and automatically sets the `Authorization: Basic ...` header.
|
|
194
|
+
|
|
195
|
+
```turtle
|
|
196
|
+
<#test> tuner:request [
|
|
197
|
+
a tuner:Request ;
|
|
198
|
+
tuner:url <http://example.com/api> ;
|
|
199
|
+
tuner:basicAuth ( "admin" "secret" ) ;
|
|
200
|
+
] .
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
#### Shell Variables
|
|
204
|
+
|
|
205
|
+
Values used in request URL, headers and query params are resolved from the shell environment.
|
|
206
|
+
|
|
207
|
+
```turtle
|
|
208
|
+
<#test> tuner:request [
|
|
209
|
+
a tuner:Request ;
|
|
210
|
+
tuner:url <http://example.com/api/$PATH> ;
|
|
211
|
+
tuner:header ( "X-Api-Key" "$API_KEY" ) ;
|
|
212
|
+
tuner:query ( "q" "$QUERY" ) ;
|
|
213
|
+
] .
|
|
214
|
+
```
|
|
215
|
+
|
|
191
216
|
### Assertions
|
|
192
217
|
|
|
193
218
|
Assertions are performed on the `tuner:Response` object (usually captured in a variable like `?res`).
|
package/lib/download-eye.js
CHANGED
|
@@ -1,11 +1,26 @@
|
|
|
1
1
|
#! /usr/bin/env node
|
|
2
2
|
/* eslint-disable no-console */
|
|
3
3
|
import fs from 'node:fs'
|
|
4
|
+
import { spawnSync } from 'node:child_process'
|
|
4
5
|
import { Readable } from 'node:stream'
|
|
5
6
|
import * as tar from 'tar'
|
|
6
7
|
|
|
7
8
|
async function main() {
|
|
8
9
|
const EYE_VERSION = process.env.EYE_VERSION
|
|
10
|
+
|
|
11
|
+
if (fs.existsSync('eye')) {
|
|
12
|
+
try {
|
|
13
|
+
const versionOutput = spawnSync('eye/bin/eye', ['--version'], { encoding: 'utf-8' })
|
|
14
|
+
if (versionOutput.stderr.includes(EYE_VERSION)) {
|
|
15
|
+
console.log(`EYE v${EYE_VERSION} already installed`)
|
|
16
|
+
return
|
|
17
|
+
}
|
|
18
|
+
} catch (e) {
|
|
19
|
+
console.warn(`Failed to check EYE version: ${e.message}`)
|
|
20
|
+
console.warn('Re-downloading...')
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
9
24
|
const url = `https://github.com/eyereasoner/eye/archive/refs/tags/v${EYE_VERSION}.tar.gz`
|
|
10
25
|
|
|
11
26
|
// Download and extract tarball directly from stream
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "api-tuner",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.2",
|
|
4
4
|
"main": "index.js",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -8,12 +8,12 @@
|
|
|
8
8
|
"api-tuner": "bin/tuner.sh"
|
|
9
9
|
},
|
|
10
10
|
"scripts": {
|
|
11
|
-
"download-eye": "EYE_VERSION=11.
|
|
12
|
-
"postinstall": "
|
|
11
|
+
"download-eye": "EYE_VERSION=11.24.3 ./lib/download-eye.js",
|
|
12
|
+
"postinstall": "npm run download-eye && eye/install.sh --prefix=eye",
|
|
13
13
|
"prepare": "husky",
|
|
14
14
|
"lint": "eslint . --quiet --ignore-path .gitignore",
|
|
15
|
-
"pre_test": "docker compose up -d && docker compose restart && npx wait-on http-get://localhost:1080/ping -t
|
|
16
|
-
"_test": "./bin/tuner.sh --base-iri http://localhost:1080/",
|
|
15
|
+
"pre_test": "docker compose up -d && docker compose restart && npx wait-on http-get://localhost:1080/ping -t 20s",
|
|
16
|
+
"_test": "export FOO=BAR; ./bin/tuner.sh --base-iri http://localhost:1080/",
|
|
17
17
|
"test": "npm run _test -- tests/*.n3 tests/**/*.n3",
|
|
18
18
|
"prepack": "tsc",
|
|
19
19
|
"release": "changeset publish"
|
package/rules/assertions.n3
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
PREFIX math: <http://www.w3.org/2000/10/swap/math#>
|
|
1
2
|
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
|
|
2
3
|
PREFIX list: <http://www.w3.org/2000/10/swap/list#>
|
|
3
4
|
PREFIX tuner: <https://api-tuner.described.at/>
|
|
@@ -91,8 +92,11 @@ prefix file: <http://www.w3.org/2000/10/swap/file#>
|
|
|
91
92
|
# remove surrounding quotes added by the shell
|
|
92
93
|
( ( ?actualRaw '^\"' "")!string:replace '\"$' "") string:replace ?actual .
|
|
93
94
|
|
|
95
|
+
( ?actual ?builtIn ) math:normaliseLiteral ?actualNormalised .
|
|
96
|
+
( ?expected ?builtIn ) math:normaliseLiteral ?expectedNormalised .
|
|
97
|
+
|
|
94
98
|
(
|
|
95
|
-
{ ?
|
|
99
|
+
{ ?actualNormalised ?builtIn ?expectedNormalised }
|
|
96
100
|
true
|
|
97
101
|
{
|
|
98
102
|
("Expected JSON path '" ?path "' to satisfy '" ?builtIn " " ?expected "' but got '" ?actual "'")!string:concatenation^tuner:info .
|
|
@@ -110,8 +114,25 @@ prefix file: <http://www.w3.org/2000/10/swap/file#>
|
|
|
110
114
|
{
|
|
111
115
|
?res tuner:header ( ?name ?value ?builtIn ) .
|
|
112
116
|
} <= {
|
|
117
|
+
?name log:rawType log:Literal .
|
|
113
118
|
?name string:lowerCase ?nameLower .
|
|
114
119
|
|
|
120
|
+
(
|
|
121
|
+
{
|
|
122
|
+
?res log:notIncludes {
|
|
123
|
+
[] a tuner:Response ;
|
|
124
|
+
tuner:headers [
|
|
125
|
+
tuner:name ?nameLower ;
|
|
126
|
+
] .
|
|
127
|
+
} .
|
|
128
|
+
}
|
|
129
|
+
{
|
|
130
|
+
("Expected header '" ?name "' but it was not present in the response")!string:concatenation^tuner:info .
|
|
131
|
+
true log:equalTo false .
|
|
132
|
+
}
|
|
133
|
+
true
|
|
134
|
+
) log:ifThenElseIn [] .
|
|
135
|
+
|
|
115
136
|
?res log:includes {
|
|
116
137
|
[] a tuner:Response ;
|
|
117
138
|
tuner:headers [
|
|
@@ -120,8 +141,11 @@ prefix file: <http://www.w3.org/2000/10/swap/file#>
|
|
|
120
141
|
] .
|
|
121
142
|
} .
|
|
122
143
|
|
|
144
|
+
( ?actualValue ?builtIn ) math:normaliseLiteral ?actualNormalised .
|
|
145
|
+
( ?value ?builtIn ) math:normaliseLiteral ?expectedNormalised .
|
|
146
|
+
|
|
123
147
|
(
|
|
124
|
-
{ ?
|
|
148
|
+
{ ?actualNormalised ?builtIn ?expectedNormalised }
|
|
125
149
|
true
|
|
126
150
|
{
|
|
127
151
|
("Expected header '" ?name "' '" ?value "' to satisfy '" ?builtIn "' but got '" ?actualValue "'")!string:concatenation^tuner:info .
|
package/rules/curl-body.n3
CHANGED
|
@@ -34,8 +34,14 @@ prefix math: <http://www.w3.org/2000/10/swap/math#>
|
|
|
34
34
|
?literalBody </#body> ( ?curlArgs [] ) .
|
|
35
35
|
} <= {
|
|
36
36
|
?literalBody log:rawType log:Literal .
|
|
37
|
+
() file:temp ?requestBodyFile .
|
|
38
|
+
|
|
39
|
+
# Save body to file so that it can be used in the curl command reliably
|
|
40
|
+
(
|
|
41
|
+
"echo '" ?literalBody "' > " ?requestBodyFile
|
|
42
|
+
)!string:concatenation!e:exec .
|
|
37
43
|
|
|
38
|
-
( " -
|
|
44
|
+
( " --data-binary @" ?requestBodyFile ) string:concatenation ?curlArgs .
|
|
39
45
|
} .
|
|
40
46
|
|
|
41
47
|
{
|
package/rules/files.n3
CHANGED
|
@@ -15,7 +15,7 @@ prefix file: <http://www.w3.org/2000/10/swap/file#>
|
|
|
15
15
|
} <= {
|
|
16
16
|
?uri log:uri ( "urn:rand:" ( 1000 )!e:random )!string:concatenation .
|
|
17
17
|
# log:shell captures the traling newline
|
|
18
|
-
( "mktemp -t api-tuner -d 2>/dev/null || mktemp -d -t api-tuner.XXXXXXXX"!log:shell "\n" "" ) string:
|
|
18
|
+
( "mktemp -t api-tuner -d 2>/dev/null || mktemp -d -t api-tuner.XXXXXXXX"!log:shell ("\n") ("") ) string:replaceAll ?tempDir .
|
|
19
19
|
|
|
20
20
|
(
|
|
21
21
|
?tempDir
|
package/rules/headers.n3
CHANGED
|
@@ -1,8 +1,25 @@
|
|
|
1
|
+
PREFIX log: <http://www.w3.org/2000/10/swap/log#>
|
|
1
2
|
prefix tuner: <https://api-tuner.described.at/>
|
|
2
3
|
prefix string: <http://www.w3.org/2000/10/swap/string#>
|
|
3
4
|
|
|
5
|
+
tuner:header a tuner:HeaderRule ; tuner:headerArgsRule <#defaultHeader> .
|
|
6
|
+
|
|
4
7
|
{
|
|
5
|
-
(?fieldName ?fieldValue)
|
|
8
|
+
(?fieldName ?fieldValue) <#defaultHeader> ?curlArg .
|
|
6
9
|
} <= {
|
|
7
|
-
(
|
|
10
|
+
( ' -H "' ?fieldName ":" ?fieldValue '"' ) string:concatenation ?curlArg .
|
|
11
|
+
} .
|
|
12
|
+
|
|
13
|
+
####
|
|
14
|
+
|
|
15
|
+
tuner:basicAuth a tuner:HeaderRule ; tuner:headerArgsRule <#basicAuth> .
|
|
16
|
+
|
|
17
|
+
{
|
|
18
|
+
( ?user ?password ) <#basicAuth> ?curlArgs .
|
|
19
|
+
} <= {
|
|
20
|
+
( ?user ":" ?password ) string:concatenation ?credentials .
|
|
21
|
+
|
|
22
|
+
( "node -e 'console.log(Buffer.from(\"" ?credentials "\").toString(\"base64\"))'" )!string:concatenation log:shell ?encoded .
|
|
23
|
+
|
|
24
|
+
( "Authorization" ("Basic " (?encoded "\n$" "")!string:replace)!string:concatenation ) <#defaultHeader> ?curlArgs .
|
|
8
25
|
} .
|
package/rules/math.n3
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>
|
|
2
|
+
PREFIX log: <http://www.w3.org/2000/10/swap/log#>
|
|
3
|
+
prefix math: <http://www.w3.org/2000/10/swap/math#>
|
|
4
|
+
prefix string: <http://www.w3.org/2000/10/swap/string#>
|
|
5
|
+
|
|
6
|
+
# See https://github.com/eyereasoner/eye/issues/174#issuecomment-4405018796
|
|
7
|
+
{
|
|
8
|
+
( ?value ?builtIn ) math:normaliseLiteral ?normalised
|
|
9
|
+
} <= {
|
|
10
|
+
(
|
|
11
|
+
{
|
|
12
|
+
?builtIn!log:uri string:startsWith math:!log:uri
|
|
13
|
+
}
|
|
14
|
+
{
|
|
15
|
+
( ?value xsd:decimal ) log:dtlit ?normalised
|
|
16
|
+
}
|
|
17
|
+
{ ?value log:equalTo ?normalised }
|
|
18
|
+
) log:ifThenElseIn ?SCOPE
|
|
19
|
+
} .
|
package/rules/queryParams.n3
CHANGED
|
@@ -4,5 +4,5 @@ prefix string: <http://www.w3.org/2000/10/swap/string#>
|
|
|
4
4
|
{
|
|
5
5
|
(?name ?value) tuner:queryParamArg ?curlArg .
|
|
6
6
|
} <= {
|
|
7
|
-
(
|
|
7
|
+
( ' --url-query "' ?name "=" ?value '"' ) string:concatenation ?curlArg .
|
|
8
8
|
} .
|
package/rules/requests.n3
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
|
|
1
2
|
PREFIX list: <http://www.w3.org/2000/10/swap/list#>
|
|
2
3
|
prefix e: <http://eulersharp.sourceforge.net/2003/03swap/log-rules#>
|
|
3
4
|
prefix log: <http://www.w3.org/2000/10/swap/log#>
|
|
@@ -20,10 +21,14 @@ prefix earl: <http://www.w3.org/ns/earl#>
|
|
|
20
21
|
true log:becomes { ?req tuner:done true } .
|
|
21
22
|
|
|
22
23
|
(
|
|
23
|
-
{ ?req tuner:header [] . }
|
|
24
24
|
{
|
|
25
|
-
|
|
26
|
-
|
|
25
|
+
?req ?headerRule [] .
|
|
26
|
+
?headerRule a tuner:HeaderRule .
|
|
27
|
+
?headerRule tuner:headerArgsRule ?headerRuleFn .
|
|
28
|
+
}
|
|
29
|
+
{
|
|
30
|
+
( ?header { ?req ?headerRule ?header } ?headers ) log:collectAllIn [] .
|
|
31
|
+
( ?headers ?headerRuleFn )!list:map string:concatenation ?headersArgs .
|
|
27
32
|
}
|
|
28
33
|
{ ?headersArgs log:equalTo "" }
|
|
29
34
|
) log:ifThenElseIn [] .
|
|
@@ -55,7 +60,7 @@ prefix earl: <http://www.w3.org/ns/earl#>
|
|
|
55
60
|
) log:ifThenElseIn [] .
|
|
56
61
|
|
|
57
62
|
(
|
|
58
|
-
"curl -s -X " ?method "
|
|
63
|
+
"curl -s -X " ?method ' "' ?endpoint '"'
|
|
59
64
|
?headersArgs
|
|
60
65
|
?bodyArgs
|
|
61
66
|
?queryParamArgs
|