typespec-http-zod 0.19.0 → 0.20.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/dist/src/api.d.ts +16 -0
- package/dist/src/api.js +38 -8
- package/package.json +1 -1
package/dist/src/api.d.ts
CHANGED
|
@@ -222,6 +222,22 @@ export interface EmittedRoute {
|
|
|
222
222
|
* {@link rawBodyProperty}, whose case is the same statement about a different body.
|
|
223
223
|
*/
|
|
224
224
|
readonly bodyProperty: string | undefined;
|
|
225
|
+
/**
|
|
226
|
+
* Whether the document publishes `requestBody.required: false`, so a request carrying NO body at
|
|
227
|
+
* all is one the contract permits.
|
|
228
|
+
*
|
|
229
|
+
* **A body that may be absent cannot be flattened into the input, which is why this is published
|
|
230
|
+
* rather than kept internal.** Merged, there is no way to say "these properties are here only
|
|
231
|
+
* sometimes" without making every one of them optional, which would be a different and weaker
|
|
232
|
+
* claim about the body that IS sent. So an optional body is named, exactly as an indexed one is,
|
|
233
|
+
* and a wrapping emitter spells the property optional from this.
|
|
234
|
+
*
|
|
235
|
+
* Measured before it existed: a bodyless `POST` naming `content-type: application/json` answered
|
|
236
|
+
* **400 `Malformed JSON in request body`** as `text/plain`, produced before the app's `invalid`
|
|
237
|
+
* hook and so outside its error envelope entirely - a service refusing a request its own contract
|
|
238
|
+
* permits, in a shape that contract forbids.
|
|
239
|
+
*/
|
|
240
|
+
readonly optionalBody: boolean;
|
|
225
241
|
/** Declared failures, each with the schema for its OWN body, in OpenAPI's precedence order. */
|
|
226
242
|
readonly errorArms: readonly {
|
|
227
243
|
readonly status: StatusKey;
|
package/dist/src/api.js
CHANGED
|
@@ -1054,7 +1054,12 @@ export function collectRoutes(program, registry, service) {
|
|
|
1054
1054
|
* resolved model's own indexer rather than from the emitted schema text, which would be a
|
|
1055
1055
|
* decision made by pattern-matching generated output.
|
|
1056
1056
|
*/
|
|
1057
|
-
|
|
1057
|
+
/**
|
|
1058
|
+
* **An OPTIONAL body is named for the same reason an indexed one is**: the merge cannot
|
|
1059
|
+
* express "absent". See {@link EmittedRoute.optionalBody}.
|
|
1060
|
+
*/
|
|
1061
|
+
const optionalBody = bodyParameter?.property?.optional === true;
|
|
1062
|
+
const bodyProperty = requestType?.kind === "Model" && (requestType.indexer !== undefined || optionalBody)
|
|
1058
1063
|
? (bodyParameter?.property?.name ?? "body")
|
|
1059
1064
|
: undefined;
|
|
1060
1065
|
routes.push({
|
|
@@ -1135,6 +1140,7 @@ export function collectRoutes(program, registry, service) {
|
|
|
1135
1140
|
: registry.expressionFor(responseType)),
|
|
1136
1141
|
rawBodyProperty,
|
|
1137
1142
|
bodyProperty,
|
|
1143
|
+
optionalBody,
|
|
1138
1144
|
// Responses are read at Visibility.Read, exactly as the success body above is. Resolving
|
|
1139
1145
|
// them under the ambient request visibility declared six components under the wrong
|
|
1140
1146
|
// suffix - measured: type/model/visibility gained six divergences.
|
|
@@ -1780,7 +1786,29 @@ type Identical<A, B> = (<T>() => T extends A ? 1 : 2) extends <T>() => T extends
|
|
|
1780
1786
|
*
|
|
1781
1787
|
* Deep, because openness recurs: a nested open model puts one at every level, which is why a single
|
|
1782
1788
|
* spread never repaired the shape it was supposed to repair.
|
|
1789
|
+
*
|
|
1790
|
+
* **An index signature arrives two ways and only one of them is openness.** A model spreading
|
|
1791
|
+
* \`...Record<unknown>\` gains one because its validator is loose - a fact about the MODEL, which the
|
|
1792
|
+
* contract type does not state, so it is stripped. A property declared \`Record<unknown>\` gains one
|
|
1793
|
+
* because that IS its type, stated identically in both artefacts, and stripping it destroys the
|
|
1794
|
+
* property: \`Declared<Record<string, unknown>>\` became \`{}\`, and any spec with a dictionary
|
|
1795
|
+
* property emitted an assertion that does not compile.
|
|
1796
|
+
*
|
|
1797
|
+
* The two are told apart the same way \`types.ts\` already tells them apart: **a string indexer means
|
|
1798
|
+
* "dictionary" only when there are no declared properties beside it.** So the index signature is
|
|
1799
|
+
* dropped from a shape that has other keys, and kept - with its value type still mapped - from one
|
|
1800
|
+
* that does not.
|
|
1783
1801
|
*/
|
|
1802
|
+
type DeclaredKeyOf<T> = keyof {
|
|
1803
|
+
[K in keyof T as string extends K
|
|
1804
|
+
? never
|
|
1805
|
+
: number extends K
|
|
1806
|
+
? never
|
|
1807
|
+
: symbol extends K
|
|
1808
|
+
? never
|
|
1809
|
+
: K]: 0;
|
|
1810
|
+
};
|
|
1811
|
+
|
|
1784
1812
|
type Declared<T> = T extends (...args: never[]) => unknown
|
|
1785
1813
|
? T
|
|
1786
1814
|
: T extends readonly (infer Element)[]
|
|
@@ -1788,15 +1816,17 @@ type Declared<T> = T extends (...args: never[]) => unknown
|
|
|
1788
1816
|
? Declared<Element>[]
|
|
1789
1817
|
: readonly Declared<Element>[]
|
|
1790
1818
|
: T extends object
|
|
1791
|
-
?
|
|
1792
|
-
|
|
1793
|
-
|
|
1794
|
-
|
|
1819
|
+
? [DeclaredKeyOf<T>] extends [never]
|
|
1820
|
+
? { [K in keyof T]: Declared<T[K]> }
|
|
1821
|
+
: {
|
|
1822
|
+
[K in keyof T as string extends K
|
|
1795
1823
|
? never
|
|
1796
|
-
:
|
|
1824
|
+
: number extends K
|
|
1797
1825
|
? never
|
|
1798
|
-
:
|
|
1799
|
-
|
|
1826
|
+
: symbol extends K
|
|
1827
|
+
? never
|
|
1828
|
+
: K]: Declared<T[K]>;
|
|
1829
|
+
}
|
|
1800
1830
|
: T;
|
|
1801
1831
|
|
|
1802
1832
|
/**
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "typespec-http-zod",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.20.0",
|
|
4
4
|
"description": "TypeSpec emitter and library: turn an HTTP service definition into Zod validators and framework-free contract types that agree, keyword for keyword, with the OpenAPI document @typespec/openapi3 publishes from the same source.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"codegen",
|