@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
@@ -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.
@@ -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
@@ -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
-
@@ -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
- };