{"_id":"@austinkelleher/next-rest-framework","_rev":"1-cf6971378c53d08a75ee8d868beb26e9","name":"@austinkelleher/next-rest-framework","dist-tags":{"latest":"5.2.1"},"versions":{"5.2.0":{"name":"@austinkelleher/next-rest-framework","version":"5.2.0","description":"Next REST Framework - Type-safe, self-documenting APIs for Next.js","keywords":["nextjs","rest","api","next-rest-framework"],"homepage":"https://next-rest-framework.vercel.app","bugs":{"url":"https://github.com/blomqma/next-rest-framework/issues","email":"blomqma@omg.lol"},"license":"ISC","author":{"name":"Markus Blomqvist","email":"blomqma@omg.lol"},"main":"dist/index.js","module":"dist/index.mjs","types":"dist/index.d.ts","repository":{"type":"git","url":"git+https://github.com/blomqma/next-rest-framework.git","directory":"packages/next-rest-framework"},"scripts":{"lint":"tsc","test":"jest","test:watch":"jest --watch","build":"tsup --dts"},"bin":{"next-rest-framework":"dist/cli/index.js"},"dependencies":{"chalk":"4.1.2","commander":"10.0.1","esbuild":"0.19.11","lodash":"4.17.21","prettier":"3.0.2","fast-glob":"3.3.2","zod-to-json-schema":"3.21.4","qs":"6.11.2"},"devDependencies":{"@types/jest":"29.5.4","@types/lodash":"4.14.197","@types/qs":"6.9.11","jest":"29.6.4","node-mocks-http":"1.13.0","openapi-types":"12.1.3","ts-jest":"29.1.1","ts-node":"10.9.1","tsup":"8.0.1","typescript":"*","next":"*","zod":"*"},"_id":"@austinkelleher/next-rest-framework@5.2.0","gitHead":"bc9053f3b9e3a5b37d1c6072ba0f34206293d68b","_nodeVersion":"20.9.0","_npmVersion":"10.1.0","dist":{"integrity":"sha512-VYPnVI7ZO+pEBj5Tn9Z3tOmnBk+UxN4xmXd17os7MV3M7VNR/dhyWQVg6k6R1qWYhki0w6MFmrR4/3kppMZfPQ==","shasum":"074aa45c522ba0d447f9fb4b08598a90ef22d5dc","tarball":"https://registry.npmjs.org/@austinkelleher/next-rest-framework/-/next-rest-framework-5.2.0.tgz","fileCount":33,"unpackedSize":493269,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQC5K8UM9J1Wn+gFtdM6vbSxnqK8/aaokZM7dqY+nQ2yfgIhAKZG+x16VF0lGhSFn7bMpns/lSRcQ1nLv645uQ88ioL1"}]},"_npmUser":{"name":"austinkelleher","email":"austinlkelleher@gmail.com"},"directories":{},"maintainers":[{"name":"austinkelleher","email":"austinlkelleher@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/next-rest-framework_5.2.0_1713032077171_0.2882155393076422"},"_hasShrinkwrap":false},"5.2.1":{"name":"@austinkelleher/next-rest-framework","version":"5.2.1","description":"Next REST Framework - Type-safe, self-documenting APIs for Next.js","keywords":["nextjs","rest","api","next-rest-framework"],"homepage":"https://next-rest-framework.vercel.app","bugs":{"url":"https://github.com/blomqma/next-rest-framework/issues","email":"blomqma@omg.lol"},"license":"ISC","author":{"name":"Markus Blomqvist","email":"blomqma@omg.lol"},"main":"dist/index.js","module":"dist/index.mjs","types":"dist/index.d.ts","repository":{"type":"git","url":"git+https://github.com/blomqma/next-rest-framework.git","directory":"packages/next-rest-framework"},"scripts":{"lint":"tsc","test":"jest","test:watch":"jest --watch","build":"tsup --dts"},"bin":{"next-rest-framework":"dist/cli/index.js"},"dependencies":{"chalk":"4.1.2","commander":"10.0.1","esbuild":"0.19.11","lodash":"4.17.21","prettier":"3.0.2","fast-glob":"3.3.2","zod-to-json-schema":"3.21.4","qs":"6.11.2"},"devDependencies":{"@types/jest":"29.5.4","@types/lodash":"4.14.197","@types/qs":"6.9.11","jest":"29.6.4","node-mocks-http":"1.13.0","openapi-types":"12.1.3","ts-jest":"29.1.1","ts-node":"10.9.1","tsup":"8.0.1","typescript":"*","next":"*","zod":"*"},"_id":"@austinkelleher/next-rest-framework@5.2.1","gitHead":"be6771587a75f2e68a47319cc2181e7279bdf2d4","_nodeVersion":"20.9.0","_npmVersion":"10.1.0","dist":{"integrity":"sha512-yzT/sHB9hB5kpJcFop3tj7XULLrdt7RDzHO6IBeEn/oTLVvpIPdmJttkrjUgTFSFehjCB4Ek3HrtTOT7UWmz2Q==","shasum":"66d55100a1456c2a0e4dfe96b410c4ac25edd8f8","tarball":"https://registry.npmjs.org/@austinkelleher/next-rest-framework/-/next-rest-framework-5.2.1.tgz","fileCount":38,"unpackedSize":514861,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDKs6VWy3PfuUMtIOq3ZTkieoW+7C3QiozFiiGGXpS4YgIgTQqHyr50bKDO0i00AFwtEIR9vs7u0UowWjLNlMksFFs="}]},"_npmUser":{"name":"austinkelleher","email":"austinlkelleher@gmail.com"},"directories":{},"maintainers":[{"name":"austinkelleher","email":"austinlkelleher@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/next-rest-framework_5.2.1_1713032810740_0.47589661364019276"},"_hasShrinkwrap":false}},"time":{"created":"2024-04-13T18:14:37.038Z","5.2.0":"2024-04-13T18:14:37.435Z","modified":"2024-04-13T18:26:51.108Z","5.2.1":"2024-04-13T18:26:50.896Z"},"maintainers":[{"name":"austinkelleher","email":"austinlkelleher@gmail.com"}],"description":"Next REST Framework - Type-safe, self-documenting APIs for Next.js","homepage":"https://next-rest-framework.vercel.app","keywords":["nextjs","rest","api","next-rest-framework"],"repository":{"type":"git","url":"git+https://github.com/blomqma/next-rest-framework.git","directory":"packages/next-rest-framework"},"author":{"name":"Markus Blomqvist","email":"blomqma@omg.lol"},"bugs":{"url":"https://github.com/blomqma/next-rest-framework/issues","email":"blomqma@omg.lol"},"license":"ISC","readme":"<p align=\"center\">\n  <br/>\n  <img width=\"250px\" src=\"https://raw.githubusercontent.com/blomqma/next-rest-framework/d02224b38d07ede85257b22ed50159a947681f99/packages/next-rest-framework/logo.svg\" />\n  <h2 align=\"center\">Next REST Framework</h3>\n  <p align=\"center\">Type-safe, self-documenting APIs for Next.js</p>\n  <br/>\n  <p align=\"center\">\n    <a href=\"https://github.com/blomqma/next-rest-framework/actions?query=branch%3Amain\">\n      <img src=\"https://github.com/blomqma/next-rest-framework/actions/workflows/ci.yml/badge.svg?event=push&branch=main\" alt=\"CI status\" />\n    </a>\n    <a href=\"https://codecov.io/gh/blomqma/next-rest-framework\" >\n      <img src=\"https://codecov.io/gh/blomqma/next-rest-framework/branch/main/graph/badge.svg?token=IUG5ZCVGPV\"/>\n    </a>\n    <a href=\"https://github.com/blomqma/next-rest-framework/stargazers\">\n      <img src=\"https://img.shields.io/github/stars/blomqma/next-rest-framework\" alt=\"Github Stars\" />\n    </a>\n    <a href=\"https://opensource.org/licenses/ISC\" rel=\"nofollow\">\n      <img src=\"https://img.shields.io/badge/License-ISC-blue.svg\" alt=\"License\">\n    </a>\n    <img src=\"https://img.shields.io/badge/Contributor%20Covenant-2.1-4baaaa.svg\" alt=\"Contributor Covenant 2.1\" />\n  </p>\n</p>\n\n## Table of contents\n\n- [Table of contents](#table-of-contents)\n- [Overview](#overview)\n- [Features](#features)\n  - [Lightweight, type-safe, easy to use](#lightweight-type-safe-easy-to-use)\n- [Requirements](#requirements)\n- [Installation](#installation)\n- [Getting started](#getting-started)\n  - [Create docs endpoint](#create-docs-endpoint)\n    - [App router docs route:](#app-router-docs-route)\n    - [Pages router docs API route:](#pages-router-docs-api-route)\n  - [Create endpoint](#create-endpoint)\n    - [REST endpoints](#rest-endpoints)\n      - [App router route:](#app-router-route)\n      - [Pages router API route:](#pages-router-api-route)\n    - [RPC endpoints](#rpc-endpoints)\n      - [App router RPC route:](#app-router-rpc-route)\n      - [Pages router RPC route:](#pages-router-rpc-route)\n  - [Client](#client)\n    - [REST client](#rest-client)\n    - [RPC client](#rpc-client)\n- [API reference](#api-reference)\n  - [Docs handler options](#docs-handler-options)\n  - [Docs config](#docs-config)\n  - [REST](#rest)\n    - [Route handler options](#route-handler-options)\n    - [Route operations](#route-operations)\n      - [Route operation input](#route-operation-input)\n      - [Route operation outputs](#route-operation-outputs)\n      - [Route operation middleware](#route-operation-middleware)\n      - [Route operation handler](#route-operation-handler)\n  - [RPC](#rpc)\n    - [RPC route handler options](#rpc-route-handler-options)\n    - [RPC operations](#rpc-operations)\n      - [RPC operation input](#rpc-operation-input)\n      - [RPC operation outputs](#rpc-operation-outputs)\n      - [RPC operation middleware](#rpc-operation-middleware)\n      - [RPC operation handler](#rpc-operation-handler)\n- [CLI](#cli)\n- [Changelog](#changelog)\n- [Contributing](#contributing)\n- [License](#license)\n\n## [Overview](#overview)\n\nNext REST Framework is an open-source, opinionated, lightweight, easy-to-use set of tools to build type-safe, self-documenting APIs with [Next.js](http://nextjs.org/). Building OpenAPI specification-compliant APIs can be cumbersome and slow but Next REST Framework makes this easy with auto-generated OpenAPI documents and docs using TypeScript and object schemas.\n\n- [Live demo](https://next-rest-framework-demo.vercel.app)\n- [Docs](https://next-rest-framework.vercel.app)\n\nThis is a monorepo containing the following packages / projects:\n\n1. The primary `next-rest-framework` package\n2. An example application for live demo and local development\n\n## [Features](#features)\n\n### Lightweight, type-safe, easy to use\n\n- Designed to work with TypeScript so that your requests and responses are strongly typed.\n- Supports API endpoints using both RESTful and RPC principles.\n- Object-schema validation with [Zod](https://github.com/colinhacks/zod). The object schemas are automatically converted to JSON schema format for the auto-generated OpenAPI specification.\n- Auto-generated and extensible `openapi.json` spec file from your business logic.\n- Auto-generated [Redoc](https://github.com/Redocly/redoc) and/or [SwaggerUI](https://swagger.io/tools/swagger-ui/) documentation frontend.\n- Works with Next.js [Middleware](https://nextjs.org/docs/app/building-your-application/routing/middleware) and other server-side libraries, like [NextAuth.js](#https://github.com/nextauthjs/next-auth).\n- Supports both Next.js [app router](https://nextjs.org/docs/app/building-your-application/routing#the-app-router) and [pages router](https://nextjs.org/docs/pages/building-your-application/routing), even at the same time.\n- Supports [Edge runtime](https://nextjs.org/docs/app/building-your-application/rendering/edge-and-nodejs-runtimes).\n- Fully customizable and compatible with any existing Next.js project.\n\n## Requirements\n\nIn order to use Next REST Framework you need to have a Next.js project with the following dependencies installed:\n\n- [Next.js](https://github.com/vercel/next.js) >= v12\n- [Zod](https://github.com/colinhacks/zod) >= v3\n- [TypeScript](https://www.typescriptlang.org/) >= v3\n\n## [Installation](#installation)\n\n```sh\nnpm install next-rest-framework\n```\n\n## [Getting started](#getting-started)\n\n### [Create docs endpoint](#create-docs-endpoint)\n\nTo get access to the auto-generated documentation, initialize the docs endpoint somewhere in your codebase. You can also skip this step if you don't want to expose a public API documentation.\n\n#### [App router docs route](#app-router-docs-route):\n\n```typescript\n// src/app/api/route.ts\n\nimport { docsRoute } from 'next-rest-framework';\n\n// export const runtime = 'edge'; // Edge runtime is supported.\n\nexport const { GET } = docsRoute();\n```\n\n#### [Pages router docs API route](#pages-router-docs-api-route):\n\n```typescript\n// src/pages/api.ts\n\nimport { docsApiRoute } from 'next-rest-framework';\n\nexport default docsApiRoute();\n```\n\nThis is enough to get you started. Now you can access the API documentation in your browser. Running `npx next-rest-framework generate` in the project root will generate the `openapi.json` OpenAPI specification file, located in the `public` folder. You can create multiple docs endpoints if needed and specify which config to use for the [CLI](#cli). See the full configuration options of this endpoint in the [Docs handler options](#docs-handler-options) section.\n\n### [Create endpoint](#create-endpoint)\n\n#### [REST endpoints](#rest-endpoints)\n\n##### [App router route](#app-router-route):\n\n```typescript\n// src/app/api/todos/route.ts\n\nimport { TypedNextResponse, route, routeOperation } from 'next-rest-framework';\nimport { z } from 'zod';\n\nconst TODOS = [\n  {\n    id: 1,\n    name: 'TODO 1',\n    completed: false\n  }\n];\n\n// export const runtime = 'edge'; // Edge runtime is supported.\n\n// Example app router route handler with GET/POST handlers.\nexport const { GET, POST } = route({\n  getTodos: routeOperation({\n    method: 'GET',\n    // Optional OpenAPI operation documentation.\n    openApiOperation: {\n      tags: ['example-api', 'todos', 'app-router']\n    }\n  })\n    // Output schema for strictly-typed responses and OpenAPI documentation.\n    .outputs([\n      {\n        status: 200,\n        contentType: 'application/json',\n        schema: z.array(\n          z.object({\n            id: z.number(),\n            name: z.string(),\n            completed: z.boolean()\n          })\n        )\n      }\n    ])\n    .handler(() => {\n      // Type-checked response.\n      return TypedNextResponse.json(TODOS, {\n        status: 200\n      });\n    }),\n\n  createTodo: routeOperation({\n    method: 'POST',\n    // Optional OpenAPI operation documentation.\n    openApiOperation: {\n      tags: ['example-api', 'todos', 'app-router']\n    }\n  })\n    // Input schema for strictly-typed request, request validation and OpenAPI documentation.\n    .input({\n      contentType: 'application/json',\n      body: z.object({\n        name: z.string()\n      })\n    })\n    // Output schema for strictly-typed responses and OpenAPI documentation.\n    .outputs([\n      {\n        status: 201,\n        contentType: 'application/json',\n        schema: z.string()\n      },\n      {\n        status: 401,\n        contentType: 'application/json',\n        schema: z.string()\n      }\n    ])\n    .middleware(\n      // Optional middleware logic executed before request validation.\n      (req) => {\n        if (!req.headers.get('authorization')) {\n          // Type-checked response.\n          return TypedNextResponse.json('Unauthorized', {\n            status: 401\n          });\n        }\n      }\n    )\n    .handler(async (req) => {\n      const { name } = await req.json(); // Strictly-typed request.\n\n      // Type-checked response.\n      return TypedNextResponse.json(`New TODO created: ${name}`, {\n        status: 201\n      });\n    })\n});\n```\n\nThe `TypedNextResponse` ensures that the response status codes and content-type headers are type-checked. You can still use the regular `NextResponse` if you prefer to have less type-safety.\n\nWhen using the default `nodejs` runtime with app router routes (`docsRoute` or `route`), you may encounter the [Dynamic server usage](https://nextjs.org/docs/messages/dynamic-server-error) Next.js error when running `next build`. In that case you should force the route to be dynamically rendered with the [dynamic](https://nextjs.org/docs/app/api-reference/file-conventions/route-segment-config#dynamic) option:\n\n```typescript\nexport const dynamic = 'force-dynamic';\n```\n\n##### [Pages router API route](#pages-router-api-route):\n\n```typescript\n// src/pages/api/todos.ts\n\nimport { apiRoute, apiRouteOperation } from 'next-rest-framework';\nimport { z } from 'zod';\n\nconst TODOS = [\n  {\n    id: 1,\n    name: 'TODO 1',\n    completed: false\n  }\n];\n\n// Example pages router API route with GET/POST handlers.\nexport default apiRoute({\n  getTodos: apiRouteOperation({\n    method: 'GET',\n    // Optional OpenAPI operation documentation.\n    openApiOperation: {\n      tags: ['example-api', 'todos', 'pages-router']\n    }\n  })\n    // Output schema for strictly-typed responses and OpenAPI documentation.\n    .outputs([\n      {\n        status: 200,\n        contentType: 'application/json',\n        schema: z.array(\n          z.object({\n            id: z.number(),\n            name: z.string(),\n            completed: z.boolean()\n          })\n        )\n      }\n    ])\n    .handler((_req, res) => {\n      // Type-checked response.\n      res.status(200).json(TODOS);\n    }),\n\n  createTodo: apiRouteOperation({\n    method: 'POST',\n    // Optional OpenAPI operation documentation.\n    openApiOperation: {\n      tags: ['example-api', 'todos', 'pages-router']\n    }\n  })\n    // Input schema for strictly-typed request, request validation and OpenAPI documentation.\n    .input({\n      contentType: 'application/json',\n      body: z.object({\n        name: z.string()\n      })\n    })\n    // Output schema for strictly-typed responses and OpenAPI documentation.\n    .outputs([\n      {\n        status: 201,\n        contentType: 'application/json',\n        schema: z.string()\n      },\n      {\n        status: 401,\n        contentType: 'application/json',\n        schema: z.string()\n      }\n    ])\n    // Optional middleware logic executed before request validation.\n    .middleware((req, res) => {\n      if (!req.headers.authorization) {\n        res.status(401).json('Unauthorized'); // Type-checked response.\n      }\n    })\n    .handler((req, res) => {\n      const { name } = req.body; // Strictly-typed request.\n      res.status(201).json(`New TODO created: ${name}`); // Type-checked response.\n    })\n});\n```\n\nAfter running `next-rest-framework generate`, all of above type-safe endpoints will be auto-generated to your OpenAPI spec and exposed in the documentation:\n\n![Next REST Framework docs](./docs/static/img/docs-screenshot.jpg)\n\n#### [RPC endpoints](#rpc-endpoints)\n\n##### [App router RPC route](#app-router-rpc-route):\n\nA recommended way is to write your RPC operation in a separate server-side module where they can be consumed both by the RPC endpoints and directly as server-side functions (server actions):\n\n```typescript\n// src/app/actions.ts\n\n'use server';\n\nimport { rpcOperation } from 'next-rest-framework';\nimport { z } from 'zod';\n\nconst TODOS = [\n  {\n    id: 1,\n    name: 'TODO 1',\n    completed: false\n  }\n];\n\nconst todoSchema = z.object({\n  id: z.number(),\n  name: z.string(),\n  completed: z.boolean()\n});\n\nexport const getTodos = rpcOperation({\n  tags: ['RPC']\n})\n  .outputs([\n    {\n      schema: z.array(todoSchema)\n    }\n  ])\n  .handler(() => {\n    return TODOS; // Type-checked output.\n  });\n\nexport const getTodoById = rpcOperation({\n  tags: ['RPC']\n})\n  .input(z.string())\n  .outputs([\n    {\n      schema: z.object({\n        error: z.string()\n      })\n    },\n    {\n      schema: todoSchema\n    }\n  ])\n  .handler((id) => {\n    const todo = TODOS.find((t) => t.id === Number(id));\n\n    if (!todo) {\n      return { error: 'TODO not found.' }; // Type-checked output.\n    }\n\n    return todo; // Type-checked output.\n  });\n\nexport const createTodo = rpcOperation({\n  tags: ['RPC']\n})\n  .input(\n    z.object({\n      name: z.string()\n    })\n  )\n  .outputs([{ schema: todoSchema }])\n  .handler(\n    async ({\n      name // Strictly-typed input.\n    }) => {\n      // Create todo.\n      const todo = { id: 2, name, completed: false };\n      return todo; // Type-checked output.\n    }\n  );\n\nexport const deleteTodo = rpcOperation({\n  tags: ['RPC']\n})\n  .input(z.string())\n  .outputs([\n    { schema: z.object({ error: z.string() }) },\n    { schema: z.object({ message: z.string() }) }\n  ])\n  .handler((id) => {\n    // Delete todo.\n    const todo = TODOS.find((t) => t.id === Number(id));\n\n    if (!todo) {\n      return {\n        error: 'TODO not found.' // Type-checked output.\n      };\n    }\n\n    return { message: 'TODO deleted.' }; // Type-checked output.\n  });\n```\n\nThe file path to and RPC route must end with `/[operationId]/route.ts`. Import the RPC operations in to your RPC route handler:\n\n```typescript\n// src/app/api/rpc/[operationId]/route.ts\n\nimport { createTodo, deleteTodo, getTodoById, getTodos } from 'src/app/actions';\nimport { rpcRoute } from 'next-rest-framework';\n\n// export const runtime = 'edge'; // Edge runtime is supported.\n\nexport const { POST } = rpcRoute({\n  getTodos,\n  getTodoById,\n  createTodo,\n  deleteTodo\n});\n\nexport type RpcClient = typeof POST.client;\n```\n\nConsume the RPC operations directly in your server-side components:\n\n```typescript\n'use server';\n\nimport { getTodos, createTodo } from 'src/app/actions';\n\nexport default async function Page() {\n  const todos = await getTodos();\n\n  const createTodo = async (name: string) => {\n    'use server';\n    return createTodo({ name });\n  };\n\n  // ...\n}\n```\n\n##### [Pages router RPC route](#pages-router-rpc-api-route):\n\nThe filename of an RPC API route must be `[operationId].ts`.\n\n```typescript\n// src/pages/api/rpc/[operationId].ts\n\nimport { rpcApiRoute } from 'next-rest-framework';\n\n// Example pages router RPC handler.\nconst handler = rpcApiRoute({\n  // ...\n  // Exactly the same as the app router example. You can also inline the RPC operations in this object.\n});\n\nexport default handler;\n\nexport type RpcClient = typeof handler.client;\n```\n\nThe RPC routes will also be included in your OpenAPI spec after running `next-rest-framework generate`.\n\n### [Client](#client)\n\n#### [REST client](#rest-client)\n\nTo achieve end-to-end type-safety, you can use any client implementation that relies on the generated OpenAPI specification, e.g. [openapi-client-axios](https://github.com/openapistack/openapi-client-axios).\n\n#### [RPC client](#rpc-client)\n\nFor client-rendered components you can use the strongly-typed `rpcClient`:\n\n```typescript\n'use client';\n\nimport { rpcClient } from 'next-rest-framework/rpc-client';\nimport { type RpcClient } from 'app/api/rpc/[operationId]';\n\nconst client = rpcClient<RpcClient>({\n  url: 'http://localhost:3000/api/rpc'\n});\n\nexport default function Page() {\n  // ...\n\n  useEffect(() => {\n    client\n      .getTodos()\n      .then(() => {\n        // ...\n      })\n      .catch(console.error);\n  }, []);\n\n  const createTodo = async (name: string) => {\n    const todo = client.createTodo({ name });\n    // ...\n  };\n\n  // ...\n}\n```\n\nThe `rpcClient` calls can also be easily integrated with any data fetching framework, like React Query or RTKQ.\n\n## [API reference](#api-reference)\n\n### [Docs handler options](#docs-handler-options)\n\nThe following options can be passed to the `docsRoute` (app router) and `docsApiRoute` (pages router) functions for customizing Next REST Framework:\n\n| Name              | Description                                                                                                                                                                                                                                                                                                            |\n| ----------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| `deniedPaths`     | Array of paths that are denied by Next REST Framework and not included in the OpenAPI spec. Supports wildcards using asterisk `*` and double asterisk `**` for recursive matching. Example: `['/api/disallowed-path', '/api/disallowed-path-2/*', '/api/disallowed-path-3/**']` Defaults to no paths being disallowed. |\n| `allowedPaths`    | Array of paths that are allowed by Next REST Framework and included in the OpenAPI spec. Supports wildcards using asterisk `*` and double asterisk `**` for recursive matching. Example: `['/api/allowed-path', '/api/allowed-path-2/*', '/api/allowed-path-3/**']` Defaults to all paths being allowed.               |\n| `openApiObject`   | An [OpenAPI Object](https://swagger.io/specification/#openapi-object) that can be used to override and extend the auto-generated specification.                                                                                                                                                                        |\n| `openApiJsonPath` | Path that will be used for fetching the OpenAPI spec - defaults to `/openapi.json`. This path also determines the path where this file will be generated inside the `public` folder.                                                                                                                                   |\n| `docsConfig`      | A [Docs config](#docs-config) object for customizing the generated docs.                                                                                                                                                                                                                                               |\n\n### [Docs config](#docs-config)\n\nThe docs config options can be used to customize the generated docs:\n\n| Name          | Description                                                                                                                                  |\n| ------------- | -------------------------------------------------------------------------------------------------------------------------------------------- |\n| `provider`    | Determines whether to render the docs using Redoc (`redoc`) or SwaggerUI `swagger-ui`. Defaults to `redoc`.                                  |\n| `title`       | Custom title, used for the visible title and HTML title.                                                                                     |\n| `description` | Custom description, used for the visible description and HTML meta description.                                                              |\n| `faviconUrl`  | Custom HTML meta favicon URL.                                                                                                                |\n| `logoUrl`     | A URL for a custom logo.                                                                                                                     |\n| `ogConfig`    | [Basic customization options](https://ogp.me/#metadata) for OG meta tags. Requires the following fields: `title`, `type`, `url`, `imageUrl`. |\n\n### REST\n\n#### [Route handler options](#route-handler-options)\n\nThe following options can be passed to the `routeHandler` (app router) and `apiRouteHandler` (pages router) functions to create new API endpoints:\n\n| Name                                                       | Description                                                                                                                                                 | Required |\n| ---------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------- | -------- |\n| `GET \\| PUT \\| POST \\| DELETE \\| OPTIONS \\| HEAD \\| PATCH` | A [Method handler](#method-handlers) object.                                                                                                                | `true`   |\n| `openApiPath`                                              | An OpenAPI [Path Item Object](https://swagger.io/specification/#path-item-object) that can be used to override and extend the auto-generated specification. | `false`  |\n\n#### [Route operations](#route-operations)\n\nThe route operation functions `routeOperation` (app router) and `apiRouteOperation` (pages router) allow you to define your API handlers for your endpoints. These functions accept an OpenAPI [Operation object](https://swagger.io/specification/#operation-object) as a parameter, that can be used to override the auto-generated specification. Calling this function allows you to chain your API handler logic with the following functions:\n\n| Name         | Description                                                                                                                                                                                                                                                          |\n| ------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| `input`      | A [Route operation input](#route-operation-input) function for defining the validation and documentation of the request.                                                                                                                                             |\n| `outputs`    | An [Route operation outputs](#route-operation-outputs) function for defining the validation and documentation of the response.                                                                                                                                       |\n| `handler`    | A [Route operation-handler](#route-operation-handler) function for defining your business logic.                                                                                                                                                                     |\n| `middleware` | A [Route operation middleware](#route-operation-middleware) function that gets executed before the request input is validated. You may chain up to three middlewares together and share data between the middlewares by taking the input of the previous middleware. |\n\n##### [Route operation input](#route-operation-input)\n\nThe route operation input function is used for type-checking, validation and documentation of the request, taking in an object with the following properties:\n\n| Name          | Description                                                                                                                                                                                            | Required |\n| ------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -------- |\n| `contentType` | The content type header of the request. When the content type is defined, a request with an incorrect content type header will get an error response.                                                  | `false`  |\n| `body`        | A [Zod](https://github.com/colinhacks/zod) schema describing the format of the request body. When the body schema is defined, a request with an invalid request body will get an error response.       | `false`  |\n| `query`       | A [Zod](https://github.com/colinhacks/zod) schema describing the format of the query parameters. When the query schema is defined, a request with invalid query parameters will get an error response. | `false`  |\n\nCalling the route operation input function allows you to chain your API handler logic with the [Route operation outputs](#route-operation-outputs), [Route operation middleware](#route-operation-middleware) and [Route operation handler](#route-operation-handler) functions.\n\n##### [Route operation outputs](#route-operation-outputs)\n\nThe route operation outputs function is used for type-checking and documentation of the response, taking in an array of objects with the following properties:\n\n| Name          | Description                                                                                   | Required |\n| ------------- | --------------------------------------------------------------------------------------------- | -------- |\n| `status`      | A status code that your API can return.                                                       | `true`   |\n| `contentType` | The content type header of the response.                                                      | `true`   |\n| `schema`      | A [Zod](https://github.com/colinhacks/zod) schema describing the format of the response data. |  `true`  |\n\nCalling the route operation outputs function allows you to chain your API handler logic with the [Route operation middleware](#route-operation-middleware) and [Route operation handler](#route-operation-handler) functions.\n\n##### [Route operation middleware](#route-operation-middleware)\n\nThe route operation middleware function is executed before validating the request input. The function takes in the same parameters as the Next.js [router handlers](https://nextjs.org/docs/app/building-your-application/routing/route-handlers) and [API routes](https://nextjs.org/docs/pages/building-your-application/routing/api-routes) handlers. Additionally, as a second parameter this function takes the return value of your last middleware function, defaulting to an empty object. Throwing an error inside a middleware function will stop the execution of the handler and you can also return a custom response like you would do within the [Handler](#handler) function. Calling the route operation middleware function allows you to chain your API handler logic with the [Handler](#handler) function. Alternatively, you may chain up to three middleware functions together:\n\n```typescript\n// ...\nconst handler = route({\n  getTodos: routeOperation()\n    .middleware(() => {\n      return { foo: 'bar' };\n    })\n    .middleware((_req, _ctx, { foo }) => {\n      // if (myCondition) {\n      //   return NextResponse.json({ error: 'My error.' });\n      // }\n\n      return {\n        foo,\n        bar: 'baz'\n      };\n    })\n    .handler((_req, _ctx, { foo, bar }) => {\n      // ...\n    })\n});\n```\n\n##### [Route operation handler](#route-operation-handler)\n\nThe route operation handler function is a strongly-typed function to implement the business logic for your API. The function takes in strongly-typed versions of the same parameters as the Next.js [router handlers](https://nextjs.org/docs/app/building-your-application/routing/route-handlers) and [API routes](https://nextjs.org/docs/pages/building-your-application/routing/api-routes) handlers. Additionally, as a third parameter this function takes the return value of your last middleware function:\n\n```typescript\n// ...\nconst handler = route({\n  getTodos: routeOperation()\n    .middleware(() => {\n      return { foo: \"bar\" };\n    })\n    .handler((_req, _ctx, { foo }) => {\n      // ...\n    });\n});\n```\n\n### RPC\n\n#### [RPC route handler options](#rpc-route-handler-options)\n\nThe `rpcRouteHandler` (app router) and `rpcApiRouteHandler` (pages router) functions allow you to define your API handlers for your RPC endpoints. These functions accept an OpenAPI [Operation object](https://swagger.io/specification/#operation-object) as a parameter, that can be used to override the auto-generated specification.\n\n#### [RPC operations](#rpc-operations)\n\nThe `rpcOperation` function allows you to define your API handlers for your RPC endpoint. Calling this function allows you to chain your API handler logic with the following functions.\n\n| Name         | Description                                                                                                                                                                                                                                                         |\n| ------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| `input`      | An [RPC operation input](#rpc-operation-input) function for defining the validation and documentation of the operation.                                                                                                                                             |\n| `outputs`    | An [RPC operation outputs](#rpc-operation-outputs) function for defining the validation and documentation of the response.                                                                                                                                          |\n| `handler`    | An [RPC operation handler](#rpc-operation-handler) function for defining your business logic.                                                                                                                                                                       |\n| `middleware` | An [RPC operation middleware](#rpc-operation-middleware) function that gets executed before the operation input is validated. You may chain up to three middlewares together and share data between the middlewares by taking the input of the previous middleware. |\n\n##### [RPC operation input](#rpc-operation-input)\n\nThe RPC operation input function is used for type-checking, validation and documentation of the RPC call. It takes in a A [Zod](https://github.com/colinhacks/zod) schema as a parameter that describes the format of the operation input. When the input schema is defined, an RPC call with invalid input will get an error response.\n\nCalling the RPC input function allows you to chain your API handler logic with the [RPC operation outputs](#rpc-operation-outputs), [RPC middleware](#rpc-operation-middleware) and [RPC handler](#rpc-operation-handler) functions.\n\n##### [RPC operation outputs](#rpc-operation-outputs)\n\nThe RPC operation outputs function is used for type-checking and documentation of the response, taking in an array of objects with the following properties:\n\n| Name     | Description                                                                                   | Required |\n| -------- | --------------------------------------------------------------------------------------------- | -------- |\n| `schema` | A [Zod](https://github.com/colinhacks/zod) schema describing the format of the response data. |  `true`  |\n| `name`   | An optional name used in the generated OpenAPI spec, e.g. `GetTodosErrorResponse`.            | `false`  |\n\nCalling the RPC operation outputs function allows you to chain your API handler logic with the [RPC operation middleware](#rpc-operation-middleware) and [RPC operation handler](#rpc-operation-handler) functions.\n\n##### [RPC operation middleware](#rpc-operation-middleware)\n\nThe RPC operation middleware function is executed before validating RPC operation input. The function takes in strongly typed parameters typed by the [RPC operation input](#rpc-operation-input) function. Additionally, as a second parameter this function takes the return value of your last middleware function, defaulting to an empty object. Throwing an error inside a middleware function will stop the execution of the handler. Calling the RPC operation middleware function allows you to chain your RPC API handler logic with the [RPC operation handler](#rpc-operation-handler) function. Alternatively, you may chain up to three middleware functions together:\n\n```typescript\n// ...\nconst handler = rpcRoute({\n  getTodos: rpcOperation()\n    .middleware(() => {\n      return { foo: 'bar' };\n    })\n    .middleware((_input, { foo }) => {\n      // if (myCondition) {\n      //   throw Error('My error.')\n      // }\n\n      return {\n        foo,\n        bar: 'baz'\n      };\n    })\n    .handler((_input, { foo, bar }) => {\n      // ...\n    })\n});\n```\n\n##### [RPC operation handler](#rpc-operation-handler)\n\nThe RPC operation handler function is a strongly-typed function to implement the business logic for your API. The function takes in strongly typed parameters typed by the [RPC operation input](#rpc-operation-input) function. Additionally, as a second parameter this function takes the return value of your last middleware function:\n\n```typescript\n// ...\nconst handler = rpcApiRoute({\n  getTodos: rpcOperation()\n    .middleware(() => {\n      return { foo: \"bar\" };\n    })\n    .handler((_input, { foo }) => {\n      // ...\n    });\n});\n```\n\n## [CLI](#cli)\n\nThe Next REST Framework CLI supports generating and validating the `openapi.json` file:\n\n- `npx next-rest-framework generate` to generate the `openapi.json` file.\n- `npx next-rest-framework validate` to validate that the `openapi.json` file is up-to-date.\n\nThe `next-rest-framework validate` command is useful to have as part of the static checks in your CI/CD pipeline. Both commands support the following options:\n\n| Name                    | Description                                                                                                                                                                                    |\n| ----------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| `--configPath <string>` | In case you have multiple docs handlers with different configurations, you can specify which configuration you want to use by providing the path to the API. Example: `/api/my-configuration`. |\n\nA good practice is to set these in your `package.json` as both commands are needed:\n\n```json\n\"scripts\": {\n  \"generate\": \"next-rest-framework generate\",\n  \"validate\": \"next-rest-framework validate\",\n}\n```\n\n## [Changelog](#changelog)\n\nSee the changelog in [CHANGELOG.md](https://github.com/blomqma/next-rest-framework/blob/main/CHANGELOG.md)\n\n## [Contributing](#contributing)\n\nAll contributions are welcome!\n\n## [License](#license)\n\nISC, see full license in [LICENSE](https://github.com/blomqma/next-rest-framework/blob/main/LICENCE).\n","readmeFilename":"README.md"}