@lovrozagar/oat 0.1.1 → 0.2.1
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 +116 -68
- package/dist/cli.js +11 -1
- package/dist/config/define-config.d.ts +50 -0
- package/dist/config/define-config.d.ts.map +1 -1
- package/dist/config/define-config.js.map +1 -1
- package/dist/config/load.d.ts +1 -1
- package/dist/config/load.d.ts.map +1 -1
- package/dist/config/load.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/report/console.d.ts +3 -2
- package/dist/report/console.d.ts.map +1 -1
- package/dist/report/console.js +5 -4
- package/dist/report/console.js.map +1 -1
- package/dist/report/matrix.d.ts +6 -5
- package/dist/report/matrix.d.ts.map +1 -1
- package/dist/report/matrix.js +29 -28
- package/dist/report/matrix.js.map +1 -1
- package/dist/report/render.d.ts +8 -0
- package/dist/report/render.d.ts.map +1 -1
- package/dist/report/render.js +28 -0
- package/dist/report/render.js.map +1 -1
- package/dist/runtime/checks.d.ts.map +1 -1
- package/dist/runtime/checks.js +17 -7
- package/dist/runtime/checks.js.map +1 -1
- package/dist/runtime/client.d.ts +12 -1
- package/dist/runtime/client.d.ts.map +1 -1
- package/dist/runtime/client.js +17 -2
- package/dist/runtime/client.js.map +1 -1
- package/dist/runtime/profile.d.ts +30 -0
- package/dist/runtime/profile.d.ts.map +1 -0
- package/dist/runtime/profile.js +46 -0
- package/dist/runtime/profile.js.map +1 -0
- package/dist/runtime/rate-limit.d.ts +53 -0
- package/dist/runtime/rate-limit.d.ts.map +1 -0
- package/dist/runtime/rate-limit.js +165 -0
- package/dist/runtime/rate-limit.js.map +1 -0
- package/dist/runtime/run.d.ts +15 -1
- package/dist/runtime/run.d.ts.map +1 -1
- package/dist/runtime/run.js +131 -48
- package/dist/runtime/run.js.map +1 -1
- package/dist/spec/extensions.d.ts +11 -0
- package/dist/spec/extensions.d.ts.map +1 -1
- package/dist/spec/extensions.js +15 -0
- package/dist/spec/extensions.js.map +1 -1
- package/dist/spec/graph.d.ts +2 -1
- package/dist/spec/graph.d.ts.map +1 -1
- package/dist/spec/graph.js +2 -1
- package/dist/spec/graph.js.map +1 -1
- package/labs/README.md +1 -1
- package/labs/annotated-openapi.yaml +60 -0
- package/labs/{anyrow.config.ts → oob-auth.config.ts} +9 -9
- package/package.json +11 -6
package/labs/README.md
CHANGED
|
@@ -119,7 +119,7 @@ These also live here — there is no top-level `examples/`.
|
|
|
119
119
|
| `oat.config.ts` | principals for a labs world (D1) |
|
|
120
120
|
| `local.config.ts` | point oat at `oat serve` (the fixture) |
|
|
121
121
|
| `minimal.config.ts` | smallest useful config, static API key |
|
|
122
|
-
| `
|
|
122
|
+
| `oob-auth.config.ts` | multi-step login against a stranger API |
|
|
123
123
|
| `annotated-openapi.yaml` | every `x-*` tag in one document |
|
|
124
124
|
| `demo.mjs` | one-process fixture demo (`npm run demo`) |
|
|
125
125
|
|
|
@@ -294,6 +294,60 @@ paths:
|
|
|
294
294
|
status: { type: string, enum: [pending, running, complete, failed] }
|
|
295
295
|
required: [export_id, status]
|
|
296
296
|
|
|
297
|
+
# ── public catalogue ──────────────────────────────────────────────────────
|
|
298
|
+
# No x-tenant, and `{template_id}` is not a tenant name. A second principal
|
|
299
|
+
# GETting a row created by the first is correct: the resource is shared.
|
|
300
|
+
# tenant.item-not-readable-cross-tenant does not apply here. The workspace
|
|
301
|
+
# widget above still does — tag → SECURITY, inferred → AMBIGUITY.
|
|
302
|
+
/v1/templates:
|
|
303
|
+
get:
|
|
304
|
+
operationId: template.list
|
|
305
|
+
summary: List public templates
|
|
306
|
+
x-entity: { name: template, action: list, identity: id }
|
|
307
|
+
responses:
|
|
308
|
+
"200":
|
|
309
|
+
description: A page of templates
|
|
310
|
+
content:
|
|
311
|
+
application/json:
|
|
312
|
+
schema:
|
|
313
|
+
type: object
|
|
314
|
+
properties:
|
|
315
|
+
templates: { type: array, items: { $ref: "#/components/schemas/Template" } }
|
|
316
|
+
required: [templates]
|
|
317
|
+
post:
|
|
318
|
+
operationId: template.create
|
|
319
|
+
summary: Publish a template
|
|
320
|
+
x-entity: { name: template, action: create, identity: id }
|
|
321
|
+
requestBody:
|
|
322
|
+
required: true
|
|
323
|
+
content:
|
|
324
|
+
application/json:
|
|
325
|
+
schema:
|
|
326
|
+
type: object
|
|
327
|
+
additionalProperties: false
|
|
328
|
+
properties:
|
|
329
|
+
name: { type: string, maxLength: 128 }
|
|
330
|
+
required: [name]
|
|
331
|
+
responses:
|
|
332
|
+
"201":
|
|
333
|
+
description: Created
|
|
334
|
+
content:
|
|
335
|
+
application/json:
|
|
336
|
+
schema: { $ref: "#/components/schemas/Template" }
|
|
337
|
+
|
|
338
|
+
/v1/templates/{template_id}:
|
|
339
|
+
get:
|
|
340
|
+
operationId: template.read
|
|
341
|
+
x-entity: { name: template, action: read, identity: id }
|
|
342
|
+
parameters:
|
|
343
|
+
- { name: template_id, in: path, required: true, schema: { type: string } }
|
|
344
|
+
responses:
|
|
345
|
+
"200":
|
|
346
|
+
description: A public template
|
|
347
|
+
content:
|
|
348
|
+
application/json:
|
|
349
|
+
schema: { $ref: "#/components/schemas/Template" }
|
|
350
|
+
|
|
297
351
|
components:
|
|
298
352
|
schemas:
|
|
299
353
|
Widget:
|
|
@@ -309,3 +363,9 @@ components:
|
|
|
309
363
|
updated_at: { type: string, format: date-time }
|
|
310
364
|
deleted_at: { type: [string, "null"] }
|
|
311
365
|
required: [id, workspace_id, name, status, priority, created_at, updated_at]
|
|
366
|
+
Template:
|
|
367
|
+
type: object
|
|
368
|
+
properties:
|
|
369
|
+
id: { type: string }
|
|
370
|
+
name: { type: string }
|
|
371
|
+
required: [id, name]
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* header carries it, and which path parameters the credential itself identifies. Delete it and
|
|
7
7
|
* oat still runs against any other OpenAPI document.
|
|
8
8
|
*
|
|
9
|
-
*
|
|
9
|
+
* OAT_API_URL=... OAT_TESTER_KEY=... oat run --config labs/oob-auth.config.ts
|
|
10
10
|
*
|
|
11
11
|
* Written as `from "../dist/index.js"` only because this file lives inside the repository —
|
|
12
12
|
* in your own project it is `from "@lovrozagar/oat"`.
|
|
@@ -14,13 +14,13 @@
|
|
|
14
14
|
|
|
15
15
|
import { defineConfig, type AuthFlow, type OutOfBandRequest } from "../dist/index.js"
|
|
16
16
|
|
|
17
|
-
const API = process.env.
|
|
18
|
-
const TESTER_KEY = process.env.
|
|
17
|
+
const API = process.env.OAT_API_URL ?? "https://api.example.com"
|
|
18
|
+
const TESTER_KEY = process.env.OAT_TESTER_KEY ?? ""
|
|
19
19
|
const PASSWORD = "OatSpec123!x"
|
|
20
20
|
|
|
21
21
|
/** A distinct address per principal per run, so tenants never collide between runs. */
|
|
22
22
|
function freshEmail(label: string): string {
|
|
23
|
-
return `oat-${label}-${Date.now()}-${Math.floor(Math.random() * 10_000)}@
|
|
23
|
+
return `oat-${label}-${Date.now()}-${Math.floor(Math.random() * 10_000)}@oat-spec.test`
|
|
24
24
|
}
|
|
25
25
|
|
|
26
26
|
/**
|
|
@@ -36,8 +36,8 @@ function signUp(label: string): AuthFlow {
|
|
|
36
36
|
credentialFrom: "$.access_token",
|
|
37
37
|
expiresInFrom: "$.access_token_expires_in",
|
|
38
38
|
steps: [
|
|
39
|
-
/* Raw paths rather than operationIds:
|
|
40
|
-
* operations at all, so there is nothing in the spec to reference. `oat doctor`
|
|
39
|
+
/* Raw paths rather than operationIds: an API document like this commonly contains no
|
|
40
|
+
* auth operations at all, so there is nothing in the spec to reference. `oat doctor`
|
|
41
41
|
* reports that as a gap — a document describing a protected API should describe how
|
|
42
42
|
* to authenticate to it. */
|
|
43
43
|
{
|
|
@@ -72,7 +72,7 @@ async function resolveOutOfBand({ address, kind }: OutOfBandRequest): Promise<st
|
|
|
72
72
|
const url = new URL(`${API}/v1/test/last-token`)
|
|
73
73
|
url.searchParams.set("email", address)
|
|
74
74
|
url.searchParams.set("type", kind)
|
|
75
|
-
const response = await fetch(url, { headers: { "x-
|
|
75
|
+
const response = await fetch(url, { headers: { "x-oat-tester-key": TESTER_KEY } })
|
|
76
76
|
if (!response.ok) return null
|
|
77
77
|
const body = (await response.json()) as { token?: unknown }
|
|
78
78
|
return typeof body.token === "string" ? body.token : null
|
|
@@ -82,13 +82,13 @@ async function resolveOutOfBand({ address, kind }: OutOfBandRequest): Promise<st
|
|
|
82
82
|
async function teardownPrincipal(address: string): Promise<void> {
|
|
83
83
|
const url = new URL(`${API}/v1/test/cleanup-user`)
|
|
84
84
|
url.searchParams.set("email", address)
|
|
85
|
-
await fetch(url, { headers: { "x-
|
|
85
|
+
await fetch(url, { headers: { "x-oat-tester-key": TESTER_KEY }, method: "DELETE" })
|
|
86
86
|
}
|
|
87
87
|
|
|
88
88
|
export default defineConfig({
|
|
89
89
|
baseUrl: API,
|
|
90
90
|
/* Sent on every request. Opaque to oat — it never inspects these. */
|
|
91
|
-
globalHeaders: { "x-
|
|
91
|
+
globalHeaders: { "x-oat-tester-key": TESTER_KEY },
|
|
92
92
|
hooks: { resolveOutOfBand, teardownPrincipal },
|
|
93
93
|
principals: [
|
|
94
94
|
{
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lovrozagar/oat",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.1",
|
|
4
4
|
"description": "OpenAPI Tester — matrix-test a live API against its OpenAPI spec",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"api",
|
|
@@ -37,7 +37,7 @@
|
|
|
37
37
|
"labs/annotated-openapi.yaml",
|
|
38
38
|
"labs/local.config.ts",
|
|
39
39
|
"labs/minimal.config.ts",
|
|
40
|
-
"labs/
|
|
40
|
+
"labs/oob-auth.config.ts",
|
|
41
41
|
"labs/demo.mjs",
|
|
42
42
|
"labs/README.md"
|
|
43
43
|
],
|
|
@@ -54,19 +54,21 @@
|
|
|
54
54
|
"access": "public"
|
|
55
55
|
},
|
|
56
56
|
"scripts": {
|
|
57
|
+
"prepare": "git config --get core.hooksPath >/dev/null || git config core.hooksPath .githooks || true",
|
|
57
58
|
"build": "tsc -p tsconfig.json",
|
|
58
59
|
"dev": "tsc -p tsconfig.json --watch",
|
|
59
60
|
"check": "tsc -p tsconfig.json --noEmit",
|
|
60
|
-
"test": "
|
|
61
|
+
"test": "bun run build && node --experimental-sqlite dist/cli.js conformance",
|
|
61
62
|
"conformance": "node --experimental-sqlite dist/cli.js conformance",
|
|
62
|
-
"
|
|
63
|
+
"bisect": "node --experimental-sqlite labs/bisect.mjs",
|
|
64
|
+
"demo": "bun run build && node labs/demo.mjs",
|
|
63
65
|
"labs": "node --experimental-strip-types labs/serve.ts",
|
|
64
66
|
"labs:sweep": "bash labs/sweep.sh",
|
|
65
67
|
"lint": "oxlint",
|
|
66
68
|
"lint:fix": "oxlint --fix",
|
|
67
69
|
"fmt": "oxfmt",
|
|
68
70
|
"fmt:check": "oxfmt --check",
|
|
69
|
-
"prepublishOnly": "
|
|
71
|
+
"prepublishOnly": "bun run build"
|
|
70
72
|
},
|
|
71
73
|
"dependencies": {
|
|
72
74
|
"ajv": "^8.17.1",
|
|
@@ -74,6 +76,8 @@
|
|
|
74
76
|
"yaml": "^2.9.0"
|
|
75
77
|
},
|
|
76
78
|
"devDependencies": {
|
|
79
|
+
"@commitlint/cli": "^21.2.1",
|
|
80
|
+
"@commitlint/config-conventional": "^21.2.0",
|
|
77
81
|
"@types/node": "^22.10.0",
|
|
78
82
|
"oxfmt": "^0.63.0",
|
|
79
83
|
"oxlint": "^1.78.0",
|
|
@@ -82,5 +86,6 @@
|
|
|
82
86
|
},
|
|
83
87
|
"engines": {
|
|
84
88
|
"node": ">=20"
|
|
85
|
-
}
|
|
89
|
+
},
|
|
90
|
+
"packageManager": "bun@1.3.11"
|
|
86
91
|
}
|