typespec-http-zod 0.27.0 → 0.28.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 +6 -6
- package/dist/src/api.d.ts +42 -9
- package/dist/src/api.js +619 -295
- package/dist/src/constraints.d.ts +1 -1
- package/dist/src/constraints.js +14 -10
- package/dist/src/registry.js +26 -5
- package/dist/src/results.d.ts +113 -0
- package/dist/src/results.js +134 -0
- package/dist/src/statuses.d.ts +24 -0
- package/dist/src/statuses.js +27 -0
- package/dist/src/types.js +37 -24
- package/dist/src/uri-template.d.ts +1 -1
- package/dist/src/uri-template.js +4 -1
- package/dist/src/zod.d.ts +15 -1
- package/dist/src/zod.js +19 -1
- package/package.json +14 -14
package/README.md
CHANGED
|
@@ -177,12 +177,12 @@ then a range such as `4XX`, then `default`.
|
|
|
177
177
|
|
|
178
178
|
## What it emits
|
|
179
179
|
|
|
180
|
-
| file | contents
|
|
181
|
-
| ---------------------- |
|
|
182
|
-
| `schemas.gen.ts` | component schemas, per-operation path, query, header, body and response validators, and the response arms
|
|
183
|
-
| `requests.gen.ts` | framework-free TypeScript types, with no imports
|
|
184
|
-
| `vocabularies.gen.ts` | each enum's members as a runtime tuple
|
|
185
|
-
| `wire-contract.gen.ts` | assertions pairing the emitted Zod against those types
|
|
180
|
+
| file | contents | emitted when |
|
|
181
|
+
| ---------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------- |
|
|
182
|
+
| `schemas.gen.ts` | component schemas, per-operation path, query, header, body and response validators, and the response arms | always |
|
|
183
|
+
| `requests.gen.ts` | framework-free TypeScript types, with no imports: the models, and every operation's input, success bodies and result (`WireInputs`, `WireOutputs`, `WireResults`) | `contracts-output-dir` is set |
|
|
184
|
+
| `vocabularies.gen.ts` | each enum's members as a runtime tuple | `contracts-output-dir` is set |
|
|
185
|
+
| `wire-contract.gen.ts` | assertions pairing the emitted Zod against those types | that and `contracts-package` |
|
|
186
186
|
|
|
187
187
|
`wire-contract.gen.ts` is not imported by any other file. The file contains type-level assertions
|
|
188
188
|
pairing each generated validator with its contract type, so a mismatch between the two is a compile
|
package/dist/src/api.d.ts
CHANGED
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
import { type EmitContext, type Program, type Type } from "@typespec/compiler";
|
|
2
2
|
import { type HttpOperation, type HttpService } from "@typespec/http";
|
|
3
3
|
import { SchemaRegistry } from "./registry.js";
|
|
4
|
+
import { type StatusKey } from "./results.js";
|
|
4
5
|
import { type EmittedPathSegment } from "./uri-template.js";
|
|
5
6
|
export type { EmittedPathSegment } from "./uri-template.js";
|
|
7
|
+
export { CONTENTLESS_STATUS_CODES, STATUS_CODES } from "./statuses.js";
|
|
8
|
+
export { type BodyServing, isJsonMediaType, isMediaRange, isTextualMediaType, mediaTypeEssenceOf, mediaTypeTypeOf, type ResponseFacts, type ResultMember, resultMembersOf, type StatusKey, statusCodesOf, } from "./results.js";
|
|
6
9
|
/**
|
|
7
10
|
* `typespec-http-zod` - Zod validators and framework-free contract types from a TypeSpec HTTP
|
|
8
11
|
* service, agreeing with the OpenAPI document `@typespec/openapi3` publishes from the same source.
|
|
@@ -64,13 +67,6 @@ export declare function successStatusOf(operation: HttpOperation): number | unde
|
|
|
64
67
|
* asserts the two stay in step.
|
|
65
68
|
*/
|
|
66
69
|
export declare function successStatusesOf(operation: HttpOperation): number[];
|
|
67
|
-
/**
|
|
68
|
-
* A status as the DOCUMENT keys it: an exact code, a `4XX` bucket, or the catch-all.
|
|
69
|
-
*
|
|
70
|
-
* `"default"` is kept as itself rather than mapped to a number. The document means "any status not
|
|
71
|
-
* listed above", and inventing one would be answering a question the contract left open.
|
|
72
|
-
*/
|
|
73
|
-
export type StatusKey = number | "default" | `${1 | 2 | 3 | 4 | 5}XX`;
|
|
74
70
|
/**
|
|
75
71
|
* A header one response declares, as a handler has to supply it.
|
|
76
72
|
*
|
|
@@ -328,10 +324,29 @@ export interface EmittedRoute {
|
|
|
328
324
|
/**
|
|
329
325
|
* The input property that receives the UNPARSED body, when the operation declares one.
|
|
330
326
|
*
|
|
331
|
-
* A `bytes` body
|
|
332
|
-
* what arrived, parsing and re-serialising would verify
|
|
327
|
+
* Three bodies are handed over unparsed. A `bytes` body, because the bytes themselves are the
|
|
328
|
+
* contract: where a signature covers exactly what arrived, parsing and re-serialising would verify
|
|
329
|
+
* a different string than the sender signed. An `Http.File` body, whose contents are the body. And
|
|
330
|
+
* a body declared only under media types nothing can parse into it, such as a model as
|
|
331
|
+
* `application/xml`, which is the text that arrived, or as `application/octet-stream`, which is
|
|
332
|
+
* the bytes. {@link rawBodyBinary} says which are bytes.
|
|
333
333
|
*/
|
|
334
334
|
readonly rawBodyProperty: string | undefined;
|
|
335
|
+
/**
|
|
336
|
+
* Whether the raw body is BYTES - handed over as the unread stream - rather than the text a
|
|
337
|
+
* signature covers. A `bytes` body is bytes under a binary media type and text under a JSON one;
|
|
338
|
+
* an `Http.File` body is bytes whatever its media type, which is why a server cannot read this off
|
|
339
|
+
* {@link requestContentTypes}: a file declared `application/json` looks like a JSON body there.
|
|
340
|
+
* `false` where there is no raw body.
|
|
341
|
+
*/
|
|
342
|
+
readonly rawBodyBinary: boolean;
|
|
343
|
+
/**
|
|
344
|
+
* **The raw body is declared with a schema nothing checks it against**: it is declared only under
|
|
345
|
+
* media types nothing can parse into it, such as a model as `application/xml`. A `bytes` or
|
|
346
|
+
* `Http.File` body declares nothing to check, so it is not this. The request-side twin of
|
|
347
|
+
* {@link ResultMember.unvalidated}.
|
|
348
|
+
*/
|
|
349
|
+
readonly rawBodyUnvalidated: boolean;
|
|
335
350
|
/**
|
|
336
351
|
* The input property a PARSED body arrives under, where it must not be spread into the parameters.
|
|
337
352
|
*
|
|
@@ -427,6 +442,17 @@ export interface RouteSchemaNames {
|
|
|
427
442
|
*/
|
|
428
443
|
readonly queryFields: string | undefined;
|
|
429
444
|
readonly header: string | undefined;
|
|
445
|
+
/**
|
|
446
|
+
* **The `accept` the negotiation selects this operation by**, on a route several operations
|
|
447
|
+
* share. `header` leaves it out there, because it chooses the operation rather than constraining
|
|
448
|
+
* one, and the operation's input still declares it: the one value that reaches this operation is
|
|
449
|
+
* its own literal, so a handler receives exactly that. `undefined` wherever `header` validates
|
|
450
|
+
* `accept` itself, or the operation declares no literal one.
|
|
451
|
+
*/
|
|
452
|
+
readonly selectedAccept: {
|
|
453
|
+
readonly name: string;
|
|
454
|
+
readonly value: string;
|
|
455
|
+
} | undefined;
|
|
430
456
|
/**
|
|
431
457
|
* Cookie parameters. **Optional on the interface, so a server emitter that does not read it yet
|
|
432
458
|
* still compiles** - this arrived after the other four and two emitters consume this type.
|
|
@@ -475,6 +501,13 @@ export interface EmittedService {
|
|
|
475
501
|
readonly routes: readonly EmittedRoute[];
|
|
476
502
|
/** The identifiers every per-operation validator was declared under, keyed by operation id. */
|
|
477
503
|
readonly schemaNames: ReadonlyMap<string, RouteSchemaNames>;
|
|
504
|
+
/**
|
|
505
|
+
* **The operation each route was collected from, keyed by operation id**, so a wrapping emitter
|
|
506
|
+
* reading its doc comment, tags or diagnostic target reads the right one. Verb and path do not
|
|
507
|
+
* identify an operation: `@sharedRoute` puts several on one, and a lookup by them answers the
|
|
508
|
+
* same operation for each - its description became every member's, and its tags selected them.
|
|
509
|
+
*/
|
|
510
|
+
readonly operations: ReadonlyMap<string, HttpOperation>;
|
|
478
511
|
/** Where this service's artefacts were written - a server emitter writes its own beside them. */
|
|
479
512
|
readonly outputDir: string;
|
|
480
513
|
/** Already resolved through the per-service overrides, so a caller re-reads nothing. */
|