nitro-openapi-schemas 2.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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Oumar Barry
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,184 @@
1
+ # nitro-openapi-schemas
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)
5
+ [![license](https://img.shields.io/npm/l/nitro-openapi-schemas?color=yellow)](https://github.com/oumarbarry/nitro-openapi-schemas/blob/main/LICENSE)
6
+
7
+ Schema-driven OpenAPI for [Nitro](https://nitro.build). The Zod, Valibot or
8
+ ArkType schema that validates a route at runtime also documents it: every
9
+ handler with `validate` schemas or `meta.openAPI` ends up in `/_openapi.json`,
10
+ with a Scalar UI at `/_scalar`. Nothing is declared twice and nothing is
11
+ extracted from source at build time.
12
+
13
+ ```
14
+ Zod / Valibot / ArkType schema
15
+ → defineValidatedHandler validates the request
16
+ → /_openapi.json OpenAPI 3.1, generated from the same schemas
17
+ → openapi.json written after `nitro build`, ready for SDK codegen
18
+ ```
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.
23
+ - Zod 4.2+, ArkType 2.1.28+, and Valibot through `@valibot/to-json-schema`
24
+ 1.5+, via [Standard JSON Schema](https://github.com/standard-schema/standard-schema/pull/134).
25
+ Bring the one you use; none is installed for you.
26
+ - Named schemas become `components/schemas` entries, emitted once and
27
+ referenced by `$ref` wherever they appear.
28
+
29
+ ## Install
30
+
31
+ ```sh
32
+ bun add nitro-openapi-schemas@nitro-v2 # or npm, pnpm
33
+ ```
34
+
35
+ ## Usage
36
+
37
+ Register the module and, optionally, the `info` block of the spec:
38
+
39
+ ```ts
40
+ // nitro.config.ts
41
+ import { defineNitroConfig } from "nitropack/config";
42
+ import openAPISchemas from "nitro-openapi-schemas";
43
+
44
+ export default defineNitroConfig({
45
+ modules: [openAPISchemas],
46
+ openAPISchemas: {
47
+ info: { title: "Payments API", version: "1.0.0" },
48
+ // route: "/_openapi.json", // default
49
+ // scalar: true, // default, Scalar UI at /_scalar
50
+ },
51
+ });
52
+ ```
53
+
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:
71
+
72
+ ```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";
76
+ import { createPaymentSchema, paymentSchema } from "../../shared/schema.ts";
77
+
78
+ export default defineValidatedHandler({
79
+ validate: { body: createPaymentSchema },
80
+ meta: {
81
+ openAPI: {
82
+ tags: ["payments"],
83
+ summary: "Create a payment",
84
+ responses: { 200: { description: "Payment created", schema: paymentSchema } },
85
+ },
86
+ },
87
+ handler: async (event) => {
88
+ const body = await readBody(event); // already validated
89
+ // ...
90
+ },
91
+ });
92
+ ```
93
+
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.
99
+
100
+ ### Naming components
101
+
102
+ A schema with an id is hoisted into `components/schemas` under that id and
103
+ referenced by `$ref` everywhere it appears, nested schemas included. Each
104
+ library has its own way to set it:
105
+
106
+ | Library | Named schema |
107
+ | ------- | ---------------------------------------------------------- |
108
+ | Zod | `z.object({ ... }).meta({ id: "Payment" })` |
109
+ | ArkType | `type({ ... }).configure({ id: "Payment" })` |
110
+ | Valibot | `v.pipe(v.object({ ... }), v.metadata({ id: "Payment" }))` |
111
+
112
+ Anonymous schemas are inlined. A query or header schema is flattened into one
113
+ parameter per property.
114
+
115
+ ### The spec as a build artifact
116
+
117
+ The spec is generated at runtime from the handlers in the bundle, so getting it
118
+ as a file means booting the built server once and saving the response.
119
+ [examples/nitro/scripts/emit-openapi.mjs](examples/nitro/scripts/emit-openapi.mjs)
120
+ does exactly that, and `openapi-typescript` turns the result into a typed
121
+ client:
122
+
123
+ ```sh
124
+ bun run openapi # nitro build, boot the output, write openapi.json
125
+ bun run sdk # openapi-typescript openapi.json -o sdk.d.ts
126
+ ```
127
+
128
+ ## Nitro v3
129
+
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.
133
+
134
+ ## How it works
135
+
136
+ 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.
144
+
145
+ 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
+
148
+ ## Limitations
149
+
150
+ - JSON request bodies only. Cookie parameters and other content types are not
151
+ described.
152
+ - One HTTP method per route file, as in Nitro's file routing.
153
+ - Header parameter names are emitted as written in the schema, without case
154
+ normalization.
155
+ - The document is cached after the first request. In dev, restart the server
156
+ after changing a schema in a route that was already loaded.
157
+ - Response schemas go in `meta.openAPI.responses[status].schema`, since h3's
158
+ `validate` has no `response` field.
159
+
160
+ ## Background
161
+
162
+ This module is the implementation behind
163
+ [nitrojs/nitro#4402](https://github.com/nitrojs/nitro/discussions/4402), a
164
+ proposal to generate OpenAPI from Standard Schema validators inside Nitro
165
+ itself (see also [#2974](https://github.com/nitrojs/nitro/issues/2974) and
166
+ [#3542](https://github.com/nitrojs/nitro/issues/3542)). Until that lands, it
167
+ works as a standalone module.
168
+
169
+ ## Development
170
+
171
+ ```sh
172
+ 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
178
+ ```
179
+
180
+ See [CONTRIBUTING.md](CONTRIBUTING.md).
181
+
182
+ ## License
183
+
184
+ MIT
package/dist/h3.d.mts ADDED
@@ -0,0 +1,36 @@
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 ADDED
@@ -0,0 +1,27 @@
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 };
@@ -0,0 +1,32 @@
1
+ import { NitroModule } from "nitropack/types";
2
+ interface NitroOpenAPISchemasOptions {
3
+ /** Route serving the generated spec. Default: `/_openapi.json` */
4
+ route?: string;
5
+ /** Mount Nitro's Scalar UI at `/_scalar` on top of the spec. Default: true */
6
+ scalar?: boolean;
7
+ /** OpenAPI info object (title, version, description). */
8
+ info?: {
9
+ title?: string;
10
+ version?: string;
11
+ description?: string;
12
+ };
13
+ }
14
+ declare module "nitropack/types" {
15
+ interface NitroConfig {
16
+ openAPISchemas?: NitroOpenAPISchemasOptions;
17
+ }
18
+ interface NitroOptions {
19
+ openAPISchemas?: NitroOpenAPISchemasOptions;
20
+ }
21
+ }
22
+ /**
23
+ * Nitro v2 / Nuxt 4 line.
24
+ *
25
+ * Emits a virtual module that imports every scanned route handler *directly*
26
+ * (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.
30
+ */
31
+ declare const nitroOpenAPISchemas: NitroModule;
32
+ export { NitroOpenAPISchemasOptions, nitroOpenAPISchemas as default };
package/dist/index.mjs ADDED
@@ -0,0 +1,30 @@
1
+ import { fileURLToPath } from "node:url";
2
+ import { join } from "node:path";
3
+ import { runtimeDir } from "nitropack/runtime/meta";
4
+ const nitroOpenAPISchemas = {
5
+ name: "nitro-openapi-schemas",
6
+ setup(nitro) {
7
+ const options = nitro.options.openAPISchemas || {};
8
+ const specRoute = options.route || "/_openapi.json";
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");
11
+ const files = [...new Set(entries.map((h) => h.handler))];
12
+ return [
13
+ ...files.map((file, i) => `import h${i} from ${JSON.stringify(file)};`),
14
+ `export const config = ${JSON.stringify({ info: options.info })};`,
15
+ "export const routes = [",
16
+ ...entries.map((h) => ` { route: ${JSON.stringify(h.route)}, method: ${JSON.stringify((h.method || "get").toLowerCase())}, handler: h${files.indexOf(h.handler)} },`),
17
+ "];"
18
+ ].join("\n");
19
+ };
20
+ nitro.options.handlers.push({
21
+ route: specRoute,
22
+ handler: fileURLToPath(new URL("runtime/route", import.meta.url))
23
+ });
24
+ if (options.scalar !== false) nitro.options.handlers.push({
25
+ route: "/_scalar",
26
+ handler: join(runtimeDir, "internal/routes/scalar")
27
+ });
28
+ }
29
+ };
30
+ export { nitroOpenAPISchemas as default };
@@ -0,0 +1,190 @@
1
+ export async function toOpenAPIDocument(entries, opts = {}) {
2
+ const registry = new SchemaRegistry();
3
+ const paths = {};
4
+ for (const entry of entries) {
5
+ const { route, parameters } = normalizeRoute(entry.route);
6
+ const { validate, meta } = entry.handler;
7
+ const { responses: metaResponses, ...openAPI } = meta?.openAPI || {};
8
+ if (validate?.query) {
9
+ parameters.push(...await schemaToParameters(registry, validate.query, "query"));
10
+ }
11
+ if (validate?.headers) {
12
+ parameters.push(...await schemaToParameters(registry, validate.headers, "header"));
13
+ }
14
+ const operation = {
15
+ ...parameters.length > 0 ? { parameters } : {},
16
+ responses: { 200: { description: "OK" } },
17
+ ...openAPI
18
+ };
19
+ if (validate?.body) {
20
+ operation.requestBody = {
21
+ required: true,
22
+ content: { "application/json": { schema: await registry.toJsonSchema(validate.body, "input") } }
23
+ };
24
+ }
25
+ if (metaResponses) {
26
+ operation.responses = {};
27
+ for (const [status, res] of Object.entries(metaResponses)) {
28
+ const { schema, ...rest } = res;
29
+ operation.responses[status] = isStandardSchema(schema) ? {
30
+ ...rest,
31
+ content: { "application/json": { schema: await registry.toJsonSchema(schema, "output") } }
32
+ } : res;
33
+ }
34
+ }
35
+ (paths[route] ??= {})[entry.method] = operation;
36
+ }
37
+ return {
38
+ openapi: "3.1.0",
39
+ info: {
40
+ title: "Nitro Server Routes",
41
+ version: "1.0.0",
42
+ ...opts.info
43
+ },
44
+ servers: opts.servers,
45
+ paths,
46
+ ...registry.hasComponents() ? { components: { schemas: registry.components } } : {}
47
+ };
48
+ }
49
+
50
+ function isStandardSchema(value) {
51
+ return !!value && typeof value === "object" && "~standard" in value;
52
+ }
53
+
54
+ class SchemaRegistry {
55
+ components = {};
56
+
57
+ #seen = {
58
+ input: new Map(),
59
+ output: new Map()
60
+ };
61
+ hasComponents() {
62
+ return Object.keys(this.components).length > 0;
63
+ }
64
+ async toJsonSchema(schema, io) {
65
+ const seen = this.#seen[io];
66
+ const cached = seen.get(schema);
67
+ if (cached) return cached;
68
+ const { json, name } = await convert(schema, io);
69
+
70
+
71
+ if (json.$defs) {
72
+ for (const [defName, defSchema] of Object.entries(json.$defs)) {
73
+ this.components[defName] ??= rewriteDefsRefs(defSchema);
74
+ }
75
+ delete json.$defs;
76
+ rewriteDefsRefs(json);
77
+ }
78
+ let result = json;
79
+ if (name) {
80
+
81
+
82
+ const finalName = io === "input" && this.components[name] ? `${name}Input` : name;
83
+ this.components[finalName] = json;
84
+ result = { $ref: `#/components/schemas/${finalName}` };
85
+ }
86
+ seen.set(schema, result);
87
+ return result;
88
+ }
89
+ }
90
+
91
+
92
+
93
+ function schemaId(schema, vendor) {
94
+ switch (vendor) {
95
+ case "zod": {
96
+ return schema.meta?.()?.id;
97
+ }
98
+ case "arktype": {
99
+ return schema.meta?.id;
100
+ }
101
+ default: {
102
+ return undefined;
103
+ }
104
+ }
105
+ }
106
+ function rewriteDefsRefs(node) {
107
+ if (Array.isArray(node)) {
108
+ for (const item of node) rewriteDefsRefs(item);
109
+ } else if (node && typeof node === "object") {
110
+ if (typeof node.$ref === "string" && node.$ref.startsWith("#/$defs/")) {
111
+ node.$ref = node.$ref.replace("#/$defs/", "#/components/schemas/");
112
+ }
113
+ for (const value of Object.values(node)) rewriteDefsRefs(value);
114
+ }
115
+ return node;
116
+ }
117
+ async function convert(schema, io) {
118
+ const std = schema["~standard"];
119
+
120
+
121
+
122
+ if (std.jsonSchema) {
123
+ const json = std.jsonSchema[io]({ target: "draft-2020-12" });
124
+ delete json.$schema;
125
+ return {
126
+ json,
127
+ name: schemaId(schema, std.vendor)
128
+ };
129
+ }
130
+
131
+
132
+
133
+ const vendor = std.vendor;
134
+ switch (vendor) {
135
+ case "valibot": {
136
+
137
+
138
+ // @valibot/to-json-schema@1.5+ ships toStandardJsonSchema(), a
139
+
140
+
141
+
142
+
143
+ const { toStandardJsonSchema } = await import("@valibot/" + "to-json-schema");
144
+ const name = schema.pipe?.find((a) => a.kind === "metadata")?.metadata?.id;
145
+ const { json } = await convert(toStandardJsonSchema(schema), io);
146
+ return {
147
+ json,
148
+ name
149
+ };
150
+ }
151
+ case "arktype": {
152
+ return { json: schema.toJsonSchema() };
153
+ }
154
+ default: {
155
+ throw new Error(`[openapi] No JSON Schema converter for schema vendor "${vendor}". Supported: zod, valibot, arktype.`);
156
+ }
157
+ }
158
+ }
159
+ async function schemaToParameters(registry, schema, location) {
160
+ const json = await registry.toJsonSchema(schema, "input");
161
+ const resolved = json.$ref ? registry.components[json.$ref.split("/").pop()] : json;
162
+ if (resolved?.type !== "object" || !resolved.properties) return [];
163
+ return Object.entries(resolved.properties).map(([name, propSchema]) => ({
164
+ name,
165
+ in: location,
166
+ required: resolved.required?.includes(name) ?? false,
167
+ schema: propSchema
168
+ }));
169
+ }
170
+
171
+ function normalizeRoute(_route) {
172
+ const parameters = [];
173
+ let anonymousCtr = 0;
174
+ const route = _route.replace(/:(\w+)/g, (_, name) => `{${name}}`).replace(/\/(\*)\//g, () => `/{param${++anonymousCtr}}/`).replace(/\*\*{/, "{").replace(/\/(\*\*)$/g, () => `/{*param${++anonymousCtr}}`);
175
+ for (const match of route.matchAll(/{(\*?\w+)}/g)) {
176
+ const name = match[1];
177
+ if (!parameters.some((p) => p.name === name)) {
178
+ parameters.push({
179
+ name,
180
+ in: "path",
181
+ required: true,
182
+ schema: { type: "string" }
183
+ });
184
+ }
185
+ }
186
+ return {
187
+ route,
188
+ parameters
189
+ };
190
+ }
@@ -0,0 +1,13 @@
1
+ import { defineEventHandler, getRequestURL } from "h3";
2
+ // @ts-expect-error virtual module provided by ../index.ts
3
+ import { routes, config } from "#nitro-openapi-schemas";
4
+ import { toOpenAPIDocument } from "./generator.mjs";
5
+ let cached;
6
+ export default defineEventHandler((event) => {
7
+
8
+ const origin = getRequestURL(event).origin;
9
+ return cached ??= toOpenAPIDocument(routes, {
10
+ info: config.info,
11
+ servers: [{ url: origin }]
12
+ });
13
+ });
package/package.json ADDED
@@ -0,0 +1,87 @@
1
+ {
2
+ "name": "nitro-openapi-schemas",
3
+ "version": "2.0.0",
4
+ "description": "Schema-driven OpenAPI for Nitro: the Zod, Valibot or ArkType schema that validates a route also documents it",
5
+ "keywords": [
6
+ "api",
7
+ "arktype",
8
+ "h3",
9
+ "json-schema",
10
+ "nitro",
11
+ "nuxt",
12
+ "openapi",
13
+ "standard-schema",
14
+ "swagger",
15
+ "valibot",
16
+ "zod"
17
+ ],
18
+ "homepage": "https://github.com/oumarbarry/nitro-openapi-schemas#readme",
19
+ "bugs": "https://github.com/oumarbarry/nitro-openapi-schemas/issues",
20
+ "license": "MIT",
21
+ "author": "Oumar Barry",
22
+ "repository": {
23
+ "type": "git",
24
+ "url": "git+https://github.com/oumarbarry/nitro-openapi-schemas.git"
25
+ },
26
+ "workspaces": [
27
+ "examples/*"
28
+ ],
29
+ "files": [
30
+ "dist"
31
+ ],
32
+ "type": "module",
33
+ "sideEffects": false,
34
+ "exports": {
35
+ ".": {
36
+ "types": "./dist/index.d.mts",
37
+ "default": "./dist/index.mjs"
38
+ },
39
+ "./h3": {
40
+ "types": "./dist/h3.d.mts",
41
+ "default": "./dist/h3.mjs"
42
+ }
43
+ },
44
+ "publishConfig": {
45
+ "access": "public"
46
+ },
47
+ "scripts": {
48
+ "dev": "bun run --cwd examples/nitro dev",
49
+ "openapi": "bun run --cwd examples/nitro openapi",
50
+ "openapi:nuxt4": "bun run --cwd examples/nuxt4 openapi",
51
+ "sdk": "bun run --cwd examples/nitro sdk",
52
+ "build": "obuild",
53
+ "prepare": "obuild",
54
+ "lint": "oxlint",
55
+ "lint:fix": "oxlint --fix",
56
+ "format": "oxfmt",
57
+ "format:check": "oxfmt --check",
58
+ "check": "oxlint && oxfmt --check",
59
+ "fix": "oxlint --fix && oxfmt"
60
+ },
61
+ "devDependencies": {
62
+ "@types/node": "^26.1.0",
63
+ "jiti": "^2.7.0",
64
+ "obuild": "^0.4.37",
65
+ "oxfmt": "^0.57.0",
66
+ "oxlint": "^1.72.0",
67
+ "typescript": "^6.0.3"
68
+ },
69
+ "peerDependencies": {
70
+ "@valibot/to-json-schema": "^1.5.0",
71
+ "arktype": "^2.1.28",
72
+ "h3": "^1.15.0",
73
+ "nitropack": "^2.12.0",
74
+ "zod": "^4.2.0"
75
+ },
76
+ "peerDependenciesMeta": {
77
+ "zod": {
78
+ "optional": true
79
+ },
80
+ "arktype": {
81
+ "optional": true
82
+ },
83
+ "@valibot/to-json-schema": {
84
+ "optional": true
85
+ }
86
+ }
87
+ }