@codexsploitx/schemaapi 1.0.0 → 1.0.2

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.
Files changed (52) hide show
  1. package/LICENSE +21 -0
  2. package/package.json +1 -1
  3. package/readme.md +125 -48
  4. package/docs/adapters/deno.md +0 -51
  5. package/docs/adapters/express.md +0 -67
  6. package/docs/adapters/fastify.md +0 -64
  7. package/docs/adapters/hapi.md +0 -67
  8. package/docs/adapters/koa.md +0 -61
  9. package/docs/adapters/nest.md +0 -66
  10. package/docs/adapters/next.md +0 -66
  11. package/docs/adapters/remix.md +0 -72
  12. package/docs/cli.md +0 -18
  13. package/docs/consepts.md +0 -18
  14. package/docs/getting_started.md +0 -149
  15. package/docs/sdk.md +0 -25
  16. package/docs/validation.md +0 -228
  17. package/docs/versioning.md +0 -28
  18. package/eslint.config.mjs +0 -34
  19. package/rollup.config.js +0 -19
  20. package/src/adapters/deno.ts +0 -139
  21. package/src/adapters/express.ts +0 -134
  22. package/src/adapters/fastify.ts +0 -133
  23. package/src/adapters/hapi.ts +0 -140
  24. package/src/adapters/index.ts +0 -9
  25. package/src/adapters/koa.ts +0 -128
  26. package/src/adapters/nest.ts +0 -122
  27. package/src/adapters/next.ts +0 -175
  28. package/src/adapters/remix.ts +0 -145
  29. package/src/adapters/ws.ts +0 -132
  30. package/src/core/client.ts +0 -104
  31. package/src/core/contract.ts +0 -534
  32. package/src/core/versioning.test.ts +0 -174
  33. package/src/docs.ts +0 -535
  34. package/src/index.ts +0 -5
  35. package/src/playground.test.ts +0 -98
  36. package/src/playground.ts +0 -13
  37. package/src/sdk.ts +0 -17
  38. package/tests/adapters.deno.test.ts +0 -70
  39. package/tests/adapters.express.test.ts +0 -67
  40. package/tests/adapters.fastify.test.ts +0 -63
  41. package/tests/adapters.hapi.test.ts +0 -66
  42. package/tests/adapters.koa.test.ts +0 -58
  43. package/tests/adapters.nest.test.ts +0 -85
  44. package/tests/adapters.next.test.ts +0 -39
  45. package/tests/adapters.remix.test.ts +0 -52
  46. package/tests/adapters.ws.test.ts +0 -91
  47. package/tests/cli.test.ts +0 -156
  48. package/tests/client.test.ts +0 -110
  49. package/tests/contract.handle.test.ts +0 -267
  50. package/tests/docs.test.ts +0 -96
  51. package/tests/sdk.test.ts +0 -34
  52. package/tsconfig.json +0 -15
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 CodexSploitx
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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@codexsploitx/schemaapi",
3
- "version": "1.0.0",
3
+ "version": "1.0.2",
4
4
  "description": "Type-safe API contracts (HTTP/WebSocket) with adapters, client and docs generator.",
5
5
  "main": "dist/schemaapi.cjs.js",
6
6
  "module": "dist/schemaapi.esm.js",
package/readme.md CHANGED
@@ -1,61 +1,70 @@
1
+ <div align="center">
2
+
1
3
  # SchemaApi
2
4
 
3
- > El Zod de las APIs
4
- > No reemplaza tu stack. Lo hace confiable.
5
+ **The Zod of APIs**
6
+ *Type-safe contracts. Runtime validation. Auto-generated docs.*
5
7
 
6
- SchemaApi es una librería de **contratos para APIs**.
7
- No sustituye Express, Fastify, Next.js, Axios ni Fetch.
8
- Se coloca **encima** de ellos como una capa de validación, coherencia y arquitectura.
8
+ [![npm version](https://img.shields.io/npm/v/schemaapi?style=flat-square&color=blue)](https://www.npmjs.com/package/schemaapi)
9
+ [![License](https://img.shields.io/npm/l/schemaapi?style=flat-square&color=green)](LICENSE)
10
+ [![Tests](https://img.shields.io/github/actions/workflow/status/CodexSploitx/SchemaApi/test.yml?label=tests&style=flat-square)](https://github.com/CodexSploitx/SchemaApi/actions)
11
+ [![TypeScript](https://img.shields.io/badge/TypeScript-5.0+-blue?style=flat-square&logo=typescript)](https://www.typescriptlang.org/)
9
12
 
10
- ---
13
+ [Features](#-features) • [Installation](#-installation) • [Usage](#-usage) • [Adapters](#-adapters) • [Documentation](#-documentation)
11
14
 
12
- ## 🧠 Filosofía
15
+ </div>
13
16
 
14
- > “Tu API no es tu código.
15
- > Tu API es el contrato que prometes al mundo.”
17
+ ---
16
18
 
17
- SchemaApi convierte ese contrato en:
18
- - Código tipado
19
- - Validación runtime
20
- - Seguridad (roles y errores tipados)
21
- - Documentación (vía CLI y contrato)
22
- - SDK de cliente básico
23
- - Tests (unitarios y de contrato)
19
+ ## 🚀 Why SchemaApi?
24
20
 
25
- ---
21
+ **Your API is a contract.** But in most codebases, that contract is broken into pieces:
22
+ - Validation logic in controllers.
23
+ - Types in a `types.ts` file.
24
+ - Documentation in a stale Swagger file.
25
+ - Client SDKs handwritten (and buggy).
26
26
 
27
- ## Lo que hace SchemaApi hoy
27
+ **SchemaApi** unifies everything into a **Single Source of Truth**. Define your contract once, and get everything else for free.
28
28
 
29
- - Valida rutas, métodos HTTP y parámetros
30
- - Valida query, body y headers
31
- - Controla roles y autenticación
32
- - Valida responses y errores (incluye status codes definidos en el contrato)
33
- - Expone un contrato único fuente de verdad para docs/SDK/tests
34
- - Ofrece un cliente JS/TS básico vía `createClient`
35
- - Proporciona una CLI mínima (`schemaapi`) para orquestar generación de docs/SDK/tests
36
- - Versionado de API con detección de breaking changes
29
+ > "It doesn't replace your framework. It makes it invincible."
37
30
 
38
31
  ---
39
32
 
40
- ## Lo que NO hace
33
+ ## Features
41
34
 
42
- - No transporta datos (usa Fetch / Axios)
43
- - No reemplaza tu framework (Express / Next / Fastify)
44
- - No maneja DB ni ORM
45
- - No es un servidor
35
+ | Feature | Description |
36
+ | :--- | :--- |
37
+ | **🛡️ End-to-End Type Safety** | Types flow from your server contract directly to your client SDK. No code generation required. |
38
+ | **⚡ Runtime Validation** | Powered by **[Zod](https://zod.dev)**. Automatically validates params, query, body, and headers. |
39
+ | **🔐 Built-in Security** | Define `roles` and `scopes` directly in your contract. RBAC made simple. |
40
+ | **📚 Auto Documentation** | Generate beautiful, interactive HTML documentation that never drifts from code. |
41
+ | **🔌 Framework Agnostic** | Works with Express, Next.js, Fastify, Remix, NestJS, and more. |
42
+ | **📦 Zero-Config SDK** | Export a fully typed client that handles methods, paths, and errors for you. |
46
43
 
47
44
  ---
48
45
 
49
- ## 🌐 Instalación
46
+ ## 📦 Installation
50
47
 
51
48
  ```bash
52
- npm install schemaapi
53
- # o
54
- yarn add schemaapi
49
+ # npm
50
+ npm install schemaapi zod
51
+
52
+ # pnpm
53
+ pnpm add schemaapi zod
55
54
 
55
+ # yarn
56
+ yarn add schemaapi zod
57
+ ```
56
58
 
57
- 🧩 Ejemplo básico
59
+ ---
60
+
61
+ ## 🛠 Usage
62
+
63
+ ### 1️⃣ Define the Contract
58
64
 
65
+ Create a shared file (e.g., `contract.ts`). This is your API's law.
66
+
67
+ ```typescript
59
68
  import { createContract } from "schemaapi";
60
69
  import { z } from "zod";
61
70
 
@@ -63,27 +72,95 @@ export const contract = createContract({
63
72
  "/users/:id": {
64
73
  GET: {
65
74
  params: z.object({ id: z.string().uuid() }),
66
- headers: z.object({ authorization: z.string() }),
67
- roles: ["user", "admin"],
68
75
  response: z.object({
69
76
  id: z.string(),
70
- username: z.string(),
71
- email: z.string().email()
77
+ name: z.string(),
78
+ email: z.string().email(),
72
79
  }),
73
- errors: { 401: "UNAUTHORIZED", 404: "USER_NOT_FOUND" }
74
- }
75
- }
80
+ errors: {
81
+ 404: "USER_NOT_FOUND",
82
+ },
83
+ },
84
+ },
76
85
  });
86
+ ```
77
87
 
88
+ ### 2️⃣ Implement the Server
78
89
 
90
+ Use the `handle` method to implement the logic. SchemaApi ensures you return exactly what the contract promises.
79
91
 
80
- 🛠 Integración con Express
92
+ ```typescript
93
+ import express from "express";
94
+ import { contract } from "./contract";
95
+
96
+ const app = express();
81
97
 
82
98
  app.get(
83
99
  "/users/:id",
84
- contract.handle("GET /users/:id", async (ctx) => {
85
- const user = await db.findUser(ctx.params.id);
86
- return user; // Validación automática
100
+ contract.handle("GET /users/:id", async ({ params }) => {
101
+ // `params.id` is strictly typed as a UUID string
102
+ const user = await db.users.find(params.id);
103
+
104
+ if (!user) {
105
+ throw { status: 404, message: "User not found" };
106
+ }
107
+
108
+ // TypeScript ensures this return value matches the contract
109
+ return user;
87
110
  })
88
111
  );
89
- # SchemaApi
112
+ ```
113
+
114
+ ### 3️⃣ Consume with Client SDK
115
+
116
+ No more manual fetch calls. No more `any`.
117
+
118
+ ```typescript
119
+ import { createClient } from "schemaapi";
120
+ import { contract } from "./shared/contract";
121
+
122
+ const client = createClient(contract, {
123
+ baseUrl: "https://api.example.com"
124
+ });
125
+
126
+ // Full autocomplete & type checking
127
+ const user = await client.users.get({
128
+ id: "550e8400-e29b-41d4-a716-446655440000"
129
+ });
130
+
131
+ console.log(user.email); // ✅ Typed!
132
+ ```
133
+
134
+ ---
135
+
136
+ ## 🔌 Adapters Ecosystem
137
+
138
+ SchemaApi is designed to drop into any stack.
139
+
140
+ | Adapter | Status | Package Support |
141
+ | :--- | :---: | :--- |
142
+ | <img src="https://raw.githubusercontent.com/expressjs/expressjs.com/gh-pages/images/favicon.png" width="20" /> **Express** | ✅ Stable | Native support |
143
+ | <img src="https://assets.vercel.com/image/upload/v1662130559/nextjs/Icon_dark_background.png" width="20" /> **Next.js** | ✅ Stable | API Routes & App Router |
144
+ | <img src="https://raw.githubusercontent.com/fastify/graphics/master/fastify-icon.png" width="20" /> **Fastify** | ✅ Stable | High performance |
145
+ | <img src="https://github.com/remix-run/branding/raw/main/remix-r.png" width="20" /> **Remix** | ✅ Stable | Loaders & Actions |
146
+ | <img src="https://nestjs.com/img/logo-small.svg" width="20" /> **NestJS** | ✅ Stable | Decorators |
147
+ | <img src="https://upload.wikimedia.org/wikipedia/commons/thumb/8/84/Deno.svg/1200px-Deno.svg.png" width="20" /> **Deno** | ✅ Stable | Native HTTP |
148
+ | ⚡ **WebSocket** | 🚧 Beta | Real-time contracts |
149
+
150
+ ---
151
+
152
+ ## 📚 Documentation Generator
153
+
154
+ Stop writing Swagger files manually. Generate a stunning static documentation site with one command.
155
+
156
+ ```bash
157
+ npx schemaapi generate docs --out ./docs
158
+ ```
159
+
160
+ It creates a fully responsive, dark-mode ready HTML dashboard showing all your routes, schemas, and types.
161
+
162
+ ---
163
+
164
+ ## 📄 License
165
+
166
+ MIT © [CodexSploitx](https://github.com/CodexSploitx)
@@ -1,51 +0,0 @@
1
- # Deno Adapter
2
-
3
- Adaptador para usar `SchemaApi` en Deno (usando `Deno.serve`).
4
-
5
- ## Uso
6
-
7
- ```typescript
8
- import { createContract, adapters } from "npm:schemaapi"; // Asumiendo importación desde npm o path relativo
9
-
10
- const contract = createContract({
11
- "/api/data": {
12
- GET: {
13
- // ...
14
- },
15
- },
16
- });
17
-
18
- const handler = adapters.deno.handleContract(contract, {
19
- "GET /api/data": async (ctx) => {
20
- return { data: "Hello form Deno" };
21
- },
22
- });
23
-
24
- Deno.serve(handler);
25
- ```
26
-
27
- ## Estructura recomendada de contratos
28
-
29
- Cuando usas Deno (o entornos similares como Workers, Bun, etc.) es habitual compartir contratos entre varias funciones/lambdas y entre servidor y cliente. Es **muy recomendable** centralizar los contratos en una carpeta o paquete dedicado:
30
-
31
- ```txt
32
- contracts/
33
- ├─ usersContract.ts
34
- ├─ clientsContract.ts
35
- ├─ productsContract.ts
36
- ├─ facturasContract.ts
37
- ├─ ofertasContract.ts
38
- └─ index.ts
39
- ```
40
-
41
- Cada handler puede importar solo el contrato que necesita:
42
-
43
- ```typescript
44
- import { adapters } from "npm:schemaapi";
45
- import { usersContract } from "./contracts/usersContract.ts";
46
- ```
47
-
48
- ## Características
49
-
50
- - Usa la API estándar de Web (`Request`, `Response`).
51
- - Compatible con cualquier entorno que use `(req: Request) => Response`, incluyendo Bun, Cloudflare Workers, etc.
@@ -1,67 +0,0 @@
1
- # Express Adapter
2
-
3
- Este adaptador permite conectar tu contrato definido con `SchemaApi` a una aplicación Express.
4
-
5
- ## Uso
6
-
7
- ```typescript
8
- import express from "express";
9
- import { createContract, adapters } from "schemaapi";
10
- import { z } from "zod";
11
-
12
- const app = express();
13
- app.use(express.json()); // Necesario para parsear body JSON
14
-
15
- const contract = createContract({
16
- "/users/:id": {
17
- GET: {
18
- params: z.object({ id: z.string() }),
19
- response: z.object({ id: z.string(), name: z.string() }),
20
- },
21
- },
22
- });
23
-
24
- adapters.express.handleContract(app, contract, {
25
- "GET /users/:id": async (ctx) => {
26
- // ctx.params, ctx.query, ctx.body, ctx.headers están tipados y validados
27
- return { id: ctx.params.id, name: "John Doe" };
28
- },
29
- });
30
-
31
- app.listen(3000, () => {
32
- console.log("Server running on port 3000");
33
- });
34
- ```
35
-
36
- ## Estructura recomendada de contratos
37
-
38
- En aplicaciones Express pequeñas puedes definir un único contrato grande, pero a medida que crece el número de endpoints se recomienda separar los contratos por dominio en una carpeta dedicada:
39
-
40
- ```txt
41
- contracts/
42
- ├─ usersContract.ts
43
- ├─ clientsContract.ts
44
- ├─ productsContract.ts
45
- ├─ facturasContract.ts
46
- ├─ ofertasContract.ts
47
- └─ index.ts
48
- ```
49
-
50
- Cada archivo define el contrato de un dominio concreto y `contracts/index.ts` reexporta todos. Luego puedes montar cada contrato en su propio router o módulo:
51
-
52
- ```typescript
53
- import { usersContract } from "./contracts";
54
- import { adapters } from "schemaapi";
55
-
56
- adapters.express.handleContract(app, usersContract, {
57
- "GET /users/:id": async (ctx) => {
58
- return { id: ctx.params.id, name: "John Doe" };
59
- },
60
- });
61
- ```
62
-
63
- ## Características
64
-
65
- - Validación automática de `params`, `query`, `body` y `headers` usando el esquema Zod.
66
- - Manejo de errores: Si la validación falla, devuelve automáticamente un error 400.
67
- - Integración nativa con rutas de Express.
@@ -1,64 +0,0 @@
1
- # Fastify Adapter
2
-
3
- Este adaptador conecta `SchemaApi` con Fastify.
4
-
5
- ## Uso
6
-
7
- ```typescript
8
- import Fastify from "fastify";
9
- import { createContract, adapters } from "schemaapi";
10
- import { z } from "zod";
11
-
12
- const fastify = Fastify();
13
-
14
- const contract = createContract({
15
- "/ping": {
16
- GET: {
17
- response: z.object({ pong: z.boolean() }),
18
- },
19
- },
20
- });
21
-
22
- adapters.fastify.handleContract(fastify, contract, {
23
- "GET /ping": async () => {
24
- return { pong: true };
25
- },
26
- });
27
-
28
- fastify.listen({ port: 3000 }, (err) => {
29
- if (err) throw err;
30
- console.log("Server listening on port 3000");
31
- });
32
- ```
33
-
34
- ## Estructura recomendada de contratos
35
-
36
- Con Fastify es habitual organizar la aplicación en plugins por dominio. Encaja muy bien tener también contratos por dominio en una carpeta dedicada:
37
-
38
- ```txt
39
- contracts/
40
- ├─ usersContract.ts
41
- ├─ clientsContract.ts
42
- ├─ productsContract.ts
43
- ├─ facturasContract.ts
44
- ├─ ofertasContract.ts
45
- └─ index.ts
46
- ```
47
-
48
- Cada plugin puede registrar solo el contrato que le corresponde:
49
-
50
- ```typescript
51
- import { usersContract } from "./contracts";
52
- import { adapters } from "schemaapi";
53
-
54
- adapters.fastify.handleContract(fastify, usersContract, {
55
- "GET /users/:id": async (ctx) => {
56
- return { id: ctx.params.id };
57
- },
58
- });
59
- ```
60
-
61
- ## Características
62
-
63
- - Usa `fastify.route` internamente.
64
- - Soporta validación de esquemas (aunque Fastify tiene su propio validador, aquí usamos la validación centralizada de SchemaApi).
@@ -1,67 +0,0 @@
1
- # Hapi Adapter
2
-
3
- Adaptador para el framework Hapi.
4
-
5
- ## Uso
6
-
7
- ```typescript
8
- import Hapi from "@hapi/hapi";
9
- import { createContract, adapters } from "schemaapi";
10
-
11
- const init = async () => {
12
- const server = Hapi.server({
13
- port: 3000,
14
- host: "localhost",
15
- });
16
-
17
- const contract = createContract({
18
- "/hello/:name": {
19
- GET: {
20
- // ...
21
- },
22
- },
23
- });
24
-
25
- adapters.hapi.handleContract(server, contract, {
26
- "GET /hello/:name": async (ctx) => {
27
- return { message: `Hello ${ctx.params.name}` };
28
- },
29
- });
30
-
31
- await server.start();
32
- console.log("Server running on %s", server.info.uri);
33
- };
34
-
35
- init();
36
- ```
37
-
38
- ## Estructura recomendada de contratos
39
-
40
- Hapi anima a agrupar rutas en plugins o dominios funcionales. Para mantener el contrato alineado con esa estructura se recomienda centralizarlo en una carpeta específica:
41
-
42
- ```txt
43
- contracts/
44
- ├─ usersContract.ts
45
- ├─ clientsContract.ts
46
- ├─ productsContract.ts
47
- ├─ facturasContract.ts
48
- ├─ ofertasContract.ts
49
- └─ index.ts
50
- ```
51
-
52
- Cada plugin puede importar solo el contrato que le corresponde:
53
-
54
- ```typescript
55
- import { usersContract } from "./contracts";
56
-
57
- adapters.hapi.handleContract(server, usersContract, {
58
- "GET /users/:id": async (ctx) => {
59
- return { id: ctx.params.id };
60
- },
61
- });
62
- ```
63
-
64
- ## Características
65
-
66
- - Convierte automáticamente las rutas de estilo Express (`:param`) al estilo Hapi (`{param}`).
67
- - Mapea `request.payload` al body del contexto.
@@ -1,61 +0,0 @@
1
- # Koa Adapter
2
-
3
- Adaptador para usar `SchemaApi` con Koa y `koa-router`.
4
-
5
- ## Uso
6
-
7
- ```typescript
8
- import Koa from "koa";
9
- import Router from "@koa/router"; // o cualquier router compatible
10
- import bodyParser from "koa-bodyparser";
11
- import { createContract, adapters } from "schemaapi";
12
-
13
- const app = new Koa();
14
- const router = new Router();
15
-
16
- app.use(bodyParser());
17
-
18
- const contract = createContract({
19
- // ... definición del contrato
20
- });
21
-
22
- adapters.koa.handleContract(router, contract, {
23
- // ... implementación de handlers
24
- });
25
-
26
- app.use(router.routes());
27
- app.use(router.allowedMethods());
28
-
29
- app.listen(3000);
30
- ```
31
-
32
- ## Estructura recomendada de contratos
33
-
34
- Koa no impone una estructura de proyecto, pero en aplicaciones medianas/grandes es recomendable separar los contratos por dominio en una carpeta dedicada:
35
-
36
- ```txt
37
- contracts/
38
- ├─ usersContract.ts
39
- ├─ clientsContract.ts
40
- ├─ productsContract.ts
41
- ├─ facturasContract.ts
42
- ├─ ofertasContract.ts
43
- └─ index.ts
44
- ```
45
-
46
- Luego puedes montar cada contrato en routers separados:
47
-
48
- ```typescript
49
- import { usersContract } from "./contracts";
50
-
51
- adapters.koa.handleContract(router, usersContract, {
52
- "GET /users/:id": async (ctx) => {
53
- return { id: ctx.params.id };
54
- },
55
- });
56
- ```
57
-
58
- ## Requisitos
59
-
60
- - Se recomienda usar `koa-bodyparser` o similar para que `ctx.request.body` esté disponible.
61
- - Se requiere un router que tenga el método `register` (como `@koa/router`).
@@ -1,66 +0,0 @@
1
- # NestJS Adapter
2
-
3
- Este adaptador permite integrar `SchemaApi` en una aplicación NestJS existente, registrando las rutas del contrato dinámicamente.
4
-
5
- ## Uso
6
-
7
- En tu archivo principal `main.ts` (o donde inicialices la app):
8
-
9
- ```typescript
10
- import { NestFactory } from "@nestjs/core";
11
- import { AppModule } from "./app.module";
12
- import { createContract, adapters } from "schemaapi";
13
- import { z } from "zod";
14
-
15
- async function bootstrap() {
16
- const app = await NestFactory.create(AppModule);
17
-
18
- const contract = createContract({
19
- "/items": {
20
- GET: {
21
- response: z.array(z.string()),
22
- },
23
- },
24
- });
25
-
26
- // Registra las rutas del contrato en la aplicación NestJS
27
- adapters.nest.SchemaApiModule.register(app, contract, {
28
- "GET /items": async () => {
29
- return ["item1", "item2"];
30
- },
31
- });
32
-
33
- await app.listen(3000);
34
- }
35
- bootstrap();
36
- ```
37
-
38
- ## Estructura recomendada de contratos
39
-
40
- NestJS suele organizarse por módulos (`UsersModule`, `OrdersModule`, etc.). Es buena práctica acompañar esa estructura con contratos por dominio, por ejemplo:
41
-
42
- ```txt
43
- contracts/
44
- ├─ usersContract.ts
45
- ├─ productsContract.ts
46
- ├─ facturasContract.ts
47
- └─ index.ts
48
- ```
49
-
50
- Cada módulo puede importar únicamente el contrato que le corresponde:
51
-
52
- ```typescript
53
- import { usersContract } from "../contracts";
54
-
55
- adapters.nest.SchemaApiModule.register(app, usersContract, {
56
- "GET /users": async () => {
57
- return [];
58
- },
59
- });
60
- ```
61
-
62
- ## Notas
63
-
64
- - Funciona accediendo al adaptador HTTP subyacente de NestJS (Express por defecto).
65
- - Permite coexistir con controladores tradicionales de NestJS.
66
- - Ideal para migrar progresivamente o exponer APIs definidas externamente.
@@ -1,66 +0,0 @@
1
- # Next.js Adapter
2
-
3
- Este adaptador permite usar `SchemaApi` con Next.js App Router (Route Handlers).
4
-
5
- ## Uso con App Router
6
-
7
- Crea un archivo catch-all para tu API, por ejemplo en `app/api/[...route]/route.ts`.
8
-
9
- ```typescript
10
- import { createContract, adapters } from "schemaapi";
11
- import { z } from "zod";
12
-
13
- const contract = createContract({
14
- "/users/:id": {
15
- GET: {
16
- params: z.object({ id: z.string() }),
17
- response: z.object({ id: z.string() }),
18
- },
19
- },
20
- });
21
-
22
- const handlers = {
23
- "GET /users/:id": async (ctx) => {
24
- return { id: ctx.params.id };
25
- },
26
- };
27
-
28
- // Exporta los métodos HTTP soportados
29
- export const { GET, POST, PUT, DELETE, PATCH } = adapters.next.handleContract(
30
- contract,
31
- handlers
32
- );
33
- ```
34
-
35
- ## Estructura recomendada de contratos
36
-
37
- En proyectos Next.js es **muy recomendable** definir los contratos en un módulo compartido, separado de los handlers. Por ejemplo:
38
-
39
- ```txt
40
- contracts/
41
- ├─ usersContract.ts
42
- ├─ clientsContract.ts
43
- ├─ productsContract.ts
44
- ├─ facturasContract.ts
45
- ├─ ofertasContract.ts
46
- └─ index.ts
47
- ```
48
-
49
- Cada archivo exporta un contrato parcial y `contracts/index.ts` reexporta todos. Así puedes usarlo tanto en el servidor (Route Handlers) como en el cliente o en el SDK generado:
50
-
51
- ```typescript
52
- import { adapters } from "schemaapi";
53
- import { usersContract } from "@/contracts";
54
-
55
- export const { GET } = adapters.next.handleContract(usersContract, {
56
- "GET /users/:id": async (ctx) => {
57
- return { id: ctx.params.id };
58
- },
59
- });
60
- ```
61
-
62
- ## Características
63
-
64
- - Soporta App Router (`app/api/...`).
65
- - Maneja automáticamente `NextRequest` y `NextResponse`.
66
- - Enrutamiento basado en el contrato (no necesitas crear carpetas para cada ruta si usas catch-all).