@openaddresses/batch-schema 10.25.0 → 10.27.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/.github/workflows/test.yml +19 -19
- package/CHANGELOG.md +15 -0
- package/README.md +78 -0
- package/dist/lib/openapi.js +16 -6
- package/dist/lib/openapi.js.map +1 -1
- package/dist/lib/schema.d.ts +45 -2
- package/dist/lib/schema.js +177 -192
- package/dist/lib/schema.js.map +1 -1
- package/dist/lib/types.d.ts +48 -1
- package/dist/lib/types.js +48 -1
- package/dist/lib/types.js.map +1 -1
- package/dist/test/response.srv.test.d.ts +1 -0
- package/dist/test/response.srv.test.js +95 -0
- package/dist/test/response.srv.test.js.map +1 -0
- package/dist/test/schema.srv.test.js +216 -0
- package/dist/test/schema.srv.test.js.map +1 -1
- package/lib/openapi.ts +14 -6
- package/lib/schema.ts +224 -201
- package/lib/types.ts +86 -1
- package/package.json +1 -1
- package/test/response.srv.test.ts +114 -0
- package/test/schema.srv.test.ts +244 -0
|
@@ -1,29 +1,29 @@
|
|
|
1
1
|
name: Test
|
|
2
2
|
|
|
3
3
|
on:
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
4
|
+
pull_request:
|
|
5
|
+
types:
|
|
6
|
+
- opened
|
|
7
|
+
- synchronize
|
|
8
|
+
- reopened
|
|
9
|
+
- ready_for_review
|
|
10
10
|
|
|
11
11
|
jobs:
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
12
|
+
build:
|
|
13
|
+
runs-on: ubuntu-latest
|
|
14
|
+
if: github.event.pull_request.draft == false
|
|
15
|
+
steps:
|
|
16
|
+
- uses: actions/checkout@v2
|
|
17
|
+
with:
|
|
18
|
+
ref: ${{ github.event.pull_request.head.sha }}
|
|
19
19
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
20
|
+
- uses: actions/setup-node@v2
|
|
21
|
+
with:
|
|
22
|
+
node-version: '18'
|
|
23
23
|
|
|
24
|
-
|
|
24
|
+
- run: npm install
|
|
25
25
|
|
|
26
|
-
|
|
26
|
+
- run: npm run lint
|
|
27
27
|
|
|
28
|
-
|
|
28
|
+
- run: npm test
|
|
29
29
|
|
package/CHANGELOG.md
CHANGED
|
@@ -10,6 +10,21 @@
|
|
|
10
10
|
|
|
11
11
|
## Version History
|
|
12
12
|
|
|
13
|
+
### v10.27.0 - 2026-07-06
|
|
14
|
+
|
|
15
|
+
- :rocket: Only wrap `res.json` when a route has a response schema that requires validation — routes without one no longer pay any response-path overhead
|
|
16
|
+
- :rocket: Replace the `JSON.parse(JSON.stringify())` response clone with a single-pass JSON-semantics clone (~1.3-1.6x faster, no intermediate string allocation)
|
|
17
|
+
- :rocket: Skip the response clone entirely for non-200 responses (validation was already skipped)
|
|
18
|
+
- :bug: `Type.Any`/`Type.Unknown` response schemas were still compiled and validated on every request due to a broken `instanceof` check; now detected via the TypeBox `Kind` symbol and skipped
|
|
19
|
+
- :rocket: Precompute the body content-type matcher and supported-types error string at route registration instead of rebuilding them per request
|
|
20
|
+
- :rocket: Consolidate the five per-method route registration paths into a single shared implementation
|
|
21
|
+
- :rocket: Truncate response-validation error logging to 4KB
|
|
22
|
+
- :white_check_mark: Add response validation test suite
|
|
23
|
+
|
|
24
|
+
### v10.26.0
|
|
25
|
+
|
|
26
|
+
- :rocket: Allow non-json content-type
|
|
27
|
+
|
|
13
28
|
### v10.25.0
|
|
14
29
|
|
|
15
30
|
- :rocket: Add `deprecated` Boolean
|
package/README.md
CHANGED
|
@@ -52,6 +52,84 @@ async function server() {
|
|
|
52
52
|
|
|
53
53
|
Set `deprecated: true` on a route schema to mark the generated OpenAPI operation as deprecated.
|
|
54
54
|
|
|
55
|
+
## Request Body Validation
|
|
56
|
+
|
|
57
|
+
The `body` option accepts two forms.
|
|
58
|
+
|
|
59
|
+
### Single TypeBox schema (legacy / shorthand)
|
|
60
|
+
|
|
61
|
+
A bare schema is treated as `application/json`:
|
|
62
|
+
|
|
63
|
+
```js
|
|
64
|
+
await schema.post('/login', {
|
|
65
|
+
body: Type.Object({
|
|
66
|
+
username: Type.String(),
|
|
67
|
+
password: Type.String()
|
|
68
|
+
}),
|
|
69
|
+
res: Type.Object({ token: Type.String() })
|
|
70
|
+
}, handler);
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
### Map keyed by content-type
|
|
74
|
+
|
|
75
|
+
Provide a record where each key is a Content-Type. The value can be:
|
|
76
|
+
|
|
77
|
+
- a `TSchema` — body is validated against the schema
|
|
78
|
+
- `true` — body is accepted but not validated (useful for XML / CSV / binary)
|
|
79
|
+
- a `{ schema, example, examples }` object — `example` and `examples` are
|
|
80
|
+
forwarded to the OpenAPI media type for documentation
|
|
81
|
+
|
|
82
|
+
Wildcards are supported in keys: `text/*`, `application/*`, `*/*`. An exact
|
|
83
|
+
content-type match always wins over a wildcard.
|
|
84
|
+
|
|
85
|
+
```js
|
|
86
|
+
await schema.post('/ingest', {
|
|
87
|
+
body: {
|
|
88
|
+
// Strict JSON validation
|
|
89
|
+
'application/json': Type.Object({ name: Type.String() }),
|
|
90
|
+
|
|
91
|
+
// Any XML accepted
|
|
92
|
+
'text/xml': true,
|
|
93
|
+
|
|
94
|
+
// Wildcard family — matches text/csv, text/plain, etc.
|
|
95
|
+
'text/*': true,
|
|
96
|
+
|
|
97
|
+
// Schema + Swagger UI examples
|
|
98
|
+
'application/vnd.api+json': {
|
|
99
|
+
schema: Type.Object({ data: Type.Any() }),
|
|
100
|
+
example: { data: { id: '1' } },
|
|
101
|
+
examples: {
|
|
102
|
+
primary: { summary: 'Primary', value: { data: { id: '1' } } },
|
|
103
|
+
secondary: { summary: 'Secondary', value: { data: { id: '2' } } }
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
},
|
|
107
|
+
res: Type.Any()
|
|
108
|
+
}, handler);
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
If a request arrives with a Content-Type that is not listed (and is not
|
|
112
|
+
covered by a wildcard), the route responds with HTTP 400 and a
|
|
113
|
+
`Content-Type ... not supported` message — the handler is not invoked.
|
|
114
|
+
|
|
115
|
+
For non-JSON content-types the body parser exposes the raw payload on
|
|
116
|
+
`req.body` as a string (`text/*`, `application/xml`, `application/*+xml`)
|
|
117
|
+
or a `Buffer` (`application/octet-stream`).
|
|
118
|
+
|
|
119
|
+
### Optional bodies
|
|
120
|
+
|
|
121
|
+
Set `bodyRequired: false` to allow requests with no body / no Content-Type.
|
|
122
|
+
When a body *is* sent it is still validated against the matching schema,
|
|
123
|
+
and the OpenAPI document marks `requestBody.required` as `false`.
|
|
124
|
+
|
|
125
|
+
```js
|
|
126
|
+
await schema.post('/maybe', {
|
|
127
|
+
body: Type.Object({ note: Type.String() }),
|
|
128
|
+
bodyRequired: false,
|
|
129
|
+
res: Type.Object({ ok: Type.Boolean() })
|
|
130
|
+
}, handler);
|
|
131
|
+
```
|
|
132
|
+
|
|
55
133
|
## API
|
|
56
134
|
|
|
57
135
|
```js
|
package/dist/lib/openapi.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { OpenAPIV3 as Doc } from 'openapi-types';
|
|
2
|
+
import { normalizeBody } from './types.js';
|
|
2
3
|
/**
|
|
3
4
|
* @class
|
|
4
5
|
*/
|
|
@@ -110,13 +111,22 @@ export default class Docs {
|
|
|
110
111
|
};
|
|
111
112
|
}
|
|
112
113
|
if (schemas.body) {
|
|
114
|
+
const normalized = normalizeBody(schemas.body) || {};
|
|
115
|
+
const content = {};
|
|
116
|
+
for (const ct of Object.keys(normalized)) {
|
|
117
|
+
const entry = normalized[ct];
|
|
118
|
+
const media = {
|
|
119
|
+
schema: entry.schema === true ? {} : entry.schema
|
|
120
|
+
};
|
|
121
|
+
if (entry.example !== undefined)
|
|
122
|
+
media.example = entry.example;
|
|
123
|
+
if (entry.examples !== undefined)
|
|
124
|
+
media.examples = entry.examples;
|
|
125
|
+
content[ct] = media;
|
|
126
|
+
}
|
|
113
127
|
document.requestBody = {
|
|
114
|
-
required:
|
|
115
|
-
content
|
|
116
|
-
'application/json': {
|
|
117
|
-
schema: schemas.body
|
|
118
|
-
}
|
|
119
|
-
}
|
|
128
|
+
required: schemas.bodyRequired !== false,
|
|
129
|
+
content
|
|
120
130
|
};
|
|
121
131
|
}
|
|
122
132
|
this.base.paths[pathstr][parsed.method] = document;
|
package/dist/lib/openapi.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"openapi.js","sourceRoot":"","sources":["../../lib/openapi.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,IAAI,GAAG,EAAE,MAAM,eAAe,CAAA;
|
|
1
|
+
{"version":3,"file":"openapi.js","sourceRoot":"","sources":["../../lib/openapi.ts"],"names":[],"mappings":"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"}
|
package/dist/lib/schema.d.ts
CHANGED
|
@@ -5,14 +5,25 @@ import type { Static, TSchema } from '@sinclair/typebox';
|
|
|
5
5
|
import { OpenAPIV3 as Doc } from 'openapi-types';
|
|
6
6
|
import { Router } from 'express';
|
|
7
7
|
import type { RequestHandler } from 'express';
|
|
8
|
-
import type { ErrorObject } from 'ajv';
|
|
9
|
-
import type { RequestValidation } from './types.js';
|
|
8
|
+
import type { ErrorObject, ValidateFunction } from 'ajv';
|
|
9
|
+
import type { RequestValidation, NormalizedBody } from './types.js';
|
|
10
10
|
import type { OpenAPIDocumentInput } from './openapi.js';
|
|
11
11
|
import Docs from './openapi.js';
|
|
12
12
|
export type ErrorListItem = {
|
|
13
13
|
type: 'Body' | 'Query' | 'Params';
|
|
14
14
|
errors: ErrorObject[];
|
|
15
15
|
};
|
|
16
|
+
/**
|
|
17
|
+
* Per-route body validation state, compiled once at route registration:
|
|
18
|
+
* ajv validators keyed by content-type, the normalized map used for
|
|
19
|
+
* content-type matching, and the precomputed supported-types string
|
|
20
|
+
* used in error messages.
|
|
21
|
+
*/
|
|
22
|
+
export type CompiledBodyValidation = {
|
|
23
|
+
validators: Map<string, true | ValidateFunction>;
|
|
24
|
+
matcher: NormalizedBody;
|
|
25
|
+
supported: string;
|
|
26
|
+
};
|
|
16
27
|
/**
|
|
17
28
|
* @class
|
|
18
29
|
*
|
|
@@ -33,6 +44,25 @@ export default class Schemas {
|
|
|
33
44
|
error: Record<number, TSchema>;
|
|
34
45
|
schemas: Map<string, RequestValidation<TSchema, TSchema, TSchema, TSchema>>;
|
|
35
46
|
validationError(method: Doc.HttpMethods, path: string): Err;
|
|
47
|
+
/**
|
|
48
|
+
* Compile body validators keyed by content-type. Returns null when no
|
|
49
|
+
* body validation is configured. Each validator entry is either `true`
|
|
50
|
+
* (any body accepted for this content-type) or a compiled ajv validator.
|
|
51
|
+
* The content-type matcher and supported-types error string are
|
|
52
|
+
* precomputed here so no per-request allocation is needed.
|
|
53
|
+
*/
|
|
54
|
+
compileBodyValidators(body: RequestValidation<TSchema, TSchema, TSchema, TSchema>['body']): CompiledBodyValidation | null;
|
|
55
|
+
/**
|
|
56
|
+
* Validate the incoming request body against the compiled validation
|
|
57
|
+
* state for the route. Pushes a Body error onto `errors` if validation
|
|
58
|
+
* fails; returns an Err to respond with for an unsupported content-type.
|
|
59
|
+
*
|
|
60
|
+
* If `opts.required` is false and the request has no body / no
|
|
61
|
+
* content-type, validation is skipped.
|
|
62
|
+
*/
|
|
63
|
+
validateBody(req: Request, compiled: CompiledBodyValidation, errors: Array<ErrorListItem>, opts?: {
|
|
64
|
+
required?: boolean;
|
|
65
|
+
}): Err | null;
|
|
36
66
|
constructor(router: Router, opts?: {
|
|
37
67
|
prefix?: string;
|
|
38
68
|
logging?: boolean | morgan.Options<Request, Response>;
|
|
@@ -65,6 +95,19 @@ export default class Schemas {
|
|
|
65
95
|
blueprint<T>(bp_fn: (schema: Schemas, config?: T) => Promise<void>, config?: T, opts?: {
|
|
66
96
|
silent: boolean;
|
|
67
97
|
}): Promise<void>;
|
|
98
|
+
/**
|
|
99
|
+
* Compile the response validator for a route. Type.Any and Type.Unknown
|
|
100
|
+
* impose no constraints, so they are skipped entirely — routes with an
|
|
101
|
+
* open response schema (or none) bypass response validation and its
|
|
102
|
+
* clone at request time.
|
|
103
|
+
*/
|
|
104
|
+
private compileResponseValidation;
|
|
105
|
+
/**
|
|
106
|
+
* Shared route registration: compiles all validators once, then installs
|
|
107
|
+
* a request handler that validates params/query/body and — only when a
|
|
108
|
+
* response schema requires it — wraps res.json with response validation.
|
|
109
|
+
*/
|
|
110
|
+
private route;
|
|
68
111
|
get<TParams extends TSchema, TQuery extends TSchema, TBody extends TSchema, TResponse extends TSchema>(path: string, opts: RequestValidation<TParams, TQuery, TBody, TResponse> | undefined, handler: RequestHandler<Static<TParams>, Static<TResponse>, Static<TBody>, Static<TQuery>>): Promise<void>;
|
|
69
112
|
delete<TParams extends TSchema, TQuery extends TSchema, TBody extends TSchema, TResponse extends TSchema>(path: string, opts: RequestValidation<TParams, TQuery, TBody, TResponse> | undefined, handler: RequestHandler<Static<TParams>, Static<TResponse>, Static<TBody>, Static<TQuery>>): Promise<void>;
|
|
70
113
|
post<TParams extends TSchema, TQuery extends TSchema, TBody extends TSchema, TResponse extends TSchema>(path: string, opts: RequestValidation<TParams, TQuery, TBody, TResponse> | undefined, handler: RequestHandler<Static<TParams>, Static<TResponse>, Static<TBody>, Static<TQuery>>): Promise<void>;
|