typespec-http-zod 0.8.0 → 0.10.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 +26 -0
- package/dist/src/api.js +17 -5
- package/package.json +1 -1
package/dist/src/api.d.ts
CHANGED
|
@@ -109,6 +109,32 @@ export interface EmittedRoute {
|
|
|
109
109
|
readonly operationId: string;
|
|
110
110
|
readonly verb: string;
|
|
111
111
|
readonly path: string;
|
|
112
|
+
/**
|
|
113
|
+
* The WIRE names of path parameters that use RFC 6570 reserved expansion, and so match across `/`.
|
|
114
|
+
*
|
|
115
|
+
* **`path` alone cannot carry this, and that is not an oversight in the spelling.** A note path is
|
|
116
|
+
* `areas/health.md`, so a vault route has to be `GET /vault/:path{.+}`; `@typespec/http` resolves
|
|
117
|
+
* `@route("/vault/{+path}")` to `path` = `/vault/{path}` with the operator already stripped, and
|
|
118
|
+
* `@typespec/openapi3` publishes the same. **Measured at 3.0.0, 3.1.0 and 3.2.0**: OpenAPI cannot
|
|
119
|
+
* express reserved expansion at any version, so the document says `/vault/{path}` and openapi3
|
|
120
|
+
* raises `path-reserved-expansion` as a warning. The fact exists in the program and reaches no
|
|
121
|
+
* artefact, so a server emitter mounts a route that answers 404 to every request it was written
|
|
122
|
+
* for. This is the one place the IR deliberately carries more than the document - see
|
|
123
|
+
* `docs/reference.md`.
|
|
124
|
+
*
|
|
125
|
+
* **Read from the parameter, never by parsing `path` or `uriTemplate` for `{+`.** Two forms reach
|
|
126
|
+
* `allowReserved`, and only the parameter entry answers for both: the operator in the template
|
|
127
|
+
* (`@route("/vault/{+path}")`), and `@path(#{allowReserved: true})` on a required parameter the
|
|
128
|
+
* template does not already name, which is what `@typespec/http-specs` itself uses and which
|
|
129
|
+
* `@typespec/http` resolves by APPENDING `{+param}` to the template. Deciding this by matching
|
|
130
|
+
* emitted text would also be the defect class that produced six others here.
|
|
131
|
+
*
|
|
132
|
+
* Wire names, so `@path("note-path") notePath` appears as `note-path` - the name a router has to
|
|
133
|
+
* match, and the same one `pathSchema` keys on. Empty when the operation has none, never
|
|
134
|
+
* `undefined`, so a consumer does not branch. Reserved-ness is per PARAMETER: `/repo/{owner}/{+ref}`
|
|
135
|
+
* carries one of each.
|
|
136
|
+
*/
|
|
137
|
+
readonly reservedPathParameters: readonly string[];
|
|
112
138
|
readonly statusCode: number;
|
|
113
139
|
readonly statusCodes: readonly number[];
|
|
114
140
|
/** Media types the success body can be served as - the basis for `Accept` negotiation. */
|
package/dist/src/api.js
CHANGED
|
@@ -892,6 +892,14 @@ export function collectRoutes(program, registry, service) {
|
|
|
892
892
|
* particular router can express the path.
|
|
893
893
|
*/
|
|
894
894
|
path: operation.path,
|
|
895
|
+
/**
|
|
896
|
+
* Asked of the resolved parameter, which is the only place both marker forms agree -
|
|
897
|
+
* see {@link EmittedRoute.reservedPathParameters}. `allowReserved` is a required
|
|
898
|
+
* boolean on every path parameter entry, so this reads a fact rather than an absence.
|
|
899
|
+
*/
|
|
900
|
+
reservedPathParameters: operation.parameters.parameters
|
|
901
|
+
.filter((parameter) => parameter.type === "path" && parameter.allowReserved)
|
|
902
|
+
.map((parameter) => parameter.name),
|
|
895
903
|
statusCode,
|
|
896
904
|
statusCodes,
|
|
897
905
|
responseContentTypes: responseContentTypesOf(operation, statusCode),
|
|
@@ -1050,15 +1058,19 @@ function renderSchemas(registry, externals, routeDeclarations, runtimeModule) {
|
|
|
1050
1058
|
* **Written only when something in the file names it**, like the `ResponseArm` import below and for
|
|
1051
1059
|
* the same reason: an unused import fails the lint a generated file has to pass like any other.
|
|
1052
1060
|
*
|
|
1053
|
-
* `z` is reached through a declaration's source or a route's
|
|
1054
|
-
* operation takes nothing and returns `void`
|
|
1061
|
+
* `z` is reached through a declaration's source or a route arm's schema, and a service whose every
|
|
1062
|
+
* operation takes nothing and returns `void` has neither: its arms are
|
|
1063
|
+
* `{ status: 204, schema: undefined }`, which names nothing.
|
|
1055
1064
|
* `TS6133: 'z' is declared but its value is never read`, from a compile that reported success. Two
|
|
1056
1065
|
* bare `GET`s is where a health check starts, so it is where a new consumer starts.
|
|
1057
1066
|
*
|
|
1058
|
-
*
|
|
1059
|
-
*
|
|
1067
|
+
* **Counting declarations is not sufficient and was the first attempt.** A void-only service HAS
|
|
1068
|
+
* route declarations; they simply do not use Zod. The content decides, and it is TOKENISED on the
|
|
1069
|
+
* language's own identifier rule rather than searched for a substring, so `z` cannot be found
|
|
1070
|
+
* inside `zValidator` or missed beside a bracket. `renderExternalImports` below reads the same
|
|
1071
|
+
* rendered content for the same reason.
|
|
1060
1072
|
*/
|
|
1061
|
-
const usesZod = declarations
|
|
1073
|
+
const usesZod = new Set([...declarations, ...routeDeclarations].join("").match(/[A-Za-z_$][\w$]*/g) ?? []).has("z");
|
|
1062
1074
|
const parts = [GENERATED_BANNER];
|
|
1063
1075
|
if (usesZod)
|
|
1064
1076
|
parts.push('\nimport { z } from "zod";\n');
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "typespec-http-zod",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.10.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",
|