@lovrozagar/oat 0.4.0 → 0.6.0
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 +57 -33
- package/bin/oat.js +3 -1
- package/dist/cli.js +54 -12
- package/dist/config/define-config.d.ts +17 -3
- package/dist/config/define-config.d.ts.map +1 -1
- package/dist/config/define-config.js.map +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.js +1 -0
- package/dist/reference/defects.d.ts +14 -0
- package/dist/reference/defects.d.ts.map +1 -1
- package/dist/reference/defects.js +14 -0
- package/dist/reference/defects.js.map +1 -1
- package/dist/reference/http.d.ts.map +1 -1
- package/dist/reference/http.js +4 -1
- package/dist/reference/http.js.map +1 -1
- package/dist/report/matrix.d.ts.map +1 -1
- package/dist/report/matrix.js +2 -0
- package/dist/report/matrix.js.map +1 -1
- package/dist/runtime/async.d.ts +1 -1
- package/dist/runtime/async.d.ts.map +1 -1
- package/dist/runtime/async.js +10 -3
- package/dist/runtime/async.js.map +1 -1
- package/dist/runtime/auth.d.ts +23 -3
- package/dist/runtime/auth.d.ts.map +1 -1
- package/dist/runtime/auth.js +111 -27
- package/dist/runtime/auth.js.map +1 -1
- package/dist/runtime/checks.d.ts +2 -0
- package/dist/runtime/checks.d.ts.map +1 -1
- package/dist/runtime/checks.js +285 -1
- package/dist/runtime/checks.js.map +1 -1
- package/dist/runtime/client.d.ts +17 -1
- package/dist/runtime/client.d.ts.map +1 -1
- package/dist/runtime/client.js +83 -58
- package/dist/runtime/client.js.map +1 -1
- package/dist/runtime/fixture.d.ts.map +1 -1
- package/dist/runtime/fixture.js +4 -3
- package/dist/runtime/fixture.js.map +1 -1
- package/dist/runtime/payloads.d.ts +20 -0
- package/dist/runtime/payloads.d.ts.map +1 -0
- package/dist/runtime/payloads.js +250 -0
- package/dist/runtime/payloads.js.map +1 -0
- package/dist/runtime/run.d.ts +0 -6
- package/dist/runtime/run.d.ts.map +1 -1
- package/dist/runtime/run.js +17 -19
- package/dist/runtime/run.js.map +1 -1
- package/dist/runtime/teardown.js +1 -1
- package/dist/runtime/teardown.js.map +1 -1
- package/dist/runtime/world.js +2 -2
- package/dist/runtime/world.js.map +1 -1
- package/dist/spec/load.d.ts +2 -0
- package/dist/spec/load.d.ts.map +1 -1
- package/dist/spec/load.js +12 -0
- package/dist/spec/load.js.map +1 -1
- package/labs/oob-auth.config.ts +11 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -86,15 +86,15 @@ oat help # same as oat --help
|
|
|
86
86
|
oat --help
|
|
87
87
|
```
|
|
88
88
|
|
|
89
|
-
Unknown commands and missing required flags exit `2`.
|
|
89
|
+
Unknown commands, unknown flags, and missing required flags exit `2`.
|
|
90
90
|
|
|
91
91
|
## How a run works
|
|
92
92
|
|
|
93
93
|
1. **Load** the OpenAPI document (URL or path). Internal `$ref`s are inlined. External `$ref`s are reported, never fetched.
|
|
94
94
|
2. **Model** entities by inverting `x-invalidate` (or path heuristics) into a read surface per entity.
|
|
95
|
-
3. **Authenticate** every configured principal (static headers and/or an auth flow). Credentials refresh
|
|
95
|
+
3. **Authenticate** every configured principal (static headers and/or an auth flow). Credentials refresh on a countdown from `exp` (default 30s buffer) before every dispatch and each async poll.
|
|
96
96
|
4. **Seed** a cohort of records per entity, in parent-before-child order, using each entity's create operation.
|
|
97
|
-
5. **Test** the matrix, one entity at a time: foundations first, then composition, writes, isolation, declared effects. Checks inside an entity stay ordered.
|
|
97
|
+
5. **Test** the matrix, one entity at a time: foundations first, then composition, writes, isolation, declared effects. Entities run in series. Checks inside an entity stay ordered.
|
|
98
98
|
6. **Teardown** everything the run created, unless `--keep-fixtures` / `keepFixtures: true`.
|
|
99
99
|
|
|
100
100
|
The first principal is the writer. Isolation needs a second principal with different `roots`. A rank lattice needs two or more principals that share `roots` and differ in `rank`. Invite checks need `x-invite` plus a peer with `inviteAs`.
|
|
@@ -188,7 +188,6 @@ Same object. `${NAME}` is interpolated after load. There is no `defineConfig` wr
|
|
|
188
188
|
],
|
|
189
189
|
"seed": 42,
|
|
190
190
|
"cohortSize": 7,
|
|
191
|
-
"concurrency": 1,
|
|
192
191
|
"outDir": "./oat-out"
|
|
193
192
|
}
|
|
194
193
|
```
|
|
@@ -254,24 +253,23 @@ oat help
|
|
|
254
253
|
|
|
255
254
|
Requires `--config`. CLI flags override the same field in the config when both are set.
|
|
256
255
|
|
|
257
|
-
| flag | default | meaning
|
|
258
|
-
| ----------------- | ------------------------------ |
|
|
259
|
-
| `--config` | required | module or JSON file, default export
|
|
260
|
-
| `--base-url` | `config.baseUrl` | backend origin
|
|
261
|
-
| `--only` | `config.only` or all entities | comma-separated entity names as `oat plan` prints them (singularised)
|
|
262
|
-
| `--seed` | `config.seed` or `1` | fixture generation seed (reproducible)
|
|
263
|
-
| `--out` | `config.outDir` or `./oat-out` | report directory
|
|
264
|
-
| `--
|
|
265
|
-
| `--
|
|
266
|
-
| `--
|
|
267
|
-
| `--quiet` | false | no stderr progress; files under `--out` still update |
|
|
256
|
+
| flag | default | meaning |
|
|
257
|
+
| ----------------- | ------------------------------ | --------------------------------------------------------------------- |
|
|
258
|
+
| `--config` | required | module or JSON file, default export |
|
|
259
|
+
| `--base-url` | `config.baseUrl` | backend origin |
|
|
260
|
+
| `--only` | `config.only` or all entities | comma-separated entity names as `oat plan` prints them (singularised) |
|
|
261
|
+
| `--seed` | `config.seed` or `1` | fixture generation seed (reproducible) |
|
|
262
|
+
| `--out` | `config.outDir` or `./oat-out` | report directory |
|
|
263
|
+
| `--max-in-flight` | `config.maxInFlight` or `4` | HTTP requests allowed at once |
|
|
264
|
+
| `--keep-fixtures` | `config.keepFixtures` or false | do not DELETE what the run created |
|
|
265
|
+
| `--quiet` | false | no stderr progress; files under `--out` still update |
|
|
268
266
|
|
|
269
|
-
**Exit codes:** `0` no defects, `1` at least one root-cause finding (`BACKEND_BUG`, `SPEC_BUG`, `SECURITY`, `AMBIGUITY`), `2` usage error (missing `--config`, no principals). `COVERAGE_GAP` and `BLOCKED` do not fail the process.
|
|
267
|
+
**Exit codes:** `0` no defects, `1` at least one root-cause finding (`BACKEND_BUG`, `SPEC_BUG`, `SECURITY`, `AMBIGUITY`), `2` usage error (missing `--config`, no principals, unknown flag). `COVERAGE_GAP` and `BLOCKED` do not fail the process.
|
|
270
268
|
|
|
271
269
|
Example:
|
|
272
270
|
|
|
273
271
|
```bash
|
|
274
|
-
oat run --config oat.config.ts --only store,product --
|
|
272
|
+
oat run --config oat.config.ts --only store,product --out oat-out/prod
|
|
275
273
|
```
|
|
276
274
|
|
|
277
275
|
`--only store,product` matches the **entity names** from `oat plan`, not path segments. `/v1/stores` is usually the entity `store`. If a name is unknown, that entity is simply not tested (the others still run).
|
|
@@ -431,7 +429,6 @@ export default defineConfig({
|
|
|
431
429
|
roots: { org_id: "org_shared" }, // path params oat cannot create; also declarable via x-root
|
|
432
430
|
seed: 42, // fixture generation; a failing run with the same seed is identical
|
|
433
431
|
cohortSize: 12, // records created per entity (default 7)
|
|
434
|
-
concurrency: 1, // entities in parallel
|
|
435
432
|
maxInFlight: 4, // HTTP in flight
|
|
436
433
|
only: ["store", "product"], // restrict entities
|
|
437
434
|
keepFixtures: false,
|
|
@@ -450,7 +447,6 @@ export default defineConfig({
|
|
|
450
447
|
| `roots` | no | `{}` | Shared path params (merged with each principal's `roots`) |
|
|
451
448
|
| `seed` | no | `1` | Integer. Same seed → same fixture bodies |
|
|
452
449
|
| `cohortSize` | no | `7` | Sliced from the 7 built-in variants. Larger repeats the pattern |
|
|
453
|
-
| `concurrency` | no | `1` | Entity-level only. Checks inside one entity stay ordered |
|
|
454
450
|
| `maxInFlight` | no | `4` | Across the whole run |
|
|
455
451
|
| `only` | no | all | Entity names from `oat plan` |
|
|
456
452
|
| `keepFixtures` | no | `false` | Skip DELETE at the end |
|
|
@@ -458,7 +454,7 @@ export default defineConfig({
|
|
|
458
454
|
|
|
459
455
|
`spec` may be a path relative to `baseUrl` (`/v1/openapi/spec`) or an absolute URL or a file.
|
|
460
456
|
|
|
461
|
-
CLI `--base-url`, `--only`, `--seed`, `--out`, `--
|
|
457
|
+
CLI `--base-url`, `--only`, `--seed`, `--out`, `--max-in-flight`, `--keep-fixtures` override these when passed.
|
|
462
458
|
|
|
463
459
|
### Spec loading
|
|
464
460
|
|
|
@@ -540,16 +536,33 @@ principals: [
|
|
|
540
536
|
|
|
541
537
|
```ts
|
|
542
538
|
auth: {
|
|
543
|
-
steps: [ /*
|
|
539
|
+
steps: [ /* register / verify — first acquire only */ ],
|
|
544
540
|
credentialFrom: "$.access_token", // JSON path in the last (or saved) response
|
|
545
541
|
expiresInFrom: "$.expires_in", // lifetime in seconds
|
|
546
542
|
header: "authorization", // default
|
|
547
543
|
template: "Bearer {credential}", // default
|
|
548
544
|
assumeTtlMs: 3600000, // used only if neither expiresInFrom nor JWT exp is present
|
|
545
|
+
refreshBufferMs: 30_000, // optional; default 30s. Proactive when expiresAt - now <= this
|
|
546
|
+
refresh: { // signup flows must set this — re-running steps is not a refresh
|
|
547
|
+
steps: [
|
|
548
|
+
{
|
|
549
|
+
operationId: "auth.refreshToken",
|
|
550
|
+
body: { refresh_token: "{refreshToken}" },
|
|
551
|
+
saveAs: {
|
|
552
|
+
credential: "$.access_token",
|
|
553
|
+
refreshToken: "$.refresh_token",
|
|
554
|
+
},
|
|
555
|
+
},
|
|
556
|
+
],
|
|
557
|
+
},
|
|
549
558
|
}
|
|
550
559
|
```
|
|
551
560
|
|
|
552
|
-
Expiry is `expiresInFrom` (seconds) → JWT `exp` claim → `assumeTtlMs`.
|
|
561
|
+
Expiry is `expiresInFrom` (seconds) → JWT `exp` claim → `assumeTtlMs`. `assumeTtlMs` is only the fallback lifetime when nothing else revealed expiry — it is not used for the refresh threshold when `expiresAt` is known.
|
|
562
|
+
|
|
563
|
+
Refresh is countdown-based (`expiresAt - refreshBufferMs`, default 30s) before every dispatch and before each async poll. Signup flows declare `auth.refresh` (refresh-token operation). Re-running `steps` is only the fallback when `refresh` is omitted (API-key / token-exchange principals). A register-like first hop without `refresh` fails closed (`AUTH_REFRESH_REQUIRED`) rather than signing up again.
|
|
564
|
+
|
|
565
|
+
One 401 → force refresh + single retry with live headers. A second 401 is evidence. 5xx / 429 are never a refresh trigger. `expiresAt === null` (static-header principal) never proactive-refreshes.
|
|
553
566
|
|
|
554
567
|
Each step is one of:
|
|
555
568
|
|
|
@@ -561,7 +574,7 @@ Each step is one of:
|
|
|
561
574
|
body: { key: "${API_KEY}" },
|
|
562
575
|
headers: { "x-extra": "1" },
|
|
563
576
|
query: { realm: "test" },
|
|
564
|
-
saveAs: {
|
|
577
|
+
saveAs: { credential: "$.access_token", refreshToken: "$.refresh_token" },
|
|
565
578
|
saveClaimsFrom: { token: "$.access_token", bind: { orgId: "orgs.0.oid" } },
|
|
566
579
|
bind: { address: "user@example.test" }, // literals, with {name} interpolation
|
|
567
580
|
expect: [200], // default: any 2xx
|
|
@@ -585,7 +598,7 @@ Each step is one of:
|
|
|
585
598
|
{ outOfBand: { address: "{address}", kind: "email-verify", as: "verifyToken" } }
|
|
586
599
|
```
|
|
587
600
|
|
|
588
|
-
Later steps interpolate `{name}` from the flow scope. `saveAs` paths are `$.foo.bar` / `$.orgs.0.id` (dot + numeric index only; no JSON Pointer, no filters). `saveClaimsFrom` reads a JWT's _claims_ (signature is not verified — oat is reading its own credential). `rootsFromFlow` maps path parameter names to those bound keys.
|
|
601
|
+
Later steps interpolate `{name}` from the flow scope. `saveAs` paths are `$.foo.bar` / `$.orgs.0.id` (dot + numeric index only; no JSON Pointer, no filters). Bind `saveAs.refreshToken` from `$.refresh_token` so `{refreshToken}` interpolates in `auth.refresh`. `saveClaimsFrom` reads a JWT's _claims_ (signature is not verified — oat is reading its own credential). `rootsFromFlow` maps path parameter names to those bound keys.
|
|
589
602
|
|
|
590
603
|
`bind` on a step runs **before** the request. `saveAs` / `saveClaimsFrom` run **after**. `credentialFrom` is read from the last HTTP response unless a step already saved `credential`.
|
|
591
604
|
|
|
@@ -598,6 +611,16 @@ function signUp(email: string): AuthFlow {
|
|
|
598
611
|
return {
|
|
599
612
|
credentialFrom: "$.access_token",
|
|
600
613
|
expiresInFrom: "$.access_token_expires_in",
|
|
614
|
+
refresh: {
|
|
615
|
+
steps: [
|
|
616
|
+
{
|
|
617
|
+
body: { refresh_token: "{refreshToken}" },
|
|
618
|
+
method: "POST",
|
|
619
|
+
path: "/v1/auth/refresh",
|
|
620
|
+
saveAs: { credential: "$.access_token", refreshToken: "$.refresh_token" },
|
|
621
|
+
},
|
|
622
|
+
],
|
|
623
|
+
},
|
|
601
624
|
steps: [
|
|
602
625
|
{
|
|
603
626
|
bind: { address: email },
|
|
@@ -610,6 +633,7 @@ function signUp(email: string): AuthFlow {
|
|
|
610
633
|
body: { token: "{verifyToken}" },
|
|
611
634
|
method: "POST",
|
|
612
635
|
path: "/v1/auth/email/verify",
|
|
636
|
+
saveAs: { credential: "$.access_token", refreshToken: "$.refresh_token" },
|
|
613
637
|
saveClaimsFrom: {
|
|
614
638
|
token: "$.access_token",
|
|
615
639
|
bind: { orgId: "orgs.0.oid", projectId: "orgs.0.pids.0" },
|
|
@@ -775,7 +799,7 @@ Default cohort is **7** records, one of each variant, sliced by `cohortSize`:
|
|
|
775
799
|
| `lexical-first` | sorts first (`"aaa first alphabetically"`) |
|
|
776
800
|
| `lexical-last` | sorts last (`"zzz last alphabetically"`) |
|
|
777
801
|
| `null-heavy` | `null` on every nullable field |
|
|
778
|
-
| `unicode` | `"日本語
|
|
802
|
+
| `unicode` | `"äöüß čćžšđ 日本語 中文 한글 привет مرحبا 🙂"` |
|
|
779
803
|
| `metacharacter` | `"100% _off_ *everything*"` — LIKE / escape probes |
|
|
780
804
|
| `boundary` | empty / maxLength / numeric `maximum` |
|
|
781
805
|
|
|
@@ -1157,7 +1181,7 @@ export default defineConfig({
|
|
|
1157
1181
|
|
|
1158
1182
|
## Checks
|
|
1159
1183
|
|
|
1160
|
-
|
|
1184
|
+
57 checks. A check that cannot run says so (`did not apply` + `needs`). A check that depends on a broken primitive is `BLOCKED`. A check that ran and stopped is inconclusive, not a pass.
|
|
1161
1185
|
|
|
1162
1186
|
Order is fixed (foundations first) so cascade suppression has a cause to point at. Mutating checks run alone; read-only checks may share in-flight requests under `maxInFlight`.
|
|
1163
1187
|
|
|
@@ -1167,7 +1191,9 @@ Order is fixed (foundations first) so cascade suppression has a cause to point a
|
|
|
1167
1191
|
| ------------------------------------------ | ------------------------------------------------------------------------------------ | -------------------------------------------------------------------- | --------------------------------------- |
|
|
1168
1192
|
| `list.read-after-write` | a just-created record appears on the list | create + a seeded record | — |
|
|
1169
1193
|
| `create.persists-submitted-fields` | every writable field sent on create is echoed | create that echoes the record | `list.read-after-write` |
|
|
1194
|
+
| `payload.string-survives` | a documented-valid string is stored exactly; 4xx after an ASCII control is a fail | update or create+delete, item GET, unconstrained string | `list.read-after-write` |
|
|
1170
1195
|
| `create.status-matches-document` | create status is one the document declared | create | — |
|
|
1196
|
+
| `response.status-is-documented` | every non-create exchange returns a status that operation names (`default` ≠ 201) | a modeled non-create operation oat invoked | — |
|
|
1171
1197
|
| `schema.success-response-matches-document` | create body validates against the success schema | success schema on create | `create.status-matches-document` |
|
|
1172
1198
|
| `schema.error-response-matches-document` | an error body validates against the documented error schema | error schema on the item route | — |
|
|
1173
1199
|
| `pagination.limit-bounds-page-size` | page size ≤ the requested limit | page-size _role_ (aliases include `limit`, `per_page`, …) | `list.read-after-write` |
|
|
@@ -1469,7 +1495,6 @@ const result = await run({
|
|
|
1469
1495
|
baseUrl: config.baseUrl,
|
|
1470
1496
|
principals: config.principals,
|
|
1471
1497
|
seed: 1,
|
|
1472
|
-
concurrency: 1,
|
|
1473
1498
|
maxInFlight: 4,
|
|
1474
1499
|
onProgress: (snap) => {
|
|
1475
1500
|
// snap.phase, snap.entity, snap.check, snap.message, …
|
|
@@ -1492,7 +1517,7 @@ const { doc: resolved, externalRefs } = dereference(doc)
|
|
|
1492
1517
|
const model = buildModel(resolved)
|
|
1493
1518
|
```
|
|
1494
1519
|
|
|
1495
|
-
Types exported: `OatConfig`, `Principal`, `AuthFlow`, `AuthStep`, `Hooks`, `Uploads`, `UploadRequest`, `UploadFile`, `RunOptions`, `RunResult`, `Finding`, `Verdict`, `Actor`, `SpecModel`, `EntityModel`, `OperationModel`, `OpenApiDocument`, matrix types.
|
|
1520
|
+
Types exported: `OatConfig`, `Principal`, `AuthFlow`, `AuthRefresh`, `AuthStep`, `Hooks`, `Uploads`, `UploadRequest`, `UploadFile`, `RunOptions`, `RunResult`, `Finding`, `Verdict`, `Actor`, `SpecModel`, `EntityModel`, `OperationModel`, `OpenApiDocument`, `AuthRefreshRequiredError`, matrix types.
|
|
1496
1521
|
|
|
1497
1522
|
## CI
|
|
1498
1523
|
|
|
@@ -1506,7 +1531,7 @@ Against **your** API:
|
|
|
1506
1531
|
# GitHub Actions sketch
|
|
1507
1532
|
- run: npm i -D @lovrozagar/oat
|
|
1508
1533
|
- run: oat doctor --spec "$SPEC_URL"
|
|
1509
|
-
- run: oat run --config oat.config.ts
|
|
1534
|
+
- run: oat run --config oat.config.ts
|
|
1510
1535
|
env:
|
|
1511
1536
|
API_TOKEN: ${{ secrets.API_TOKEN }}
|
|
1512
1537
|
API_TOKEN_B: ${{ secrets.API_TOKEN_B }}
|
|
@@ -1514,8 +1539,6 @@ Against **your** API:
|
|
|
1514
1539
|
|
|
1515
1540
|
Gate on exit code 1 (defects). Read `oat-out/oat-report.json` if you need to classify verdicts.
|
|
1516
1541
|
|
|
1517
|
-
Nested APIs: keep `--concurrency 1`. Higher values create children while a parent page-walk is in flight and produce false `pagination.page-walk-covers-set` findings.
|
|
1518
|
-
|
|
1519
1542
|
Wipe leftover rows on a shared database between runs if a previous `--keep-fixtures` or a crashed teardown left data. Leftover rows make numeric/filter checks look like type bugs (`1, 10, 2` from old TEXT-sorted leftovers mixed with a fresh numeric cohort).
|
|
1520
1543
|
|
|
1521
1544
|
## Reference defects (`oat serve --defects`)
|
|
@@ -1526,6 +1549,8 @@ Comma-separated. Each is one named lie the demo API can tell. Primary check is w
|
|
|
1526
1549
|
| ------------------------------------------- | ------------------------------------------ | ------------------------------------------------------ |
|
|
1527
1550
|
| `STALE_LIST` | `list.read-after-write` | create succeeds, list does not show the row |
|
|
1528
1551
|
| `CREATE_DROPS_FIELD` | `create.persists-submitted-fields` | a submitted field is dropped |
|
|
1552
|
+
| `STRING_PAYLOAD_MANGLED` | `payload.string-survives` | non-ASCII / surrounding whitespace stripped on write |
|
|
1553
|
+
| `RESPONSE_STATUS_UNDECLARED` | `response.status-is-documented` | PATCH returns 201 when the document names 200 |
|
|
1529
1554
|
| `CREATED_201_AS_200` | `create.status-matches-document` | create returns 200 when the spec says 201 |
|
|
1530
1555
|
| `RESPONSE_SCHEMA_DRIFT` | `schema.success-response-matches-document` | success body does not match the schema |
|
|
1531
1556
|
| `ERROR_SCHEMA_DRIFT` | `schema.error-response-matches-document` | error body does not match the schema |
|
|
@@ -1595,7 +1620,7 @@ oat run --config labs/local.config.ts --base-url <url>
|
|
|
1595
1620
|
These are deliberate. An agent should not invent a flag for them.
|
|
1596
1621
|
|
|
1597
1622
|
- **No request timeout.** `fetch` waits until the server answers. Watch `idle_ms`.
|
|
1598
|
-
- **No retry on 5xx / 429
|
|
1623
|
+
- **No retry on 5xx / 429.** One 401 → force refresh + single retry. A second 401 is evidence.
|
|
1599
1624
|
- **No OpenAPI `security`.** Put credentials in `principals`. Cookie auth is a `headers: { cookie: "…" }` (or a flow that sets that header).
|
|
1600
1625
|
- **No `servers[]`.** Always set `baseUrl`.
|
|
1601
1626
|
- **No OCR.** Multipart and file parts are sent as dummy / pool / `resolveUpload` bytes. oat checks HTTP status and JSON responses, not whether a PDF is a real invoice.
|
|
@@ -1605,7 +1630,6 @@ These are deliberate. An agent should not invent a flag for them.
|
|
|
1605
1630
|
- **Rate-limit pacing only covers requests oat itself sends.** It cannot see traffic from anything else hitting the backend at the same time, so a shared budget can still trip even when oat's own share was within the declared rate.
|
|
1606
1631
|
- **Equality filter grammar** cannot express `neq` / `gt` / `like` / `and` / `or`. Those checks did-not-apply, they do not fail.
|
|
1607
1632
|
- **`or()` is postgrest-only.**
|
|
1608
|
-
- **Concurrency > 1 on nested graphs invents pagination bugs.** Use `1`.
|
|
1609
1633
|
- **Leftover rows on a shared DB** poison numeric and filter checks. Wipe between runs.
|
|
1610
1634
|
- **`--only` uses plan names** (`store`, not `stores` or `/v1/stores`).
|
|
1611
1635
|
- **Default cohort is 7.** `pagination.limit-respects-documented-max` needs `cohortSize > maxLimit`.
|
package/bin/oat.js
CHANGED
package/dist/cli.js
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
import { createWriteStream, writeFileSync } from "node:fs";
|
|
3
3
|
import { mkdir, rm, writeFile } from "node:fs/promises";
|
|
4
4
|
import { dirname, resolve } from "node:path";
|
|
5
|
+
import { pathToFileURL } from "node:url";
|
|
5
6
|
import { interpolate, loadConfig } from "./config/load.js";
|
|
6
7
|
import { report } from "./report/console.js";
|
|
7
8
|
import { renderMatrixGraph, renderMatrixHtml } from "./report/matrix.js";
|
|
@@ -10,7 +11,28 @@ import { createStderrProgress, formatProgressJsonl, formatProgressLine, formatPr
|
|
|
10
11
|
import { renderTeardown } from "./runtime/teardown.js";
|
|
11
12
|
import { buildModel } from "./spec/graph.js";
|
|
12
13
|
import { dereference, loadSpec } from "./spec/load.js";
|
|
13
|
-
|
|
14
|
+
export const KNOWN_FLAGS = new Set([
|
|
15
|
+
"help",
|
|
16
|
+
"config",
|
|
17
|
+
"spec",
|
|
18
|
+
"base-url",
|
|
19
|
+
"only",
|
|
20
|
+
"profile",
|
|
21
|
+
"seed",
|
|
22
|
+
"out",
|
|
23
|
+
"keep-fixtures",
|
|
24
|
+
"max-in-flight",
|
|
25
|
+
"quiet",
|
|
26
|
+
"untagged",
|
|
27
|
+
"backend",
|
|
28
|
+
"dialect",
|
|
29
|
+
"fuzz",
|
|
30
|
+
"precision",
|
|
31
|
+
"max-defects",
|
|
32
|
+
"json",
|
|
33
|
+
"parser",
|
|
34
|
+
]);
|
|
35
|
+
export function parseArgs(argv) {
|
|
14
36
|
const [command = "help", ...rest] = argv;
|
|
15
37
|
const flags = {};
|
|
16
38
|
for (let i = 0; i < rest.length; i++) {
|
|
@@ -29,7 +51,14 @@ function parseArgs(argv) {
|
|
|
29
51
|
}
|
|
30
52
|
return { command, flags };
|
|
31
53
|
}
|
|
32
|
-
|
|
54
|
+
export function unknownFlag(flags) {
|
|
55
|
+
for (const key of Object.keys(flags)) {
|
|
56
|
+
if (!KNOWN_FLAGS.has(key))
|
|
57
|
+
return key;
|
|
58
|
+
}
|
|
59
|
+
return undefined;
|
|
60
|
+
}
|
|
61
|
+
export const USAGE = `oat — OpenAPI Tester
|
|
33
62
|
|
|
34
63
|
oat run --config <file> test a live backend and write a report
|
|
35
64
|
oat plan --spec <url|file> derive and print the test model (offline)
|
|
@@ -46,7 +75,6 @@ Flags
|
|
|
46
75
|
--seed integer seed for fixture generation (default 1)
|
|
47
76
|
--out output directory for the report (default ./oat-out)
|
|
48
77
|
--keep-fixtures leave created records in place instead of tearing them down
|
|
49
|
-
--concurrency entities tested in parallel (default 1)
|
|
50
78
|
--max-in-flight requests allowed in flight at once (default 4)
|
|
51
79
|
--quiet no live progress on stderr (progress.log still written)
|
|
52
80
|
--untagged serve (or test) a document with every x-* tag stripped
|
|
@@ -139,7 +167,6 @@ async function commandRun(flags) {
|
|
|
139
167
|
...(config.profiles === undefined ? {} : { profiles: config.profiles }),
|
|
140
168
|
...(config.rateLimits === undefined ? {} : { rateLimits: config.rateLimits }),
|
|
141
169
|
keepFixtures: flags["keep-fixtures"] === true || config.keepFixtures === true,
|
|
142
|
-
concurrency: Number.parseInt(str(flags, "concurrency") ?? "", 10) || config.concurrency || 1,
|
|
143
170
|
maxInFlight: Number.parseInt(str(flags, "max-in-flight") ?? "", 10) || config.maxInFlight || 4,
|
|
144
171
|
seed: seedFlag === undefined ? (config.seed ?? 1) : Number.parseInt(seedFlag, 10),
|
|
145
172
|
onProgress,
|
|
@@ -195,14 +222,19 @@ async function commandRun(flags) {
|
|
|
195
222
|
* not failures, and a CI gate should react to defects only. */
|
|
196
223
|
return result.findings.filter((f) => f.verdict !== "COVERAGE_GAP" && f.verdict !== "BLOCKED").length > 0 ? 1 : 0;
|
|
197
224
|
}
|
|
198
|
-
async function main() {
|
|
225
|
+
export async function main() {
|
|
199
226
|
const { command, flags } = parseArgs(process.argv.slice(2));
|
|
227
|
+
const unknown = unknownFlag(flags);
|
|
228
|
+
if (unknown !== undefined) {
|
|
229
|
+
process.stderr.write(`oat: unknown flag "--${unknown}"\n\n${USAGE}`);
|
|
230
|
+
return 2;
|
|
231
|
+
}
|
|
200
232
|
if (command === "help" || flags.help === true) {
|
|
201
233
|
process.stdout.write(USAGE);
|
|
202
234
|
return 0;
|
|
203
235
|
}
|
|
204
236
|
if (command === "conformance") {
|
|
205
|
-
const { postgresAvailable, renderParserSuite, renderSuite, runExampleSpecSuite, runTagUnlockSuite, runParserSuite, runCoverageReportSuite, runSeedContractSuite, runTenantScopeSuite, runSuite, sqliteAvailable, d1Available, } = await import("./conformance/suite.js");
|
|
237
|
+
const { postgresAvailable, renderParserSuite, renderSuite, runExampleSpecSuite, runTagUnlockSuite, runParserSuite, runPayloadCatalogSuite, runCoverageReportSuite, runSeedContractSuite, runTenantScopeSuite, runSuite, sqliteAvailable, d1Available, } = await import("./conformance/suite.js");
|
|
206
238
|
const { runFeatureGateSuite } = await import("./conformance/feature-gate.js");
|
|
207
239
|
const parser = renderParserSuite(runParserSuite());
|
|
208
240
|
process.stdout.write(parser.text);
|
|
@@ -227,6 +259,9 @@ async function main() {
|
|
|
227
259
|
const seedContract = renderParserSuite(await runSeedContractSuite());
|
|
228
260
|
process.stdout.write(seedContract.text);
|
|
229
261
|
parser.failures += seedContract.failures;
|
|
262
|
+
const payloads = renderParserSuite(runPayloadCatalogSuite());
|
|
263
|
+
process.stdout.write(payloads.text);
|
|
264
|
+
parser.failures += payloads.failures;
|
|
230
265
|
if (flags.parser === true)
|
|
231
266
|
return parser.failures > 0 ? 1 : 0;
|
|
232
267
|
if (flags.precision !== undefined) {
|
|
@@ -400,10 +435,17 @@ async function main() {
|
|
|
400
435
|
return 2;
|
|
401
436
|
}
|
|
402
437
|
}
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
438
|
+
export function start() {
|
|
439
|
+
main().then((code) => {
|
|
440
|
+
process.exitCode = code;
|
|
441
|
+
}, (error) => {
|
|
442
|
+
process.stderr.write(`oat: ${error instanceof Error ? error.message : String(error)}\n`);
|
|
443
|
+
process.exitCode = 1;
|
|
444
|
+
});
|
|
445
|
+
}
|
|
446
|
+
/* `node dist/cli.js …` is the test/CI entry. `bin/oat.js` calls start() itself because
|
|
447
|
+
* argv[1] is the bin wrapper, not this module. */
|
|
448
|
+
if (process.argv[1] !== undefined && import.meta.url === pathToFileURL(resolve(process.argv[1])).href) {
|
|
449
|
+
start();
|
|
450
|
+
}
|
|
409
451
|
//# sourceMappingURL=cli.js.map
|
|
@@ -56,8 +56,13 @@ export interface OutOfBandStep {
|
|
|
56
56
|
};
|
|
57
57
|
}
|
|
58
58
|
export type AuthStep = OperationStep | RequestStep | OutOfBandStep;
|
|
59
|
+
/** How to renew a credential without re-running the acquire chain. */
|
|
60
|
+
export interface AuthRefresh {
|
|
61
|
+
/** Run against the existing scope so `{refreshToken}` interpolates. */
|
|
62
|
+
steps: [AuthStep, ...AuthStep[]];
|
|
63
|
+
}
|
|
59
64
|
export interface AuthFlow {
|
|
60
|
-
/** Run in order; values flow forward through the scope. */
|
|
65
|
+
/** Run in order; values flow forward through the scope. First acquire only. */
|
|
61
66
|
steps: [AuthStep, ...AuthStep[]];
|
|
62
67
|
/** Where the credential is in the final response, e.g. `$.access_token`. */
|
|
63
68
|
credentialFrom: string;
|
|
@@ -69,6 +74,17 @@ export interface AuthFlow {
|
|
|
69
74
|
template?: string;
|
|
70
75
|
/** Used only when neither the response nor the credential reveals an expiry. */
|
|
71
76
|
assumeTtlMs?: number;
|
|
77
|
+
/**
|
|
78
|
+
* Proactive refresh fires when `expiresAt - now <= refreshBufferMs`.
|
|
79
|
+
* Defaults to 30_000. Ignored when `expiresAt` is null (static-header principal).
|
|
80
|
+
*/
|
|
81
|
+
refreshBufferMs?: number;
|
|
82
|
+
/**
|
|
83
|
+
* Renew via these steps (typically `auth.refreshToken` + `{refreshToken}`).
|
|
84
|
+
* Signup flows must set this — re-running `steps` would register again.
|
|
85
|
+
* Omitted: re-run `steps` (API-key / token-exchange). Register-like first hops fail closed.
|
|
86
|
+
*/
|
|
87
|
+
refresh?: AuthRefresh;
|
|
72
88
|
}
|
|
73
89
|
export interface Principal {
|
|
74
90
|
id: string;
|
|
@@ -213,8 +229,6 @@ export interface OatConfig {
|
|
|
213
229
|
seed?: number;
|
|
214
230
|
/** Instances seeded per entity. Larger cohorts discriminate more, and cost more. */
|
|
215
231
|
cohortSize?: number;
|
|
216
|
-
/** Entities tested in parallel. Checks within one entity always stay ordered. */
|
|
217
|
-
concurrency?: number;
|
|
218
232
|
/** Requests allowed in flight at once. Past a server's comfort this makes runs slower. */
|
|
219
233
|
maxInFlight?: number;
|
|
220
234
|
/** Restrict the run to these entity names. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"define-config.d.ts","sourceRoot":"","sources":["../../src/config/define-config.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAIH,UAAU,QAAQ;IACjB;;;;OAIG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAC/B;;;;OAIG;IACH,cAAc,CAAC,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;KAAE,CAAA;IAChE,8EAA8E;IAC9E,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAC7B,8CAA8C;IAC9C,MAAM,CAAC,EAAE,MAAM,EAAE,CAAA;CACjB;AAED,2FAA2F;AAC3F,MAAM,WAAW,aAAc,SAAQ,QAAQ;IAC9C,WAAW,EAAE,MAAM,CAAA;IACnB,IAAI,CAAC,EAAE,OAAO,CAAA;IACd,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAChC,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CAC9B;AAED,sEAAsE;AACtE,MAAM,WAAW,WAAY,SAAQ,QAAQ;IAC5C,MAAM,EAAE,MAAM,CAAA;IACd,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,CAAC,EAAE,OAAO,CAAA;IACd,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAChC,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CAC9B;AAED;;;;;;GAMG;AACH,MAAM,WAAW,aAAa;IAC7B,SAAS,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAA;KAAE,CAAA;CACxD;AAED,MAAM,MAAM,QAAQ,GAAG,aAAa,GAAG,WAAW,GAAG,aAAa,CAAA;AAIlE,MAAM,WAAW,QAAQ;
|
|
1
|
+
{"version":3,"file":"define-config.d.ts","sourceRoot":"","sources":["../../src/config/define-config.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"define-config.js","sourceRoot":"","sources":["../../src/config/define-config.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;
|
|
1
|
+
{"version":3,"file":"define-config.js","sourceRoot":"","sources":["../../src/config/define-config.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AA4QH;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,YAAY,CAAC,MAAiB;IAC7C,OAAO,MAAM,CAAA;AACd,CAAC"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export { defineConfig } from "./config/define-config.ts";
|
|
2
|
-
export type { AuthFlow, AuthStep, Hooks, OatConfig, OperationStep, OutOfBandRequest, OutOfBandStep, Principal, ProfileSpec, RateLimitSpec, RequestStep, UploadFile, UploadRequest, UploadResolution, Uploads, } from "./config/define-config.ts";
|
|
2
|
+
export type { AuthFlow, AuthRefresh, AuthStep, Hooks, OatConfig, OperationStep, OutOfBandRequest, OutOfBandStep, Principal, ProfileSpec, RateLimitSpec, RequestStep, UploadFile, UploadRequest, UploadResolution, Uploads, } from "./config/define-config.ts";
|
|
3
3
|
export { loadConfig } from "./config/load.ts";
|
|
4
4
|
export { deriveCollectionShape, deriveIdentity } from "./spec/collection.ts";
|
|
5
5
|
export type { CollectionShape } from "./spec/collection.ts";
|
|
@@ -7,6 +7,7 @@ export { buildModel } from "./spec/graph.ts";
|
|
|
7
7
|
export type { EntityModel, OperationModel, SpecModel } from "./spec/graph.ts";
|
|
8
8
|
export { dereference, loadSpec, normalisePath, parseRouteRef } from "./spec/load.ts";
|
|
9
9
|
export type { OpenApiDocument } from "./spec/types.ts";
|
|
10
|
+
export { AuthRefreshRequiredError } from "./runtime/auth.ts";
|
|
10
11
|
export { run } from "./runtime/run.ts";
|
|
11
12
|
export type { RunOptions, RunResult } from "./runtime/run.ts";
|
|
12
13
|
export type { Actor } from "./runtime/checks.ts";
|
package/dist/index.js
CHANGED
|
@@ -3,6 +3,7 @@ export { loadConfig } from "./config/load.js";
|
|
|
3
3
|
export { deriveCollectionShape, deriveIdentity } from "./spec/collection.js";
|
|
4
4
|
export { buildModel } from "./spec/graph.js";
|
|
5
5
|
export { dereference, loadSpec, normalisePath, parseRouteRef } from "./spec/load.js";
|
|
6
|
+
export { AuthRefreshRequiredError } from "./runtime/auth.js";
|
|
6
7
|
export { run } from "./runtime/run.js";
|
|
7
8
|
export { buildMatrixGraph, matrixViewFromReport, renderMatrixGraph, renderMatrixHtml } from "./report/matrix.js";
|
|
8
9
|
export { coverageByCheck, renderConsole, renderJson, renderMarkdown, renderRepros } from "./report/render.js";
|
|
@@ -176,6 +176,20 @@ export declare const DEFECTS: {
|
|
|
176
176
|
readonly SEARCH_IGNORED: "q is accepted but does not filter the result";
|
|
177
177
|
/** A field is accepted at create and silently discarded. */
|
|
178
178
|
readonly CREATE_DROPS_FIELD: "create accepts a field and does not persist it";
|
|
179
|
+
/**
|
|
180
|
+
* Non-ASCII and surrounding whitespace are stripped on write.
|
|
181
|
+
*
|
|
182
|
+
* The realistic shape: a column that is not Unicode, a `.trim()`, a "sanitiser" that drops
|
|
183
|
+
* anything outside ASCII printable. Create of ordinary English still looks right.
|
|
184
|
+
*/
|
|
185
|
+
readonly STRING_PAYLOAD_MANGLED: "non-ASCII and surrounding whitespace are stripped on write";
|
|
186
|
+
/**
|
|
187
|
+
* An operation returns a success status the document does not name.
|
|
188
|
+
*
|
|
189
|
+
* Not REST (create must be 201). The document said 200 and the handler returned 201, so
|
|
190
|
+
* generated clients will not treat the response as success.
|
|
191
|
+
*/
|
|
192
|
+
readonly RESPONSE_STATUS_UNDECLARED: "an operation returns a status its document does not declare";
|
|
179
193
|
/** An enum field accepts values outside the declared set. */
|
|
180
194
|
readonly ENUM_NOT_VALIDATED: "enum field accepts a value outside the declared set";
|
|
181
195
|
/** A string longer than maxLength is stored. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"defects.d.ts","sourceRoot":"","sources":["../../src/reference/defects.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,eAAO,MAAM,OAAO;IACnB,iFAAiF;;IAEjF,qFAAqF;;IAErF,kEAAkE;;IAElE,iFAAiF;;IAEjF,wEAAwE;;IAExE,6CAA6C;;IAE7C,mFAAmF;;IAEnF;;;;;;OAMG;;IAEH;;;;;;OAMG;;IAEH;;;;;;;OAOG;;IAEH;;;;;;;OAOG;;IAEH;;;;;;OAMG;;IAEH;;;;;;;OAOG;;IAEH;;;;;;;OAOG;;IAEH;;;;;;OAMG;;IAGH;;;;OAIG;;IAGH;;;OAGG;;IAGH;;;;;;;;OAQG;;IAEH;;;;;;;OAOG;;IAEH;;;;;;OAMG;;IAEH;;;;;;;;OAQG;;IAEH;;;;;OAKG;;IAEH,wDAAwD;;IAExD,gDAAgD;;IAEhD,iDAAiD;;IAEjD,yDAAyD;;IAEzD,sDAAsD;;IAEtD,6DAA6D;;IAE7D,yDAAyD;;IAEzD,iDAAiD;;IAEjD,gDAAgD;;IAEhD,uDAAuD;;IAEvD,iEAAiE;;IAEjE,2EAA2E;;IAE3E,kDAAkD;;IAElD,oDAAoD;;IAEpD,4DAA4D;;IAE5D,6DAA6D;;IAE7D,gDAAgD;;IAEhD,kDAAkD;;IAElD,8DAA8D;;IAE9D,6DAA6D;;IAE7D,+DAA+D;;IAE/D,8DAA8D;;IAE9D,+DAA+D;;IAE/D,yFAAyF;;IAEzF,uFAAuF;;IAEvF,mEAAmE;;IAEnE,+EAA+E;;IAE/E,mDAAmD;;IAEnD,2EAA2E;;IAE3E;;;;;;;OAOG;;IAEH;;;OAGG;;IAEH;;;OAGG;;IAEH;;;;OAIG;;IAEH;;;;;;OAMG;;IAEH,4EAA4E;;IAE5E,6DAA6D;;CAEpD,CAAA;AAEV,MAAM,MAAM,UAAU,GAAG,MAAM,OAAO,OAAO,CAAA;AAE7C,qBAAa,SAAS;IACrB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAqB;gBAEjC,KAAK,GAAE,SAAS,MAAM,EAAO;IAIzC,MAAM,CAAC,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,SAAS;IAUpD,GAAG,CAAC,IAAI,EAAE,UAAU,GAAG,OAAO;IAI9B,IAAI,IAAI,UAAU,EAAE;CAGpB;AAED,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,KAAK,IAAI,UAAU,CAE/D"}
|
|
1
|
+
{"version":3,"file":"defects.d.ts","sourceRoot":"","sources":["../../src/reference/defects.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,eAAO,MAAM,OAAO;IACnB,iFAAiF;;IAEjF,qFAAqF;;IAErF,kEAAkE;;IAElE,iFAAiF;;IAEjF,wEAAwE;;IAExE,6CAA6C;;IAE7C,mFAAmF;;IAEnF;;;;;;OAMG;;IAEH;;;;;;OAMG;;IAEH;;;;;;;OAOG;;IAEH;;;;;;;OAOG;;IAEH;;;;;;OAMG;;IAEH;;;;;;;OAOG;;IAEH;;;;;;;OAOG;;IAEH;;;;;;OAMG;;IAGH;;;;OAIG;;IAGH;;;OAGG;;IAGH;;;;;;;;OAQG;;IAEH;;;;;;;OAOG;;IAEH;;;;;;OAMG;;IAEH;;;;;;;;OAQG;;IAEH;;;;;OAKG;;IAEH,wDAAwD;;IAExD,gDAAgD;;IAEhD,iDAAiD;;IAEjD,yDAAyD;;IAEzD,sDAAsD;;IAEtD,6DAA6D;;IAE7D,yDAAyD;;IAEzD,iDAAiD;;IAEjD,gDAAgD;;IAEhD,uDAAuD;;IAEvD,iEAAiE;;IAEjE,2EAA2E;;IAE3E,kDAAkD;;IAElD,oDAAoD;;IAEpD,4DAA4D;;IAE5D;;;;;OAKG;;IAEH;;;;;OAKG;;IAEH,6DAA6D;;IAE7D,gDAAgD;;IAEhD,kDAAkD;;IAElD,8DAA8D;;IAE9D,6DAA6D;;IAE7D,+DAA+D;;IAE/D,8DAA8D;;IAE9D,+DAA+D;;IAE/D,yFAAyF;;IAEzF,uFAAuF;;IAEvF,mEAAmE;;IAEnE,+EAA+E;;IAE/E,mDAAmD;;IAEnD,2EAA2E;;IAE3E;;;;;;;OAOG;;IAEH;;;OAGG;;IAEH;;;OAGG;;IAEH;;;;OAIG;;IAEH;;;;;;OAMG;;IAEH,4EAA4E;;IAE5E,6DAA6D;;CAEpD,CAAA;AAEV,MAAM,MAAM,UAAU,GAAG,MAAM,OAAO,OAAO,CAAA;AAE7C,qBAAa,SAAS;IACrB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAqB;gBAEjC,KAAK,GAAE,SAAS,MAAM,EAAO;IAIzC,MAAM,CAAC,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,SAAS;IAUpD,GAAG,CAAC,IAAI,EAAE,UAAU,GAAG,OAAO;IAI9B,IAAI,IAAI,UAAU,EAAE;CAGpB;AAED,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,KAAK,IAAI,UAAU,CAE/D"}
|
|
@@ -176,6 +176,20 @@ export const DEFECTS = {
|
|
|
176
176
|
SEARCH_IGNORED: "q is accepted but does not filter the result",
|
|
177
177
|
/** A field is accepted at create and silently discarded. */
|
|
178
178
|
CREATE_DROPS_FIELD: "create accepts a field and does not persist it",
|
|
179
|
+
/**
|
|
180
|
+
* Non-ASCII and surrounding whitespace are stripped on write.
|
|
181
|
+
*
|
|
182
|
+
* The realistic shape: a column that is not Unicode, a `.trim()`, a "sanitiser" that drops
|
|
183
|
+
* anything outside ASCII printable. Create of ordinary English still looks right.
|
|
184
|
+
*/
|
|
185
|
+
STRING_PAYLOAD_MANGLED: "non-ASCII and surrounding whitespace are stripped on write",
|
|
186
|
+
/**
|
|
187
|
+
* An operation returns a success status the document does not name.
|
|
188
|
+
*
|
|
189
|
+
* Not REST (create must be 201). The document said 200 and the handler returned 201, so
|
|
190
|
+
* generated clients will not treat the response as success.
|
|
191
|
+
*/
|
|
192
|
+
RESPONSE_STATUS_UNDECLARED: "an operation returns a status its document does not declare",
|
|
179
193
|
/** An enum field accepts values outside the declared set. */
|
|
180
194
|
ENUM_NOT_VALIDATED: "enum field accepts a value outside the declared set",
|
|
181
195
|
/** A string longer than maxLength is stored. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"defects.js","sourceRoot":"","sources":["../../src/reference/defects.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"defects.js","sourceRoot":"","sources":["../../src/reference/defects.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"http.d.ts","sourceRoot":"","sources":["../../src/reference/http.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,EAAsC,KAAK,MAAM,EAAuB,MAAM,WAAW,CAAA;AAEhG,OAAO,EAAwB,KAAK,SAAS,EAAE,MAAM,cAAc,CAAA;AAInE,OAAO,EAAsB,KAAK,KAAK,EAAE,MAAM,gBAAgB,CAAA;AAE/D,UAAU,SAAS;IAClB,GAAG,EAAE,MAAM,CAAA;IACX,KAAK,EAAE,MAAM,CAAA;IACb,SAAS,EAAE,MAAM,CAAA;IACjB,8EAA8E;IAC9E,IAAI,EAAE,MAAM,CAAA;CACZ;
|
|
1
|
+
{"version":3,"file":"http.d.ts","sourceRoot":"","sources":["../../src/reference/http.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,EAAsC,KAAK,MAAM,EAAuB,MAAM,WAAW,CAAA;AAEhG,OAAO,EAAwB,KAAK,SAAS,EAAE,MAAM,cAAc,CAAA;AAInE,OAAO,EAAsB,KAAK,KAAK,EAAE,MAAM,gBAAgB,CAAA;AAE/D,UAAU,SAAS;IAClB,GAAG,EAAE,MAAM,CAAA;IACX,KAAK,EAAE,MAAM,CAAA;IACb,SAAS,EAAE,MAAM,CAAA;IACjB,8EAA8E;IAC9E,IAAI,EAAE,MAAM,CAAA;CACZ;AA0ID,MAAM,WAAW,eAAe;IAC/B,MAAM,EAAE,MAAM,CAAA;IACd,GAAG,EAAE,MAAM,CAAA;IACX,OAAO,EAAE,SAAS,CAAA;IAClB,KAAK,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;IAC1B,UAAU,EAAE,SAAS,EAAE,CAAA;CACvB;AAED;;;GAGG;AACH,wBAAsB,qBAAqB,CAC1C,OAAO,EAAE;IAAE,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAAE,EAIrE,WAAW,EAAE,CAAC,OAAO,EAAE,SAAS,KAAK,OAAO,CAAC,KAAK,CAAC,GACjD,OAAO,CAAC,eAAe,CAAC,CAykB1B;AAsKD,uFAAuF;AACvF,wBAAsB,kBAAkB,CACvC,OAAO,GAAE;IAAE,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAAO,GACxE,OAAO,CAAC,eAAe,CAAC,CAG1B;AAED,oEAAoE;AACpE,wBAAsB,kBAAkB,CACvC,OAAO,GAAE;IAAE,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAAO,GACxE,OAAO,CAAC,eAAe,CAAC,CAI1B;AAED;;;;;;GAMG;AACH,wBAAsB,cAAc,CACnC,OAAO,GAAE;IACR,OAAO,CAAC,EAAE,MAAM,EAAE,CAAA;IAClB,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAA;CACZ,GACJ,OAAO,CAAC,eAAe,CAAC,CA2B1B;AAED,gGAAgG;AAChG,wBAAsB,oBAAoB,CACzC,OAAO,GAAE;IAAE,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAAO,GACxE,OAAO,CAAC,eAAe,CAAC,CAG1B"}
|
package/dist/reference/http.js
CHANGED
|
@@ -105,6 +105,9 @@ function coerceField(field, value, defects) {
|
|
|
105
105
|
if (field.enum !== undefined && !field.enum.includes(value) && !defects.has("ENUM_NOT_VALIDATED")) {
|
|
106
106
|
throw new HttpError(400, "invalid_input", `field "${field.name}" must be one of ${field.enum.join(", ")}`);
|
|
107
107
|
}
|
|
108
|
+
if (defects.has("STRING_PAYLOAD_MANGLED")) {
|
|
109
|
+
return value.replace(/[^\x20-\x7E]/g, "").trim();
|
|
110
|
+
}
|
|
108
111
|
return value;
|
|
109
112
|
}
|
|
110
113
|
function matchRoute(pathname) {
|
|
@@ -593,7 +596,7 @@ createStore) {
|
|
|
593
596
|
delete changes[parent];
|
|
594
597
|
}
|
|
595
598
|
const updated = await store.update(entity, itemId, changes);
|
|
596
|
-
return send(res, 200, decorate(updated ?? { ...existing, ...changes }));
|
|
599
|
+
return send(res, defects.has("RESPONSE_STATUS_UNDECLARED") ? 201 : 200, decorate(updated ?? { ...existing, ...changes }));
|
|
597
600
|
}
|
|
598
601
|
if (method === "DELETE") {
|
|
599
602
|
assertWrite(principal, "delete");
|