@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.
- package/LICENSE +21 -0
- package/package.json +1 -1
- package/readme.md +125 -48
- package/docs/adapters/deno.md +0 -51
- package/docs/adapters/express.md +0 -67
- package/docs/adapters/fastify.md +0 -64
- package/docs/adapters/hapi.md +0 -67
- package/docs/adapters/koa.md +0 -61
- package/docs/adapters/nest.md +0 -66
- package/docs/adapters/next.md +0 -66
- package/docs/adapters/remix.md +0 -72
- package/docs/cli.md +0 -18
- package/docs/consepts.md +0 -18
- package/docs/getting_started.md +0 -149
- package/docs/sdk.md +0 -25
- package/docs/validation.md +0 -228
- package/docs/versioning.md +0 -28
- package/eslint.config.mjs +0 -34
- package/rollup.config.js +0 -19
- package/src/adapters/deno.ts +0 -139
- package/src/adapters/express.ts +0 -134
- package/src/adapters/fastify.ts +0 -133
- package/src/adapters/hapi.ts +0 -140
- package/src/adapters/index.ts +0 -9
- package/src/adapters/koa.ts +0 -128
- package/src/adapters/nest.ts +0 -122
- package/src/adapters/next.ts +0 -175
- package/src/adapters/remix.ts +0 -145
- package/src/adapters/ws.ts +0 -132
- package/src/core/client.ts +0 -104
- package/src/core/contract.ts +0 -534
- package/src/core/versioning.test.ts +0 -174
- package/src/docs.ts +0 -535
- package/src/index.ts +0 -5
- package/src/playground.test.ts +0 -98
- package/src/playground.ts +0 -13
- package/src/sdk.ts +0 -17
- package/tests/adapters.deno.test.ts +0 -70
- package/tests/adapters.express.test.ts +0 -67
- package/tests/adapters.fastify.test.ts +0 -63
- package/tests/adapters.hapi.test.ts +0 -66
- package/tests/adapters.koa.test.ts +0 -58
- package/tests/adapters.nest.test.ts +0 -85
- package/tests/adapters.next.test.ts +0 -39
- package/tests/adapters.remix.test.ts +0 -52
- package/tests/adapters.ws.test.ts +0 -91
- package/tests/cli.test.ts +0 -156
- package/tests/client.test.ts +0 -110
- package/tests/contract.handle.test.ts +0 -267
- package/tests/docs.test.ts +0 -96
- package/tests/sdk.test.ts +0 -34
- package/tsconfig.json +0 -15
package/docs/adapters/remix.md
DELETED
|
@@ -1,72 +0,0 @@
|
|
|
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
DELETED
|
@@ -1,18 +0,0 @@
|
|
|
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
|
package/docs/consepts.md
DELETED
|
@@ -1,18 +0,0 @@
|
|
|
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.
|
package/docs/getting_started.md
DELETED
|
@@ -1,149 +0,0 @@
|
|
|
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
DELETED
|
@@ -1,25 +0,0 @@
|
|
|
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
|
package/docs/validation.md
DELETED
|
@@ -1,228 +0,0 @@
|
|
|
1
|
-
# SchemaApi - Guía completa de validaciones de Contract
|
|
2
|
-
|
|
3
|
-
> Esta guía sirve como referencia oficial para crear contratos con SchemaApi.
|
|
4
|
-
> Incluye ejemplos de errores, manejo de status codes y buenas prácticas.
|
|
5
|
-
|
|
6
|
-
---
|
|
7
|
-
|
|
8
|
-
## 1️⃣ Métodos HTTP
|
|
9
|
-
|
|
10
|
-
SchemaApi valida que:
|
|
11
|
-
|
|
12
|
-
- El método (GET, POST, PUT, DELETE, PATCH) esté definido en el contrato.
|
|
13
|
-
- No se pueda llamar a rutas inexistentes o métodos no permitidos.
|
|
14
|
-
|
|
15
|
-
```ts
|
|
16
|
-
"/users/:id": {
|
|
17
|
-
GET: { ... },
|
|
18
|
-
POST: { ... }
|
|
19
|
-
}
|
|
20
|
-
Ejemplo de error:
|
|
21
|
-
|
|
22
|
-
ts
|
|
23
|
-
Copiar código
|
|
24
|
-
// Llamada: DELETE /users/123
|
|
25
|
-
// Contrato no tiene DELETE → SchemaApi lanza error:
|
|
26
|
-
// 405 Method Not Allowed
|
|
27
|
-
2️⃣ Rutas existentes
|
|
28
|
-
Todas las rutas definidas en el contrato son obligatorias.
|
|
29
|
-
|
|
30
|
-
Los parámetros dinámicos deben declararse en params.
|
|
31
|
-
|
|
32
|
-
ts
|
|
33
|
-
Copiar código
|
|
34
|
-
"/posts/:postId/comments/:id": {
|
|
35
|
-
GET: { params: z.object({ postId: z.string(), id: z.string() }) }
|
|
36
|
-
}
|
|
37
|
-
Error típico:
|
|
38
|
-
|
|
39
|
-
ts
|
|
40
|
-
Copiar código
|
|
41
|
-
// Llamada: GET /posts/123/comments
|
|
42
|
-
// Falta param `id` → 400 Bad Request
|
|
43
|
-
3️⃣ Path Params
|
|
44
|
-
Valida tipos y obligatoriedad con Zod.
|
|
45
|
-
|
|
46
|
-
Campos incorrectos → 400 Bad Request
|
|
47
|
-
|
|
48
|
-
ts
|
|
49
|
-
Copiar código
|
|
50
|
-
params: z.object({ id: z.string().uuid() })
|
|
51
|
-
Ejemplo de error:
|
|
52
|
-
|
|
53
|
-
ts
|
|
54
|
-
Copiar código
|
|
55
|
-
GET /users/abc-not-uuid
|
|
56
|
-
// Error: 400 - "Invalid path param 'id'"
|
|
57
|
-
4️⃣ Query Params
|
|
58
|
-
Validación de query strings.
|
|
59
|
-
|
|
60
|
-
Soporta opcionales u obligatorios.
|
|
61
|
-
|
|
62
|
-
ts
|
|
63
|
-
Copiar código
|
|
64
|
-
query: z.object({
|
|
65
|
-
page: z.number().optional(),
|
|
66
|
-
limit: z.number().optional()
|
|
67
|
-
})
|
|
68
|
-
Error típico:
|
|
69
|
-
|
|
70
|
-
ts
|
|
71
|
-
Copiar código
|
|
72
|
-
GET /posts?page=one
|
|
73
|
-
// Error: 400 - "Query param 'page' must be a number"
|
|
74
|
-
5️⃣ Body
|
|
75
|
-
Valida requests POST, PUT, PATCH.
|
|
76
|
-
|
|
77
|
-
Campos faltantes o tipo incorrecto → 400.
|
|
78
|
-
|
|
79
|
-
ts
|
|
80
|
-
Copiar código
|
|
81
|
-
body: z.object({
|
|
82
|
-
username: z.string().min(3),
|
|
83
|
-
email: z.string().email()
|
|
84
|
-
})
|
|
85
|
-
Errores posibles:
|
|
86
|
-
|
|
87
|
-
ts
|
|
88
|
-
Copiar código
|
|
89
|
-
POST /users
|
|
90
|
-
body: { username: "ab" }
|
|
91
|
-
// Error: 400 - "Field 'username' must have at least 3 characters"
|
|
92
|
-
// Error: 400 - "Field 'email' is required"
|
|
93
|
-
6️⃣ Headers
|
|
94
|
-
Valida headers obligatorios y formato.
|
|
95
|
-
|
|
96
|
-
ts
|
|
97
|
-
Copiar código
|
|
98
|
-
headers: z.object({ authorization: z.string() })
|
|
99
|
-
Errores:
|
|
100
|
-
|
|
101
|
-
ts
|
|
102
|
-
Copiar código
|
|
103
|
-
// Falta header Authorization
|
|
104
|
-
// Error: 401 Unauthorized
|
|
105
|
-
7️⃣ Roles y autenticación
|
|
106
|
-
Control de permisos por rol.
|
|
107
|
-
|
|
108
|
-
Roles faltantes → 403 Forbidden
|
|
109
|
-
|
|
110
|
-
ts
|
|
111
|
-
Copiar código
|
|
112
|
-
roles: ["user", "admin"]
|
|
113
|
-
Ejemplo de error:
|
|
114
|
-
|
|
115
|
-
ts
|
|
116
|
-
Copiar código
|
|
117
|
-
// Usuario con rol 'guest' intenta GET /users/123
|
|
118
|
-
// Error: 403 Forbidden
|
|
119
|
-
8️⃣ Responses
|
|
120
|
-
Respuesta del handler debe cumplir el schema.
|
|
121
|
-
|
|
122
|
-
Campos faltantes o adicionales → error en dev/test.
|
|
123
|
-
|
|
124
|
-
Esto asegura consistencia con SDK y docs.
|
|
125
|
-
|
|
126
|
-
ts
|
|
127
|
-
Copiar código
|
|
128
|
-
response: z.object({
|
|
129
|
-
id: z.string(),
|
|
130
|
-
username: z.string(),
|
|
131
|
-
email: z.string().email()
|
|
132
|
-
})
|
|
133
|
-
Ejemplo de error:
|
|
134
|
-
|
|
135
|
-
ts
|
|
136
|
-
Copiar código
|
|
137
|
-
return { id: "123", username: "ferum" }
|
|
138
|
-
// Faltó 'email' → SchemaApi lo detecta
|
|
139
|
-
9️⃣ Status Codes y errores
|
|
140
|
-
Todos los errores posibles se definen en errors.
|
|
141
|
-
|
|
142
|
-
Si un handler devuelve un status code no definido → error.
|
|
143
|
-
|
|
144
|
-
ts
|
|
145
|
-
Copiar código
|
|
146
|
-
errors: {
|
|
147
|
-
401: "UNAUTHORIZED",
|
|
148
|
-
404: "USER_NOT_FOUND",
|
|
149
|
-
500: "INTERNAL_ERROR"
|
|
150
|
-
}
|
|
151
|
-
Ejemplo de error:
|
|
152
|
-
|
|
153
|
-
ts
|
|
154
|
-
Copiar código
|
|
155
|
-
// Handler retorna 418
|
|
156
|
-
// Error: 418 is not defined in contract.errors
|
|
157
|
-
🔟 Consistencia general y breaking changes
|
|
158
|
-
Detecta métodos duplicados, campos obligatorios sin schema.
|
|
159
|
-
|
|
160
|
-
Versionado de contratos detecta breaking changes automáticamente.
|
|
161
|
-
|
|
162
|
-
ts
|
|
163
|
-
Copiar código
|
|
164
|
-
const v1 = createContract({ "/users": { GET: { response: UserSchemaV1 } } });
|
|
165
|
-
const v2 = createContract({ "/users": { GET: { response: UserSchemaV2 } } });
|
|
166
|
-
v2.compareWith(v1); // Detecta cambios incompatibles
|
|
167
|
-
1️⃣1️⃣ Ejemplo completo de contrato con todo
|
|
168
|
-
ts
|
|
169
|
-
Copiar código
|
|
170
|
-
import { createContract } from "schemaapi";
|
|
171
|
-
import { z } from "zod";
|
|
172
|
-
|
|
173
|
-
export const contract = createContract({
|
|
174
|
-
"/users/:id": {
|
|
175
|
-
GET: {
|
|
176
|
-
params: z.object({ id: z.string().uuid() }),
|
|
177
|
-
query: z.object({ includePosts: z.boolean().optional() }),
|
|
178
|
-
headers: z.object({ authorization: z.string() }),
|
|
179
|
-
roles: ["user", "admin"],
|
|
180
|
-
response: z.object({
|
|
181
|
-
id: z.string(),
|
|
182
|
-
username: z.string(),
|
|
183
|
-
email: z.string().email(),
|
|
184
|
-
}),
|
|
185
|
-
errors: {
|
|
186
|
-
401: "UNAUTHORIZED",
|
|
187
|
-
404: "USER_NOT_FOUND"
|
|
188
|
-
}
|
|
189
|
-
},
|
|
190
|
-
|
|
191
|
-
PUT: {
|
|
192
|
-
params: z.object({ id: z.string().uuid() }),
|
|
193
|
-
body: z.object({ username: z.string().min(3) }),
|
|
194
|
-
roles: ["admin"],
|
|
195
|
-
response: z.object({ success: z.literal(true) }),
|
|
196
|
-
errors: {
|
|
197
|
-
401: "UNAUTHORIZED",
|
|
198
|
-
403: "FORBIDDEN"
|
|
199
|
-
}
|
|
200
|
-
}
|
|
201
|
-
}
|
|
202
|
-
});
|
|
203
|
-
✅ Resumen de validaciones
|
|
204
|
-
Capa Validación
|
|
205
|
-
Método HTTP ✔
|
|
206
|
-
Ruta existente ✔
|
|
207
|
-
Path params ✔
|
|
208
|
-
Query params ✔
|
|
209
|
-
Body ✔
|
|
210
|
-
Headers ✔
|
|
211
|
-
Roles / permisos ✔
|
|
212
|
-
Status code ✔
|
|
213
|
-
Forma de la response ✔
|
|
214
|
-
Errores declarados ✔
|
|
215
|
-
Consistencia general ✔
|
|
216
|
-
Versionado / breaking ✔
|
|
217
|
-
|
|
218
|
-
💡 Buenas prácticas
|
|
219
|
-
Siempre define roles aunque sea público.
|
|
220
|
-
|
|
221
|
-
Usa Zod para todos params, queries y body.
|
|
222
|
-
|
|
223
|
-
Declara todos los errores posibles.
|
|
224
|
-
|
|
225
|
-
Versiona contratos antes de cambios que rompan compatibilidad.
|
|
226
|
-
|
|
227
|
-
Integra validación en CI/CD para prevenir errores en producción.
|
|
228
|
-
|
package/docs/versioning.md
DELETED
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
Versionado de SchemaApi
|
|
2
|
-
|
|
3
|
-
SchemaApi permite definir versiones de contratos y detectar breaking changes automáticamente.
|
|
4
|
-
|
|
5
|
-
Ejemplo
|
|
6
|
-
const v1 = createContract({ "/users": { GET: { response: UserSchemaV1 } } });
|
|
7
|
-
const v2 = createContract({ "/users": { GET: { response: UserSchemaV2 } } });
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
v2.compareWith(v1); // Detecta cambios incompatibles
|
|
11
|
-
|
|
12
|
-
Qué detecta
|
|
13
|
-
|
|
14
|
-
Campos eliminados
|
|
15
|
-
|
|
16
|
-
Cambios de tipo
|
|
17
|
-
|
|
18
|
-
Cambios de status code
|
|
19
|
-
|
|
20
|
-
Eliminación de rutas o métodos
|
|
21
|
-
|
|
22
|
-
Beneficios
|
|
23
|
-
|
|
24
|
-
Mantener compatibilidad entre clientes y versiones
|
|
25
|
-
|
|
26
|
-
Detectar errores antes de desplegar
|
|
27
|
-
|
|
28
|
-
Facilita migración entre versiones
|
package/eslint.config.mjs
DELETED
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
import globals from "globals";
|
|
2
|
-
import pluginJs from "@eslint/js";
|
|
3
|
-
import tseslint from "typescript-eslint";
|
|
4
|
-
import eslintConfigPrettier from "eslint-config-prettier";
|
|
5
|
-
|
|
6
|
-
export default tseslint.config(
|
|
7
|
-
{
|
|
8
|
-
ignores: ["dist/**", "node_modules/**", "coverage/**"],
|
|
9
|
-
},
|
|
10
|
-
pluginJs.configs.recommended,
|
|
11
|
-
...tseslint.configs.recommended,
|
|
12
|
-
{
|
|
13
|
-
languageOptions: {
|
|
14
|
-
globals: { ...globals.node, ...globals.browser },
|
|
15
|
-
},
|
|
16
|
-
},
|
|
17
|
-
{
|
|
18
|
-
files: ["**/*.ts", "**/*.tsx"],
|
|
19
|
-
languageOptions: {
|
|
20
|
-
parserOptions: {
|
|
21
|
-
project: true,
|
|
22
|
-
tsconfigRootDir: import.meta.dirname,
|
|
23
|
-
},
|
|
24
|
-
},
|
|
25
|
-
},
|
|
26
|
-
{
|
|
27
|
-
files: ["**/*.{js,mjs,cjs}"],
|
|
28
|
-
...tseslint.configs.disableTypeChecked,
|
|
29
|
-
rules: {
|
|
30
|
-
"@typescript-eslint/no-require-imports": "off",
|
|
31
|
-
},
|
|
32
|
-
},
|
|
33
|
-
eslintConfigPrettier
|
|
34
|
-
);
|
package/rollup.config.js
DELETED
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
const typescript = require('@rollup/plugin-typescript');
|
|
2
|
-
const { nodeResolve } = require('@rollup/plugin-node-resolve');
|
|
3
|
-
const commonjs = require('@rollup/plugin-commonjs');
|
|
4
|
-
const pkg = require('./package.json');
|
|
5
|
-
|
|
6
|
-
module.exports = {
|
|
7
|
-
input: 'src/index.ts',
|
|
8
|
-
output: [
|
|
9
|
-
{ file: pkg.main, format: 'cjs', sourcemap: true },
|
|
10
|
-
{ file: pkg.module, format: 'esm', sourcemap: true },
|
|
11
|
-
{ file: pkg.browser, format: 'umd', name: 'SchemaApi', sourcemap: true }
|
|
12
|
-
],
|
|
13
|
-
external: ['zod'],
|
|
14
|
-
plugins: [
|
|
15
|
-
nodeResolve(),
|
|
16
|
-
commonjs(),
|
|
17
|
-
typescript({ tsconfig: './tsconfig.json', declaration: true, rootDir: 'src', outDir: 'dist' }),
|
|
18
|
-
]
|
|
19
|
-
};
|