nitro-openapi-schemas 2.0.0 → 3.0.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
@@ -1,7 +1,7 @@
1
1
  # nitro-openapi-schemas
2
2
 
3
- [![CI](https://github.com/oumarbarry/nitro-openapi-schemas/actions/workflows/ci.yml/badge.svg?branch=nitro-v2)](https://github.com/oumarbarry/nitro-openapi-schemas/actions/workflows/ci.yml)
4
- [![npm version](https://img.shields.io/npm/v/nitro-openapi-schemas/nitro-v2?color=yellow)](https://npmjs.com/package/nitro-openapi-schemas/v/nitro-v2)
3
+ [![CI](https://github.com/oumarbarry/nitro-openapi-schemas/actions/workflows/ci.yml/badge.svg)](https://github.com/oumarbarry/nitro-openapi-schemas/actions/workflows/ci.yml)
4
+ [![npm version](https://img.shields.io/npm/v/nitro-openapi-schemas?color=yellow)](https://npmjs.com/package/nitro-openapi-schemas)
5
5
  [![license](https://img.shields.io/npm/l/nitro-openapi-schemas?color=yellow)](https://github.com/oumarbarry/nitro-openapi-schemas/blob/main/LICENSE)
6
6
 
7
7
  Schema-driven OpenAPI for [Nitro](https://nitro.build). The Zod, Valibot or
@@ -17,9 +17,8 @@ Zod / Valibot / ArkType schema
17
17
  → openapi.json written after `nitro build`, ready for SDK codegen
18
18
  ```
19
19
 
20
- - This is the Nitro v2 and Nuxt 4 line: `nitropack` 2.x and h3 1.x, published
21
- as 2.x under the `nitro-v2` dist-tag from the branch of the same name. Nitro v3 users
22
- want the [`main` branch](https://github.com/oumarbarry/nitro-openapi-schemas/tree/main) and the `latest` tag.
20
+ - Nitro v3 and h3 v2, published as 3.x under the `latest` tag. Nitro v2 and
21
+ Nuxt 4 have their own line, see [below](#nitro-v2-and-nuxt-4).
23
22
  - Zod 4.2+, ArkType 2.1.28+, and Valibot through `@valibot/to-json-schema`
24
23
  1.5+, via [Standard JSON Schema](https://github.com/standard-schema/standard-schema/pull/134).
25
24
  Bring the one you use; none is installed for you.
@@ -29,7 +28,7 @@ Zod / Valibot / ArkType schema
29
28
  ## Install
30
29
 
31
30
  ```sh
32
- bun add nitro-openapi-schemas@nitro-v2 # or npm, pnpm
31
+ bun add nitro-openapi-schemas # or npm, pnpm
33
32
  ```
34
33
 
35
34
  ## Usage
@@ -38,10 +37,10 @@ Register the module and, optionally, the `info` block of the spec:
38
37
 
39
38
  ```ts
40
39
  // nitro.config.ts
41
- import { defineNitroConfig } from "nitropack/config";
40
+ import { defineConfig } from "nitro";
42
41
  import openAPISchemas from "nitro-openapi-schemas";
43
42
 
44
- export default defineNitroConfig({
43
+ export default defineConfig({
45
44
  modules: [openAPISchemas],
46
45
  openAPISchemas: {
47
46
  info: { title: "Payments API", version: "1.0.0" },
@@ -51,28 +50,14 @@ export default defineNitroConfig({
51
50
  });
52
51
  ```
53
52
 
54
- ```ts
55
- // nuxt.config.ts (Nuxt 4): same options, nested under `nitro`
56
- import openAPISchemas from "nitro-openapi-schemas";
57
-
58
- export default defineNuxtConfig({
59
- nitro: {
60
- modules: [openAPISchemas],
61
- openAPISchemas: { info: { title: "Payments API", version: "1.0.0" } },
62
- },
63
- });
64
- ```
65
-
66
- Then write routes with `defineValidatedHandler` from `nitro-openapi-schemas/h3`.
67
- It validates `query`, `headers` and `body` through each schema's own
68
- `~standard.validate` (400 with the issues in `data` on failure, body skipped
69
- for GET and HEAD) and documents them. `meta.openAPI` is merged into the
70
- operation, and a `schema` on a response is converted too:
53
+ Then write routes with `defineValidatedHandler` from `nitro/h3`. The `body`,
54
+ `query` and `headers` schemas are validated by h3 and documented by this
55
+ module. `meta.openAPI` is merged into the operation, and a `schema` on a
56
+ response is converted too:
71
57
 
72
58
  ```ts
73
- // routes/api/payments/index.post.ts (Nuxt: server/api/payments/index.post.ts)
74
- import { readBody } from "h3";
75
- import { defineValidatedHandler } from "nitro-openapi-schemas/h3";
59
+ // routes/api/payments/index.post.ts
60
+ import { defineValidatedHandler } from "nitro/h3";
76
61
  import { createPaymentSchema, paymentSchema } from "../../shared/schema.ts";
77
62
 
78
63
  export default defineValidatedHandler({
@@ -85,17 +70,15 @@ export default defineValidatedHandler({
85
70
  },
86
71
  },
87
72
  handler: async (event) => {
88
- const body = await readBody(event); // already validated
73
+ const body = await event.req.json(); // already validated
89
74
  // ...
90
75
  },
91
76
  });
92
77
  ```
93
78
 
94
- `readBody` returns the parsed body as it was sent, not the schema's output, so
95
- defaults and coercions declared in the schema are not applied to it. Start the
96
- server and open `/_scalar`, or fetch `/_openapi.json`. Path parameters are
97
- documented from the route pattern, so `defineValidatedHandler` with only `meta`
98
- is enough for a route without validation.
79
+ Start the server and open `/_scalar`, or fetch `/_openapi.json`. Path
80
+ parameters are documented from the route pattern, so a plain `defineHandler`
81
+ with `meta` is enough for a route without validation.
99
82
 
100
83
  ### Naming components
101
84
 
@@ -125,25 +108,25 @@ bun run openapi # nitro build, boot the output, write openapi.json
125
108
  bun run sdk # openapi-typescript openapi.json -o sdk.d.ts
126
109
  ```
127
110
 
128
- ## Nitro v3
111
+ ## Nitro v2 and Nuxt 4
129
112
 
130
- The `latest` dist-tag targets Nitro v3 and h3 v2, where `defineValidatedHandler`
131
- comes from `nitro/h3` itself. Install with `bun add nitro-openapi-schemas` and
132
- read the [`main` branch](https://github.com/oumarbarry/nitro-openapi-schemas) README.
113
+ The `v2` dist-tag targets `nitropack` 2.x and h3 1.x, which is what Nuxt 4
114
+ ships. h3 1.x has no `defineValidatedHandler`, so that line provides one at
115
+ `nitro-openapi-schemas/h3`. Install with `bun add nitro-openapi-schemas@v2`
116
+ and read the [`nitro-v2` branch](https://github.com/oumarbarry/nitro-openapi-schemas/tree/nitro-v2) README.
133
117
 
134
118
  ## How it works
135
119
 
136
120
  The module emits a virtual module that imports every scanned route handler
137
- directly, bypassing Nitro's lazy wrappers. `defineValidatedHandler` from
138
- `nitro-openapi-schemas/h3` assigns the `validate` schemas and `meta` onto the
139
- handler function, the same contract h3 v2 provides natively, so the spec route
140
- can read those live objects, convert each schema through `~standard.jsonSchema`
141
- (or wrap it with `@valibot/to-json-schema` when the library does not expose
142
- that yet), hoist named schemas and Zod's nested `$defs` into
143
- `components/schemas`, and cache the document after the first request.
121
+ directly, bypassing Nitro's lazy wrappers, because h3's `defineValidatedHandler`
122
+ and `defineHandler` assign the definition, `validate` schemas and `meta`
123
+ included, onto the handler function. The spec route reads those live objects,
124
+ converts each schema through `~standard.jsonSchema` (or wraps it with
125
+ `@valibot/to-json-schema` when the library does not expose that yet), hoists
126
+ named schemas and Zod's nested `$defs` into `components/schemas`, and caches
127
+ the document after the first request.
144
128
 
145
129
  The trade-off: routes imported by the spec route are no longer lazy-loaded.
146
- Nuxt's catch-all renderer (`/**`) is left out of the import for that reason.
147
130
 
148
131
  ## Limitations
149
132
 
@@ -170,11 +153,10 @@ works as a standalone module.
170
153
 
171
154
  ```sh
172
155
  bun install && bun install --force # the second install links the built dist/ into the examples
173
- bun run dev # example app at http://localhost:3000/_scalar
174
- bun run check # oxlint + oxfmt
175
- bun run build # obuild, writes dist/
176
- bun run openapi # end-to-end: build examples/nitro and write its openapi.json
177
- bun run openapi:nuxt4 # same for examples/nuxt4
156
+ bun run dev # example app at http://localhost:3000/_scalar
157
+ bun run check # oxlint + oxfmt
158
+ bun run build # obuild, writes dist/
159
+ bun run openapi # end-to-end: build the example and write its openapi.json
178
160
  ```
179
161
 
180
162
  See [CONTRIBUTING.md](CONTRIBUTING.md).
package/dist/index.d.mts CHANGED
@@ -1,4 +1,4 @@
1
- import { NitroModule } from "nitropack/types";
1
+ import { NitroModule } from "nitro/types";
2
2
  interface NitroOpenAPISchemasOptions {
3
3
  /** Route serving the generated spec. Default: `/_openapi.json` */
4
4
  route?: string;
@@ -11,7 +11,7 @@ interface NitroOpenAPISchemasOptions {
11
11
  description?: string;
12
12
  };
13
13
  }
14
- declare module "nitropack/types" {
14
+ declare module "nitro/types" {
15
15
  interface NitroConfig {
16
16
  openAPISchemas?: NitroOpenAPISchemasOptions;
17
17
  }
@@ -20,13 +20,10 @@ declare module "nitropack/types" {
20
20
  }
21
21
  }
22
22
  /**
23
- * Nitro v2 / Nuxt 4 line.
24
- *
25
23
  * Emits a virtual module that imports every scanned route handler *directly*
26
24
  * (bypassing lazy wrappers), so the spec route can read the live `validate`
27
- * schemas and `meta` attached to the handler function at runtime. h3 v1 has
28
- * no defineValidatedHandler, so this package ships its own shim (see ./h3.ts)
29
- * that attaches them.
25
+ * schemas and `meta` that h3's defineValidatedHandler/defineHandler attach to
26
+ * the handler function at runtime.
30
27
  */
31
28
  declare const nitroOpenAPISchemas: NitroModule;
32
29
  export { NitroOpenAPISchemasOptions, nitroOpenAPISchemas as default };
package/dist/index.mjs CHANGED
@@ -1,13 +1,13 @@
1
1
  import { fileURLToPath } from "node:url";
2
2
  import { join } from "node:path";
3
- import { runtimeDir } from "nitropack/runtime/meta";
3
+ import { runtimeDir } from "nitro/meta";
4
4
  const nitroOpenAPISchemas = {
5
5
  name: "nitro-openapi-schemas",
6
6
  setup(nitro) {
7
7
  const options = nitro.options.openAPISchemas || {};
8
8
  const specRoute = options.route || "/_openapi.json";
9
9
  nitro.options.virtual["#nitro-openapi-schemas"] = () => {
10
- const entries = [...nitro.scannedHandlers, ...nitro.options.handlers].filter((h) => h.route && !h.middleware && h.route !== specRoute && !h.route.startsWith("/_") && !h.route.includes("**") && typeof h.handler === "string");
10
+ const entries = Object.values(nitro.routing.routes.routes).flatMap((r) => r.data).filter((h) => h.route && h.route !== specRoute && !h.route.startsWith("/_") && typeof h.handler === "string");
11
11
  const files = [...new Set(entries.map((h) => h.handler))];
12
12
  return [
13
13
  ...files.map((file, i) => `import h${i} from ${JSON.stringify(file)};`),
@@ -1,11 +1,11 @@
1
- import { defineEventHandler, getRequestURL } from "h3";
1
+ import { defineHandler } from "h3";
2
2
  // @ts-expect-error virtual module provided by ../index.ts
3
3
  import { routes, config } from "#nitro-openapi-schemas";
4
4
  import { toOpenAPIDocument } from "./generator.mjs";
5
5
  let cached;
6
- export default defineEventHandler((event) => {
6
+ export default defineHandler((event) => {
7
7
 
8
- const origin = getRequestURL(event).origin;
8
+ const origin = new URL(event.req.url).origin;
9
9
  return cached ??= toOpenAPIDocument(routes, {
10
10
  info: config.info,
11
11
  servers: [{ url: origin }]
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nitro-openapi-schemas",
3
- "version": "2.0.0",
3
+ "version": "3.0.0",
4
4
  "description": "Schema-driven OpenAPI for Nitro: the Zod, Valibot or ArkType schema that validates a route also documents it",
5
5
  "keywords": [
6
6
  "api",
@@ -35,10 +35,6 @@
35
35
  ".": {
36
36
  "types": "./dist/index.d.mts",
37
37
  "default": "./dist/index.mjs"
38
- },
39
- "./h3": {
40
- "types": "./dist/h3.d.mts",
41
- "default": "./dist/h3.mjs"
42
38
  }
43
39
  },
44
40
  "publishConfig": {
@@ -47,7 +43,6 @@
47
43
  "scripts": {
48
44
  "dev": "bun run --cwd examples/nitro dev",
49
45
  "openapi": "bun run --cwd examples/nitro openapi",
50
- "openapi:nuxt4": "bun run --cwd examples/nuxt4 openapi",
51
46
  "sdk": "bun run --cwd examples/nitro sdk",
52
47
  "build": "obuild",
53
48
  "prepare": "obuild",
@@ -69,8 +64,8 @@
69
64
  "peerDependencies": {
70
65
  "@valibot/to-json-schema": "^1.5.0",
71
66
  "arktype": "^2.1.28",
72
- "h3": "^1.15.0",
73
- "nitropack": "^2.12.0",
67
+ "h3": "^2.0.1-rc.22",
68
+ "nitro": "^3.0.260610-beta",
74
69
  "zod": "^4.2.0"
75
70
  },
76
71
  "peerDependenciesMeta": {
package/dist/h3.d.mts DELETED
@@ -1,36 +0,0 @@
1
- import { EventHandler, EventHandlerObject, EventHandlerRequest, EventHandlerResponse } from "h3";
2
- interface StandardSchema {
3
- "~standard": {
4
- vendor: string;
5
- version: number;
6
- validate: (value: unknown) => {
7
- value: unknown;
8
- issues?: undefined;
9
- } | {
10
- issues: readonly unknown[];
11
- } | Promise<{
12
- value: unknown;
13
- issues?: undefined;
14
- } | {
15
- issues: readonly unknown[];
16
- }>;
17
- };
18
- }
19
- interface ValidateSchemas {
20
- body?: StandardSchema;
21
- query?: StandardSchema;
22
- headers?: StandardSchema;
23
- }
24
- interface HandlerMeta {
25
- openAPI?: Record<string, any>;
26
- [key: string]: unknown;
27
- }
28
- type ValidatedHandler<Request extends EventHandlerRequest = EventHandlerRequest, Response = EventHandlerResponse> = EventHandler<Request, Response> & {
29
- validate?: ValidateSchemas;
30
- meta?: HandlerMeta;
31
- };
32
- declare function defineValidatedHandler<Request extends EventHandlerRequest = EventHandlerRequest, Response = EventHandlerResponse>(def: EventHandlerObject<Request, Response> & {
33
- validate?: ValidateSchemas;
34
- meta?: HandlerMeta;
35
- }): ValidatedHandler<Request, Response>;
36
- export { HandlerMeta, ValidateSchemas, ValidatedHandler, defineValidatedHandler };
package/dist/h3.mjs DELETED
@@ -1,27 +0,0 @@
1
- import { createError, defineEventHandler, getQuery, getRequestHeaders, readBody } from "h3";
2
- function defineValidatedHandler(def) {
3
- const { validate, meta } = def;
4
- const handler = defineEventHandler({
5
- ...def,
6
- handler: async (event) => {
7
- if (validate?.query) await validatePart(validate.query, getQuery(event), "query");
8
- if (validate?.headers) await validatePart(validate.headers, getRequestHeaders(event), "headers");
9
- if (validate?.body && event.method !== "GET" && event.method !== "HEAD") await validatePart(validate.body, await readBody(event), "body");
10
- return def.handler(event);
11
- }
12
- });
13
- return Object.assign(handler, {
14
- validate,
15
- meta
16
- });
17
- }
18
- async function validatePart(schema, value, part) {
19
- const result = await schema["~standard"].validate(value);
20
- if (result.issues) throw createError({
21
- status: 400,
22
- statusMessage: "Validation Error",
23
- message: `Invalid ${part}`,
24
- data: result.issues
25
- });
26
- }
27
- export { defineValidatedHandler };