typespec-http-zod 0.12.1 → 0.14.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.js +8 -4
- package/dist/src/zod.js +26 -10
- package/package.json +1 -1
package/dist/src/api.js
CHANGED
|
@@ -1320,13 +1320,17 @@ function responseArmsOf(route, response, alternate) {
|
|
|
1320
1320
|
* empty list, or every `respond` implementation has to tell "none declared" from "none carried".
|
|
1321
1321
|
*/
|
|
1322
1322
|
/**
|
|
1323
|
-
* The media types this status offers.
|
|
1324
|
-
*
|
|
1325
|
-
*
|
|
1323
|
+
* The media types this status offers.
|
|
1324
|
+
*
|
|
1325
|
+
* **Emitted whenever the document names any, including a single one.** It was emitted only for
|
|
1326
|
+
* several, on the reasoning that one type is what a `respond` already assumes - and that reasoning
|
|
1327
|
+
* was wrong, because it assumed the one type is JSON. A `text/plain` arm and a JSON arm were then
|
|
1328
|
+
* indistinguishable to a generic `respond`: the document knew and the runtime did not, so consumers
|
|
1329
|
+
* restated the media type in their own result envelope to get it back.
|
|
1326
1330
|
*/
|
|
1327
1331
|
const mediaTypesFor = (status) => {
|
|
1328
1332
|
const declared = route.responseMediaTypes.find((entry) => entry.status === status)?.contentTypes ?? [];
|
|
1329
|
-
if (declared.length
|
|
1333
|
+
if (declared.length === 0)
|
|
1330
1334
|
return "";
|
|
1331
1335
|
return `, contentTypes: [${declared.map((t) => JSON.stringify(t)).join(", ")}]`;
|
|
1332
1336
|
};
|
package/dist/src/zod.js
CHANGED
|
@@ -337,18 +337,34 @@ const SCALARS = {
|
|
|
337
337
|
decimal128: "z.number()",
|
|
338
338
|
numeric: "z.number()",
|
|
339
339
|
/**
|
|
340
|
-
*
|
|
340
|
+
* **A declared TYPE is a claim about the value, and these check it.**
|
|
341
341
|
*
|
|
342
|
-
*
|
|
343
|
-
*
|
|
344
|
-
*
|
|
342
|
+
* These are not strings with a hint attached: they are scalars the document publishes as
|
|
343
|
+
* `format: date-time`, `format: uri` and so on. Emitting `z.string()` for them discarded a
|
|
344
|
+
* declared type, so a service promising a timestamp accepted `banana` - and a consumer who wanted
|
|
345
|
+
* the check had to rewrite the spec as `string` with a `@pattern`, losing `format: date-time` from
|
|
346
|
+
* the document AND getting a weaker check, since a hand-written pattern accepts `2026-02-31`. A
|
|
347
|
+
* rule that pushes consumers into writing worse specs is the wrong rule.
|
|
348
|
+
*
|
|
349
|
+
* **`@format("...")` on a plain string is a different case and stays unenforced.** Under JSON
|
|
350
|
+
* Schema 2020-12, which OpenAPI 3.1 uses, `format` is an annotation rather than an assertion, so
|
|
351
|
+
* enforcing an author's hint would add a rule the contract does not state, and
|
|
352
|
+
* `@format("account-number")` proves no general rule exists. A type is a claim; an annotation is a
|
|
353
|
+
* hint.
|
|
354
|
+
*
|
|
355
|
+
* **`{ offset: true }` is measured, not decorative.** The previous comment here warned that a
|
|
356
|
+
* stricter check would fail "a legal-but-unexpected instant", and it was right about the risk: a
|
|
357
|
+
* bare `z.iso.datetime()` REJECTS `2026-08-14T12:00:00+01:00`, which is valid RFC 3339 and valid
|
|
358
|
+
* `format: date-time`. With the offset permitted, every legal instant is accepted and only
|
|
359
|
+
* `2026-02-31` and `banana` are refused. `local: true` would go too far, admitting a value with no
|
|
360
|
+
* timezone at all, which RFC 3339 does not allow.
|
|
345
361
|
*/
|
|
346
|
-
utcDateTime: "z.
|
|
347
|
-
offsetDateTime: "z.
|
|
348
|
-
plainDate: "z.
|
|
349
|
-
plainTime: "z.
|
|
350
|
-
duration: "z.
|
|
351
|
-
url: "z.
|
|
362
|
+
utcDateTime: "z.iso.datetime({ offset: true })",
|
|
363
|
+
offsetDateTime: "z.iso.datetime({ offset: true })",
|
|
364
|
+
plainDate: "z.iso.date()",
|
|
365
|
+
plainTime: "z.iso.time()",
|
|
366
|
+
duration: "z.iso.duration()",
|
|
367
|
+
url: "z.url()",
|
|
352
368
|
};
|
|
353
369
|
function scalarToZod(program, scalar) {
|
|
354
370
|
// `scalar unixTimestamp32 is utcDateTime;` with `@encode(int32)` on the SCALAR, not on each use.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "typespec-http-zod",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.14.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",
|