@codexsploitx/schemaapi 1.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.
Files changed (66) hide show
  1. package/.prettierignore +5 -0
  2. package/.prettierrc +7 -0
  3. package/bin/schemaapi +302 -0
  4. package/build.md +246 -0
  5. package/dist/core/contract.d.ts +4 -0
  6. package/dist/index.d.ts +1 -0
  7. package/dist/schemaapi.cjs.js +13 -0
  8. package/dist/schemaapi.cjs.js.map +1 -0
  9. package/dist/schemaapi.esm.js +11 -0
  10. package/dist/schemaapi.esm.js.map +1 -0
  11. package/dist/schemaapi.umd.js +19 -0
  12. package/dist/schemaapi.umd.js.map +1 -0
  13. package/docs/adapters/deno.md +51 -0
  14. package/docs/adapters/express.md +67 -0
  15. package/docs/adapters/fastify.md +64 -0
  16. package/docs/adapters/hapi.md +67 -0
  17. package/docs/adapters/koa.md +61 -0
  18. package/docs/adapters/nest.md +66 -0
  19. package/docs/adapters/next.md +66 -0
  20. package/docs/adapters/remix.md +72 -0
  21. package/docs/cli.md +18 -0
  22. package/docs/consepts.md +18 -0
  23. package/docs/getting_started.md +149 -0
  24. package/docs/sdk.md +25 -0
  25. package/docs/validation.md +228 -0
  26. package/docs/versioning.md +28 -0
  27. package/eslint.config.mjs +34 -0
  28. package/estructure.md +55 -0
  29. package/libreria.md +319 -0
  30. package/package.json +61 -0
  31. package/readme.md +89 -0
  32. package/resumen.md +188 -0
  33. package/rollup.config.js +19 -0
  34. package/src/adapters/deno.ts +139 -0
  35. package/src/adapters/express.ts +134 -0
  36. package/src/adapters/fastify.ts +133 -0
  37. package/src/adapters/hapi.ts +140 -0
  38. package/src/adapters/index.ts +9 -0
  39. package/src/adapters/koa.ts +128 -0
  40. package/src/adapters/nest.ts +122 -0
  41. package/src/adapters/next.ts +175 -0
  42. package/src/adapters/remix.ts +145 -0
  43. package/src/adapters/ws.ts +132 -0
  44. package/src/core/client.ts +104 -0
  45. package/src/core/contract.ts +534 -0
  46. package/src/core/versioning.test.ts +174 -0
  47. package/src/docs.ts +535 -0
  48. package/src/index.ts +5 -0
  49. package/src/playground.test.ts +98 -0
  50. package/src/playground.ts +13 -0
  51. package/src/sdk.ts +17 -0
  52. package/tests/adapters.deno.test.ts +70 -0
  53. package/tests/adapters.express.test.ts +67 -0
  54. package/tests/adapters.fastify.test.ts +63 -0
  55. package/tests/adapters.hapi.test.ts +66 -0
  56. package/tests/adapters.koa.test.ts +58 -0
  57. package/tests/adapters.nest.test.ts +85 -0
  58. package/tests/adapters.next.test.ts +39 -0
  59. package/tests/adapters.remix.test.ts +52 -0
  60. package/tests/adapters.ws.test.ts +91 -0
  61. package/tests/cli.test.ts +156 -0
  62. package/tests/client.test.ts +110 -0
  63. package/tests/contract.handle.test.ts +267 -0
  64. package/tests/docs.test.ts +96 -0
  65. package/tests/sdk.test.ts +34 -0
  66. package/tsconfig.json +15 -0
@@ -0,0 +1,67 @@
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.
@@ -0,0 +1,64 @@
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).
@@ -0,0 +1,67 @@
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.
@@ -0,0 +1,61 @@
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`).
@@ -0,0 +1,66 @@
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.
@@ -0,0 +1,66 @@
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).
@@ -0,0 +1,72 @@
1
+ # Remix Adapter
2
+
3
+ Adaptador para Remix (y React Router v7+). Genera `loader` y `action` tipados para tus rutas.
4
+
5
+ ## Uso
6
+
7
+ En un archivo de ruta de Remix, por ejemplo `app/routes/users.$id.tsx`:
8
+
9
+ ```typescript
10
+ import { createContract, adapters } from "schemaapi";
11
+ import { useLoaderData } from "@remix-run/react";
12
+
13
+ // Definición del contrato (idealmente importada de un archivo compartido)
14
+ const contract = createContract({
15
+ "/users/:id": {
16
+ GET: {
17
+ // ...
18
+ },
19
+ POST: {
20
+ // ...
21
+ },
22
+ },
23
+ });
24
+
25
+ const handlers = {
26
+ "GET /users/:id": async (ctx) => {
27
+ return { id: ctx.params.id, name: "User Name" };
28
+ },
29
+ "POST /users/:id": async (ctx) => {
30
+ return { success: true };
31
+ },
32
+ };
33
+
34
+ // Genera y exporta loader y action
35
+ export const { loader, action } = adapters.remix.createRouteHandlers(
36
+ contract,
37
+ handlers,
38
+ "/users/:id"
39
+ );
40
+
41
+ export default function UserRoute() {
42
+ const data = useLoaderData<typeof loader>();
43
+ return <div>User: {data.name}</div>;
44
+ }
45
+ ```
46
+
47
+ ## Estructura recomendada de contratos
48
+
49
+ En Remix es **muy recomendable** definir los contratos en un módulo compartido (por ejemplo `app/contracts` o un paquete compartido del monorepo), y no dentro de cada archivo de ruta. Por ejemplo:
50
+
51
+ ```txt
52
+ app/
53
+ ├─ contracts/
54
+ │ ├─ usersContract.ts
55
+ │ ├─ productsContract.ts
56
+ │ └─ index.ts
57
+ └─ routes/
58
+ ├─ users.$id.tsx
59
+ └─ products._index.tsx
60
+ ```
61
+
62
+ De este modo puedes importar el contrato tanto desde el lado servidor (loader/action) como desde el cliente (hooks, componentes) y desde el SDK generado:
63
+
64
+ ```typescript
65
+ import { adapters } from "schemaapi";
66
+ import { usersContract } from "~/contracts";
67
+ ```
68
+
69
+ ## Características
70
+
71
+ - Separa automáticamente `GET` (loader) de otros métodos (action).
72
+ - Usa objetos estándar `Request` / `Response`.
package/docs/cli.md ADDED
@@ -0,0 +1,18 @@
1
+ CLI de SchemaApi
2
+
3
+ La CLI permite generar docs, SDK y tests automáticos desde el contrato.
4
+
5
+ Comandos básicos
6
+
7
+ schemaapi generate docs → Genera documentación estilo Swagger.
8
+
9
+ schemaapi generate sdk → Genera cliente tipado para JS/TS.
10
+
11
+ schemaapi generate tests → Genera tests automáticos por endpoint.
12
+
13
+ schemaapi audit → Auditoría de seguridad y validaciones.
14
+
15
+ Ejemplo
16
+ npx schemaapi generate docs
17
+ npx schemaapi generate sdk
18
+ npx schemaapi generate tests
@@ -0,0 +1,18 @@
1
+ Conceptos de SchemaApi
2
+ Filosofía
3
+
4
+ "Tu API no es tu código. Tu API es un contrato que prometes al mundo."
5
+
6
+ SchemaApi convierte ese contrato en una capa de validación, documentación, tests y SDK. Todo desde un único lugar.
7
+
8
+ Contrato: Define rutas, métodos, parámetros, headers, roles, body y responses.
9
+
10
+ Validación: Garantiza que todas las requests y responses cumplen el contrato.
11
+
12
+ Seguridad: Controla roles, autenticación y errores.
13
+
14
+ Documentación: Genera docs automáticamente desde el contrato.
15
+
16
+ SDK: Crea clientes tipados automáticamente.
17
+
18
+ Tests: Genera tests para cada endpoint y caso de error.
@@ -0,0 +1,149 @@
1
+ # docs/getting_started.md
2
+
3
+ # Cómo comenzar con SchemaApi
4
+
5
+ Este documento explica paso a paso cómo empezar a desarrollar usando SchemaApi, el stack recomendado y la metodología para estructurar tu librería o proyecto.
6
+
7
+ ---
8
+
9
+ ## 1️⃣ Elegir el stack
10
+
11
+ Para sacar el máximo provecho de SchemaApi y soportar JS y TS:
12
+
13
+ * **Lenguaje principal:** TypeScript (TS) → permite tipado y autocompletado.
14
+ * **Soporte JS:** Transpila `.ts` a `.js` y distribuye archivos de tipos `.d.ts`.
15
+ * **Node.js:** >=18
16
+ * **Package manager:** npm o pnpm
17
+ * **Test runner:** Vitest o Jest (elige uno para tests unitarios y de integración)
18
+ * **Bundler (opcional):** esbuild o Rollup si quieres empaquetar UMD/CJS/ESM
19
+ * **Linting:** ESLint + Prettier
20
+
21
+ ---
22
+
23
+ ## 2️⃣ Inicializar proyecto
24
+
25
+ ```bash
26
+ mkdir schemaapi-project
27
+ cd schemaapi-project
28
+ npm init -y
29
+ npm install typescript zod
30
+ npm install -D vitest ts-node eslint prettier
31
+ npx tsc --init
32
+ ```
33
+
34
+ Esto crea un proyecto TS básico y prepara el entorno para desarrollo.
35
+
36
+ ---
37
+
38
+ ## 3️⃣ Estructura de carpetas
39
+
40
+ Organiza el proyecto así:
41
+
42
+ ```
43
+ src/
44
+ core/ # lógica principal: createContract, validación, context
45
+ adapters/ # integraciones con Express, Next.js, Fastify, etc.
46
+ generators/ # docs, SDK, tests automáticos
47
+ cli/ # scripts de línea de comando
48
+ examples/ # ejemplos de uso
49
+ docs/ # documentación detallada
50
+ types/ # tipos globales para JS
51
+ ```
52
+
53
+ ---
54
+
55
+ ## 4️⃣ Comenzar con el contrato básico
56
+
57
+ 1. Crear el contrato con `createContract`.
58
+ 2. Definir rutas, métodos, params, body, headers, roles y responses.
59
+
60
+ ```ts
61
+ import { createContract } from "schemaapi";
62
+ import { z } from "zod";
63
+
64
+ export const contract = createContract({
65
+ "/users/:id": {
66
+ GET: {
67
+ params: z.object({ id: z.string().uuid() }),
68
+ headers: z.object({ authorization: z.string() }),
69
+ roles: ["user", "admin"],
70
+ response: z.object({ id: z.string(), username: z.string() }),
71
+ },
72
+ },
73
+ });
74
+ ```
75
+
76
+ ---
77
+
78
+ ## 5️⃣ Integrar con tu framework
79
+
80
+ * **Express:** `contract.handle()` para validar requests y responses.
81
+ * **Next.js:** `contract.next()` para Route Handlers.
82
+ * **Fastify / Hono:** middleware adaptado.
83
+
84
+ ```ts
85
+ app.get("/users/:id", contract.handle("GET /users/:id", async (ctx) => {
86
+ const user = await db.findUser(ctx.params.id);
87
+ return user;
88
+ }));
89
+ ```
90
+
91
+ ---
92
+
93
+ ## 6️⃣ Validar responses y errores
94
+
95
+ SchemaApi valida responses automáticamente:
96
+
97
+ * Campos faltantes
98
+ * Tipos incorrectos
99
+ * Status codes
100
+ * Errores definidos
101
+
102
+ ```ts
103
+ return ctx.send(user); // Validación automática de schema
104
+ ```
105
+
106
+ ---
107
+
108
+ ## 7️⃣ Generar documentación, SDK y tests
109
+
110
+ Usa la CLI de SchemaApi:
111
+
112
+ ```bash
113
+ npx schemaapi generate docs # Documentación tipo Swagger
114
+ npx schemaapi generate sdk # Cliente tipado JS/TS
115
+ npx schemaapi generate tests # Tests automáticos por endpoint
116
+ ```
117
+
118
+ ---
119
+
120
+ ## 8️⃣ Versionado de contratos
121
+
122
+ Define versiones de tus contratos y compara cambios:
123
+
124
+ ```ts
125
+ const v1 = createContract({ "/users": { GET: { response: UserSchemaV1 } } });
126
+ const v2 = createContract({ "/users": { GET: { response: UserSchemaV2 } } });
127
+ v2.compareWith(v1); // Detecta breaking changes
128
+ ```
129
+
130
+ ---
131
+
132
+ ## 9️⃣ Buenas prácticas
133
+
134
+ * Siempre define roles y permisos aunque sea público.
135
+ * Usa Zod para validar params, queries y body.
136
+ * Mantén un solo contrato por API principal.
137
+ * Genera docs y SDK desde el contrato, nunca manualmente.
138
+ * Versiona los contratos antes de hacer cambios que rompan compatibilidad.
139
+ * Integra la validación en CI/CD para prevenir errores en producción.
140
+
141
+ ---
142
+
143
+ ## 10️⃣ Próximos pasos
144
+
145
+ * Integrar observabilidad y metrics
146
+ * Crear tests más avanzados
147
+ * Expandir adapters a más frameworks
148
+ * Implementar auditoría y firewall lógico
149
+ * Construir ejemplos reales de JS/TS y publicar librería en npm
package/docs/sdk.md ADDED
@@ -0,0 +1,25 @@
1
+ docs/sdk.md
2
+ SDK de SchemaApi
3
+
4
+ SchemaApi puede generar clientes tipados que consumen tu API sin escribir axios/fetch manualmente.
5
+
6
+ Ejemplo de uso
7
+
8
+ import { createClient } from "schemaapi-sdk";
9
+
10
+
11
+ const client = createClient({ baseUrl: "https://api.mysite.com" });
12
+
13
+
14
+ const user = await client.users.get({ id: "123" });
15
+ await client.users.update({ id: "123", body: { username: "ferum" } });
16
+
17
+ Beneficios
18
+
19
+ Tipado completo en TS
20
+
21
+ Autocompletado en JS/TS
22
+
23
+ Consistencia con el contrato
24
+
25
+ Menos errores en producción