typespec-http-zod 0.30.0 → 0.32.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 CHANGED
@@ -50,6 +50,9 @@ And the OpenAPI that [`@typespec/openapi3`](https://typespec.io) generates from
50
50
 
51
51
  - **Documentation and validation cannot drift** - both come from one definition, so there is no
52
52
  second source to keep in step
53
+ - **Agrees with the OpenAPI version you publish** - 3.0, `@typespec/openapi3`'s default, and 3.1 read
54
+ some schemas differently; the validators follow the `openapi-versions` you give openapi3, and refuse
55
+ at compile what a 3.0 document cannot say. See [OpenAPI versions](docs/guides.md#openapi-versions)
53
56
  - **One runtime dependency** - `zod`, and nothing else
54
57
  - **No framework** - use the validators in a server, a client, or a test
55
58
  - **Types with zero imports** - a contracts module anything can depend on
@@ -193,6 +196,25 @@ break the build until the validator and the contract type diverge.
193
196
  Identifiers are named from the operation id the document publishes. An operation inside a namespace
194
197
  carries the whole id, so `op readWidget` in `namespace Widgets` becomes `Widgets_readWidgetPath`.
195
198
 
199
+ Every component the document publishes is declared under its name - `widgetSchema` and `Widget` -
200
+ including the types no operation reaches, which openapi3 publishes at `All`, and those no route
201
+ names, such as a model a merge holds. A type used only by an operation the document leaves out -
202
+ one whose path holds a query string, or an `@overload` on its base operation's endpoint - is
203
+ declared too, as its validators are emitted. A component carries a visibility suffix,
204
+ `WidgetCreate`, only where its type is used at more than one visibility, as openapi3 names it. Four
205
+ names cannot be TypeScript's, and are not: a namespace is dropped, as one module has one, so two
206
+ types of one name in two namespaces are `duplicate-declaration`; a character an identifier cannot
207
+ hold is written `_`, `Hy-phen` as `Hy_phen`, and a name TypeScript refuses for a declaration - a
208
+ reserved word, a predefined type such as `string`, a strict-mode word such as `public`, a type
209
+ operator such as `keyof` - or a name the generated files declare or name for themselves takes a
210
+ trailing `_` - `delete_`, `string_`, `WireReader_`, `ArrayBuffer_`; and
211
+ a scalar is validated inline wherever it is used, since TypeScript cannot carry its constraints. A
212
+ model named `Record`, `Promise`, `Readonly` or `Exclude` keeps its name - the copy a visibility
213
+ template makes of a `Record<T>` instance, which openapi3 publishes as `Record`, included - and every
214
+ generated file names the library's type as `globalThis.Record<...>`. A type published only as a
215
+ reference to another document, by `@useRef`, is refused as `unsupported-type`: the document states
216
+ no schema for it.
217
+
196
218
  ## Docs
197
219
 
198
220
  - [Guides](docs/guides.md): installing, validating a request, answering with the right body, content
package/dist/src/api.d.ts CHANGED
@@ -242,6 +242,11 @@ export interface EmittedRoute {
242
242
  * hands `pathSchema` the TEXT of that segment (for an exploding `/` expression, of every segment
243
243
  * after it), and `pathSchema` undoes the expansion. A segment holding more than one expression is
244
244
  * `unsupported`: no segment router can split it.
245
+ *
246
+ * **For a `/` expression this is the only statement of the route there is.** openapi3 cannot
247
+ * publish the operator: `/lx{/v*}` is `/lx{v}` in the document, under `simple` style and its own
248
+ * `invalid-style` warning, which joins an exploded list `1,2` where the route joins it `1/2`. The
249
+ * validator undoes the route's, as `@typespec/http-specs` expects - see `docs/reference.md`.
245
250
  */
246
251
  readonly pathSegments: readonly EmittedPathSegment[];
247
252
  /**
@@ -323,6 +328,26 @@ export interface EmittedRoute {
323
328
  readonly requestTextual: boolean;
324
329
  readonly summary: string | undefined;
325
330
  readonly requestSchema: string | undefined;
331
+ /**
332
+ * **The body as a URL-encoded form carries it**, where the route also takes it under another media
333
+ * type: each field read from the text a form holds - `n=5` is `5` where `n` is an `int32` - and a
334
+ * key sent more than once read as the list it stands for. A server validates a form body with this
335
+ * and any other with {@link requestSchema}. `undefined` where no form is declared, or where only a
336
+ * form is, when `requestSchema` reads it itself: validated as JSON, every numeric or boolean field
337
+ * of a form refused every conformant request.
338
+ */
339
+ readonly formRequestSchema?: string;
340
+ /**
341
+ * **The multipart parts whose value is read from text**, each with whether it is JSON alone: every
342
+ * part but a file and raw bytes. A client may send one with a filename all the same - `curl -F
343
+ * 'r=@data.json;type=application/json'` - and a form reader then hands it over as a file, which
344
+ * the part's schema, reading text, refuses. A server reads such a part's text first. Its media type
345
+ * says what the part is, not the filename. `undefined` where the body is not multipart.
346
+ */
347
+ readonly textParts?: readonly {
348
+ readonly name: string;
349
+ readonly json: boolean;
350
+ }[];
326
351
  /**
327
352
  * The parameters, split by WHERE they arrive - see `parameterSchemasOf`.
328
353
  *
@@ -502,6 +527,12 @@ export interface RouteSchemaNames {
502
527
  */
503
528
  readonly cookie?: string | undefined;
504
529
  readonly body: string | undefined;
530
+ /**
531
+ * The validator of the body as a URL-encoded form carries it, where it differs from `body`'s - see
532
+ * {@link EmittedRoute.formRequestSchema}. Absent where a form, if one is declared, is validated by
533
+ * `body`.
534
+ */
535
+ readonly formBody?: string;
505
536
  /**
506
537
  * The identifier each response's body is declared under, parallel to `EmittedRoute.responses` and
507
538
  * in the same order. `schema` is `undefined` exactly where that response carries no body.