@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,228 @@
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
+
@@ -0,0 +1,28 @@
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
@@ -0,0 +1,34 @@
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/estructure.md ADDED
@@ -0,0 +1,55 @@
1
+ Estructura Recomendada
2
+
3
+ schemaapi/
4
+ ├── src/
5
+ │ ├── core/
6
+ │ │ ├── contract.ts # createContract y definición de contratos
7
+ │ │ ├── validator.ts # Validación de requests/responses
8
+ │ │ ├── context.ts # Contexto de request (params, body, headers)
9
+ │ │ └── response-validator.ts # Validación de respuestas
10
+ │ ├── adapters/
11
+ │ │ ├── express.ts
12
+ │ │ ├── next.ts
13
+ │ │ ├── fastify.ts
14
+ │ │ └── hono.ts
15
+ │ ├── generators/
16
+ │ │ ├── docs.ts # Generación de documentación
17
+ │ │ ├── sdk.ts # Generación de SDK tipado
18
+ │ │ └── tests.ts # Generación de tests automáticos
19
+ │ └── cli/
20
+ │ ├── index.ts
21
+ │ └── commands/
22
+ ├── types/
23
+ │ └── index.d.ts # Tipos globales para JS
24
+ ├── docs/
25
+ │ ├── concepts.md
26
+ │ ├── validation.md
27
+ │ ├── cli.md
28
+ │ ├── sdk.md
29
+ │ └── versioning.md
30
+ ├── examples/
31
+ │ ├── express-example.ts
32
+ │ ├── nextjs-example.ts
33
+ │ └── client-js.ts
34
+ ├── package.json
35
+ ├── tsconfig.json
36
+ ├── README.md
37
+ └── LICENSE
38
+
39
+
40
+ 🏗️ Estructura interna
41
+
42
+ core/ → lógica principal de contratos y validaciones
43
+
44
+ adapters/ → integración con frameworks
45
+
46
+ generators/ → docs, SDK y tests automáticos
47
+
48
+ cli/ → herramientas de línea de comandos
49
+
50
+ types/ → tipos para JS
51
+
52
+
53
+ ---
54
+
55
+
package/libreria.md ADDED
@@ -0,0 +1,319 @@
1
+ Plan para crear la librería schemaapi en npm
2
+ 1️⃣ Stack y herramientas
3
+
4
+ Lenguaje: TypeScript (permite generar JS + tipado para usuarios TS)
5
+
6
+ Bundler: Rollup (para crear el bundle de npm, compatible con Node y Browser)
7
+
8
+ Target: Node.js y Browser (UMD + ESM)
9
+
10
+ Testing: Vitest o Jest
11
+
12
+ Lint / Formato: ESLint + Prettier
13
+
14
+ Publicación: npm
15
+
16
+ 2️⃣ Estructura del proyecto
17
+ schemaapi/
18
+ ├─ src/
19
+ │ ├─ index.ts # Entry point de la librería
20
+ │ ├─ contract.ts # createContract
21
+ │ ├─ sdk.ts # generateSDK
22
+ │ ├─ adapters/ # Adaptadores para Express, Next, Fastify...
23
+ │ │ ├─ express.ts
24
+ │ │ ├─ next.ts
25
+ │ │ └─ fastify.ts
26
+ │ └─ utils/ # Helpers internos
27
+ ├─ package.json
28
+ ├─ tsconfig.json
29
+ ├─ rollup.config.ts
30
+ ├─ README.md
31
+ └─ LICENSE
32
+
33
+ 3️⃣ Funcionalidades que debe exponer la librería
34
+ // src/index.ts
35
+ export { createContract } from "./contract";
36
+ export { generateSDK } from "./sdk";
37
+
38
+ // Adapters (opcional)
39
+ export * as adapters from "./adapters";
40
+
41
+
42
+ createContract → define los endpoints y validaciones (params, query, body, headers, roles, response, errores)
43
+
44
+ generateSDK → genera un SDK tipado listo para usar
45
+
46
+ adapters → integración rápida con frameworks populares (Express, Next.js, Fastify, NestJS, etc.)
47
+
48
+ 4️⃣ Ejemplo de uso después de publicar en npm
49
+ // Instalación
50
+ npm install schemaapi
51
+
52
+ // Definir contrato
53
+ import { createContract, generateSDK, adapters } from "schemaapi";
54
+ import { z } from "zod";
55
+
56
+ const userContract = createContract({
57
+ "/users/:id": {
58
+ GET: {
59
+ params: z.object({ id: z.string().uuid() }),
60
+ headers: z.object({ authorization: z.string() }),
61
+ roles: ["user", "admin"],
62
+ response: z.object({
63
+ id: z.string(),
64
+ username: z.string(),
65
+ email: z.string().email(),
66
+ }),
67
+ errors: {
68
+ 401: "UNAUTHORIZED",
69
+ 404: "USER_NOT_FOUND",
70
+ },
71
+ },
72
+ },
73
+ });
74
+
75
+ // Generar SDK listo para usar
76
+ const schemaApiSdk = generateSDK(userContract, { baseUrl: "http://localhost:3000" });
77
+
78
+ // Usar en Express
79
+ import express from "express";
80
+ const app = express();
81
+ app.use(express.json());
82
+ adapters.express.handleContract(app, userContract);
83
+ app.listen(3000);
84
+
85
+ // Usar SDK
86
+ const user = await schemaApiSdk.getUser({ params: { id: "uuid-aqui" }, headers: { authorization: "Bearer TOKEN" } });
87
+
88
+ 5️⃣ Configuración de Rollup
89
+ // rollup.config.ts
90
+ import typescript from "@rollup/plugin-typescript";
91
+
92
+ export default {
93
+ input: "src/index.ts",
94
+ output: [
95
+ { file: "dist/schemaapi.cjs.js", format: "cjs" },
96
+ { file: "dist/schemaapi.esm.js", format: "esm" },
97
+ ],
98
+ plugins: [typescript({ tsconfig: "./tsconfig.json" })],
99
+ external: ["zod"], // No incluir dependencias externas
100
+ };
101
+
102
+
103
+ Esto permite que tu librería sea usable tanto en Node como en Browser
104
+
105
+ Usuarios solo hacen import { createContract } from "schemaapi" y listo
106
+
107
+ 6️⃣ Publicación en npm
108
+ npm login
109
+ npm version patch
110
+ npm publish --access public
111
+
112
+
113
+ Cada cambio mayor: npm version major
114
+
115
+ Cada cambio menor: npm version minor
116
+
117
+ Cada bugfix: npm version patch
118
+
119
+ 7️⃣ Bonus: integración lista para IDE + IA
120
+
121
+ Todos los métodos de SDK son tipados → autocompletado inmediato
122
+
123
+ Cada endpoint tiene params/query/body/headers tipados desde el contrato
124
+
125
+ Adaptadores permiten integración rápida en Express, Next.js, Fastify, NestJS, etc.
126
+
127
+ Validación de response y errores en tiempo de desarrollo
128
+
129
+ Si quieres, puedo hacer un prototipo completo de librería lista para publicar en npm, con:
130
+
131
+ createContract + validaciones completas
132
+
133
+ generateSDK tipado automáticamente
134
+
135
+ Adaptadores Express / Next / Fastify
136
+
137
+ Ejemplos de uso listos para instalar
138
+
139
+ Rollup + TS configurado para npm
140
+
141
+ Esto sería básicamente tu librería lista para usar en producción.
142
+
143
+ ¿Quieres que haga eso ahora?
144
+
145
+ dame el .md para que mi ide trae ia lo haga con todos los adapatores y compatibilidad
146
+
147
+ ¡Perfecto! 😎 Te voy a armar un README.md completo que tu IDE con IA pueda usar para autocompletar y generar todo: contratos, SDK, y adaptadores listos para todos los frameworks populares. Todo explicado paso a paso y con ejemplos.
148
+
149
+ # SchemaApi - Librería NPM: Contratos, SDK y Adaptadores
150
+
151
+ > Guía completa de uso de SchemaApi con todos los adaptadores y compatibilidad para frameworks populares.
152
+ > Diseñado para autocompletado y soporte de IDEs con IA.
153
+
154
+ ---
155
+
156
+ ## 1️⃣ Instalación
157
+
158
+ ```bash
159
+ npm install schemaapi zod
160
+
161
+
162
+ zod es la dependencia principal para la validación de schemas.
163
+
164
+ 2️⃣ Importación principal
165
+ import { createContract, generateSDK, adapters } from "schemaapi";
166
+ import { z } from "zod";
167
+
168
+
169
+ createContract: define tus endpoints y validaciones
170
+
171
+ generateSDK: genera un SDK tipado listo para usar
172
+
173
+ adapters: integración rápida con frameworks populares
174
+
175
+ 3️⃣ Crear un contrato de ejemplo
176
+ export const userContract = createContract({
177
+ "/users/:id": {
178
+ GET: {
179
+ params: z.object({ id: z.string().uuid() }),
180
+ query: z.object({ includePosts: z.boolean().optional() }),
181
+ headers: z.object({ authorization: z.string() }),
182
+ roles: ["user", "admin"],
183
+ response: z.object({
184
+ id: z.string(),
185
+ username: z.string(),
186
+ email: z.string().email(),
187
+ }),
188
+ errors: {
189
+ 401: "UNAUTHORIZED",
190
+ 404: "USER_NOT_FOUND",
191
+ },
192
+ },
193
+ PUT: {
194
+ params: z.object({ id: z.string().uuid() }),
195
+ body: z.object({ username: z.string().min(3) }),
196
+ roles: ["admin"],
197
+ response: z.object({ success: z.literal(true) }),
198
+ errors: {
199
+ 401: "UNAUTHORIZED",
200
+ 403: "FORBIDDEN",
201
+ },
202
+ },
203
+ },
204
+ });
205
+
206
+ 4️⃣ Generar el SDK
207
+ export const schemaApiSdk = generateSDK(userContract, {
208
+ baseUrl: "http://localhost:3000",
209
+ });
210
+
211
+
212
+ Todos los endpoints del contrato se convierten en métodos tipados
213
+
214
+ Incluye validación automática de params, query, body, headers y response
215
+
216
+ Ejemplo de uso del SDK:
217
+
218
+ const user = await schemaApiSdk.getUser({
219
+ params: { id: "uuid-aqui" },
220
+ query: { includePosts: true },
221
+ headers: { authorization: "Bearer TOKEN" },
222
+ });
223
+ console.log(user.username);
224
+
225
+ 5️⃣ Adaptadores para frameworks populares
226
+ 5.1 Express
227
+ import express from "express";
228
+ const app = express();
229
+ app.use(express.json());
230
+ adapters.express.handleContract(app, userContract);
231
+ app.listen(3000);
232
+
233
+ 5.2 Next.js API Routes
234
+ // pages/api/users/[id].ts
235
+ export default adapters.next.handleContract(userContract);
236
+
237
+ 5.3 Fastify
238
+ import Fastify from "fastify";
239
+ const fastify = Fastify({ logger: true });
240
+ adapters.fastify.handleContract(fastify, userContract);
241
+ fastify.listen({ port: 3000 });
242
+
243
+ 5.4 NestJS
244
+ import { Module } from "@nestjs/common";
245
+
246
+ @Module({
247
+ imports: [
248
+ adapters.nest.SchemaApiModule.register({ contracts: [userContract] }),
249
+ ],
250
+ })
251
+ export class AppModule {}
252
+
253
+ 5.5 Koa
254
+ import Koa from "koa";
255
+ import bodyParser from "koa-bodyparser";
256
+ const app = new Koa();
257
+ app.use(bodyParser());
258
+ adapters.koa.handleContract(app, userContract);
259
+ app.listen(3000);
260
+
261
+ 5.6 Hapi
262
+ import Hapi from "@hapi/hapi";
263
+ const server = Hapi.server({ port: 3000 });
264
+ await adapters.hapi.handleContract(server, userContract);
265
+ await server.start();
266
+
267
+ 5.7 Remix
268
+ // app/routes/users.$id.ts
269
+ export const loader = adapters.remix.handleContract(userContract);
270
+ export const action = adapters.remix.handleContract(userContract);
271
+
272
+ 5.8 Bun / Deno
273
+ import { serve } from "bun";
274
+ serve(adapters.deno.handleContract(userContract), { port: 3000 });
275
+
276
+ 6️⃣ Ejemplo completo de frontend usando SDK
277
+ import { schemaApiSdk } from "../sdk";
278
+
279
+ async function loadUser(id: string) {
280
+ try {
281
+ const user = await schemaApiSdk.getUser({
282
+ params: { id },
283
+ query: { includePosts: true },
284
+ headers: { authorization: "Bearer TOKEN" },
285
+ });
286
+ console.log(user.username, user.email);
287
+ } catch (err) {
288
+ console.error("Error:", err.message);
289
+ }
290
+ }
291
+
292
+
293
+ Compatible con React, Next.js o cualquier frontend
294
+
295
+ Tipado y autocompletado garantizado
296
+
297
+ 7️⃣ Beneficios
298
+
299
+ Una sola fuente de verdad (contract) para todos los frameworks
300
+
301
+ Validación completa: params, query, body, headers, roles, response, status codes
302
+
303
+ SDK tipado listo para backend y frontend
304
+
305
+ Compatible con IDEs IA → autocompletado y prevención de errores
306
+
307
+ Fácil integración con Express, Next.js, Fastify, NestJS, Koa, Hapi, Remix, Bun, Deno
308
+
309
+ 8️⃣ Tips para IDE con IA
310
+
311
+ Mantener todos los contratos en un archivo central contracts/index.ts
312
+
313
+ Siempre usar TypeScript para tipado completo
314
+
315
+ Documentar cada endpoint para que la IA sugiera tipos y errores automáticamente
316
+
317
+ Usar schemaApiSdk para llamadas reales en frontend o backend
318
+
319
+ Cambios en el contrato → regenerar SDK → autocompletado actualizado