@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,5 @@
1
+ dist
2
+ node_modules
3
+ coverage
4
+ pnpm-lock.yaml
5
+ package-lock.json
package/.prettierrc ADDED
@@ -0,0 +1,7 @@
1
+ {
2
+ "semi": true,
3
+ "singleQuote": false,
4
+ "tabWidth": 2,
5
+ "trailingComma": "none",
6
+ "printWidth": 80
7
+ }
package/bin/schemaapi ADDED
@@ -0,0 +1,302 @@
1
+ #!/usr/bin/env node
2
+ const fs = require("fs");
3
+ const path = require("path");
4
+ let schemaapi = {};
5
+ try {
6
+ // When installed as a package, this resolves to the SchemaApi entrypoint.
7
+ // During local development, it points to the built dist file.
8
+ // If it fails, we fall back to an internal minimal HTML renderer.
9
+ // eslint-disable-next-line @typescript-eslint/no-var-requires
10
+ schemaapi = require("..");
11
+ } catch {
12
+ schemaapi = {};
13
+ }
14
+
15
+ const args = process.argv.slice(2);
16
+
17
+ function showHelp() {
18
+ console.log("SchemaApi CLI");
19
+ console.log("");
20
+ console.log("Usage:");
21
+ console.log(" schemaapi generate docs");
22
+ console.log(" schemaapi generate sdk");
23
+ console.log(" schemaapi generate tests");
24
+ console.log(" schemaapi audit");
25
+ console.log(" schemaapi init <adapter>");
26
+ }
27
+
28
+ function loadConfig() {
29
+ const cwd = process.cwd();
30
+ const configPath = path.join(cwd, "schemaapi.config.json");
31
+ if (!fs.existsSync(configPath)) {
32
+ return null;
33
+ }
34
+ try {
35
+ const raw = fs.readFileSync(configPath, "utf8");
36
+ return JSON.parse(raw);
37
+ } catch {
38
+ return null;
39
+ }
40
+ }
41
+
42
+ function loadContractsModule(contractsDir) {
43
+ const cwd = process.cwd();
44
+ const baseDir = path.join(cwd, contractsDir || "contracts");
45
+ const candidates = ["index.js", "index.cjs"];
46
+
47
+ for (const file of candidates) {
48
+ const fullPath = path.join(baseDir, file);
49
+ if (fs.existsSync(fullPath)) {
50
+ try {
51
+ return require(fullPath);
52
+ } catch (error) {
53
+ console.error(
54
+ `Failed to load contracts module at ${fullPath}:`,
55
+ (error && error.message) || error
56
+ );
57
+ process.exitCode = 1;
58
+ return null;
59
+ }
60
+ }
61
+ }
62
+
63
+ console.error(
64
+ `Could not find contracts entry in ${baseDir}. Expected one of: ${candidates.join(
65
+ ", "
66
+ )}`
67
+ );
68
+ process.exitCode = 1;
69
+ return null;
70
+ }
71
+
72
+ function renderDocsHtmlFallback(docs) {
73
+ const items = Array.isArray(docs.routes)
74
+ ? docs.routes
75
+ .map((route) => {
76
+ const method = route && route.method ? String(route.method) : "";
77
+ const pathValue = route && route.path ? String(route.path) : "";
78
+ return `<li><code>${method} ${pathValue}</code></li>`;
79
+ })
80
+ .join("\n")
81
+ : "";
82
+
83
+ return `<!doctype html>
84
+ <html lang="en">
85
+ <head>
86
+ <meta charset="utf-8" />
87
+ <title>SchemaApi Docs</title>
88
+ </head>
89
+ <body>
90
+ <h1>SchemaApi Docs</h1>
91
+ <ul>
92
+ ${items}
93
+ </ul>
94
+ </body>
95
+ </html>`;
96
+ }
97
+
98
+ function generateDocsFromContracts(config) {
99
+ const adapter = config && config.adapter ? String(config.adapter) : null;
100
+ const contractsDir =
101
+ config && config.contractsDir ? String(config.contractsDir) : "contracts";
102
+
103
+ console.log("Generating docs from contract");
104
+ if (adapter || contractsDir) {
105
+ console.log(
106
+ `Using config: adapter=${adapter || "unknown"}, contractsDir=${contractsDir}`
107
+ );
108
+ }
109
+
110
+ const contractsModule = loadContractsModule(contractsDir);
111
+ if (!contractsModule) {
112
+ return;
113
+ }
114
+
115
+ const candidates = Object.values(contractsModule).filter(
116
+ (value) =>
117
+ value &&
118
+ typeof value === "object" &&
119
+ typeof value.docs === "function"
120
+ );
121
+
122
+ if (candidates.length === 0) {
123
+ console.error(
124
+ "No contracts with a docs() method were found in the contracts entry file."
125
+ );
126
+ process.exitCode = 1;
127
+ return;
128
+ }
129
+
130
+ const combinedDocs = {
131
+ routes: candidates.flatMap((contract) => {
132
+ try {
133
+ const docs = contract.docs();
134
+ return Array.isArray(docs.routes) ? docs.routes : [];
135
+ } catch {
136
+ return [];
137
+ }
138
+ }),
139
+ };
140
+
141
+ if (!combinedDocs.routes.length) {
142
+ console.error(
143
+ "Contracts loaded, but no routes were found when calling docs()."
144
+ );
145
+ process.exitCode = 1;
146
+ return;
147
+ }
148
+
149
+ const outDir = path.join(process.cwd(), "schemaapi-docs");
150
+ if (!fs.existsSync(outDir)) {
151
+ fs.mkdirSync(outDir, { recursive: true });
152
+ }
153
+ const outPath = path.join(outDir, "index.html");
154
+
155
+ const hasRenderDocs =
156
+ schemaapi && typeof schemaapi.renderDocs === "function";
157
+ const html = hasRenderDocs
158
+ ? schemaapi.renderDocs(combinedDocs, {
159
+ format: "html",
160
+ title: "SchemaApi Docs",
161
+ theme: "dark",
162
+ })
163
+ : renderDocsHtmlFallback(combinedDocs);
164
+
165
+ fs.writeFileSync(outPath, html, "utf8");
166
+ console.log(`Docs generated at: ${path.relative(process.cwd(), outPath)}`);
167
+ }
168
+
169
+ function handleGenerate(target) {
170
+ const config = loadConfig();
171
+ const adapter = config && config.adapter ? String(config.adapter) : null;
172
+ const contractsDir =
173
+ config && config.contractsDir ? String(config.contractsDir) : null;
174
+
175
+ if (target === "docs") {
176
+ generateDocsFromContracts(config || {});
177
+ return;
178
+ }
179
+ if (target === "sdk") {
180
+ console.log("Generating SDK from contract");
181
+ if (adapter || contractsDir) {
182
+ console.log(
183
+ `Using config: adapter=${adapter || "unknown"}, contractsDir=${contractsDir || "contracts"}`
184
+ );
185
+ }
186
+ return;
187
+ }
188
+ if (target === "tests") {
189
+ console.log("Generating tests from contract");
190
+ if (adapter || contractsDir) {
191
+ console.log(
192
+ `Using config: adapter=${adapter || "unknown"}, contractsDir=${contractsDir || "contracts"}`
193
+ );
194
+ }
195
+ return;
196
+ }
197
+ console.error(`Unknown generate target: ${target || ""}`);
198
+ process.exitCode = 1;
199
+ }
200
+
201
+ function handleAudit() {
202
+ console.log("Running SchemaApi audit");
203
+ }
204
+
205
+ function normalizeAdapter(value) {
206
+ if (!value) return "generic";
207
+ const v = String(value).toLowerCase();
208
+ if (v === "next" || v === "nextjs") return "next";
209
+ if (v === "remix") return "remix";
210
+ if (v === "express") return "express";
211
+ if (v === "fastify") return "fastify";
212
+ if (v === "nest" || v === "nestjs") return "nest";
213
+ if (v === "koa") return "koa";
214
+ if (v === "hapi") return "hapi";
215
+ if (v === "deno") return "deno";
216
+ return v;
217
+ }
218
+
219
+ function handleInit(adapterArg) {
220
+ const adapter = normalizeAdapter(adapterArg);
221
+ const cwd = process.cwd();
222
+ const contractsDir = path.join(cwd, "contracts");
223
+
224
+ if (!fs.existsSync(contractsDir)) {
225
+ fs.mkdirSync(contractsDir, { recursive: true });
226
+ }
227
+
228
+ const usersContractPath = path.join(contractsDir, "usersContract.ts");
229
+ if (!fs.existsSync(usersContractPath)) {
230
+ const usersContractContent = [
231
+ 'import { createContract } from "schemaapi";',
232
+ 'import { z } from "zod";',
233
+ "",
234
+ "export const usersContract = createContract({",
235
+ ' "/users/:id": {',
236
+ " GET: {",
237
+ " params: z.object({ id: z.string() }),",
238
+ " response: z.object({ id: z.string(), name: z.string() }),",
239
+ " },",
240
+ " },",
241
+ "});",
242
+ "",
243
+ ].join("\n");
244
+ fs.writeFileSync(usersContractPath, usersContractContent);
245
+ }
246
+
247
+ const indexPath = path.join(contractsDir, "index.ts");
248
+ if (!fs.existsSync(indexPath)) {
249
+ fs.writeFileSync(indexPath, 'export * from "./usersContract";\n');
250
+ }
251
+
252
+ const configPath = path.join(cwd, "schemaapi.config.json");
253
+ let existingConfig = null;
254
+ if (fs.existsSync(configPath)) {
255
+ try {
256
+ const raw = fs.readFileSync(configPath, "utf8");
257
+ existingConfig = JSON.parse(raw);
258
+ } catch {
259
+ existingConfig = null;
260
+ }
261
+ }
262
+
263
+ const config = Object.assign({}, existingConfig || {}, {
264
+ adapter,
265
+ contractsDir: existingConfig && existingConfig.contractsDir ? existingConfig.contractsDir : "contracts",
266
+ });
267
+
268
+ fs.writeFileSync(configPath, JSON.stringify(config, null, 2) + "\n");
269
+
270
+ console.log(`Initialized SchemaApi project for adapter: ${adapter}`);
271
+ console.log("SchemaApi init completed. Contracts directory: ./contracts");
272
+ }
273
+
274
+ function main() {
275
+ const [command, subcommand] = args;
276
+
277
+ if (!command) {
278
+ showHelp();
279
+ return;
280
+ }
281
+
282
+ if (command === "generate") {
283
+ handleGenerate(subcommand);
284
+ return;
285
+ }
286
+
287
+ if (command === "audit") {
288
+ handleAudit();
289
+ return;
290
+ }
291
+
292
+ if (command === "init") {
293
+ handleInit(subcommand);
294
+ return;
295
+ }
296
+
297
+ console.error(`Unknown command: ${command}`);
298
+ showHelp();
299
+ process.exitCode = 1;
300
+ }
301
+
302
+ main();
package/build.md ADDED
@@ -0,0 +1,246 @@
1
+ # Guía de build y publicación de SchemaApi
2
+
3
+ Este documento resume los pasos para:
4
+
5
+ - Preparar el paquete para producción
6
+ - Generar el build
7
+ - Verificar que todo está OK
8
+ - Publicar en registries tipo **npm** (y usarlo desde **npm**, **pnpm**, **yarn**, etc.)
9
+
10
+ > Nota: Los ejemplos asumen que estás en la raíz del repo:
11
+ > `/Users/admin/Desktop/DEV/SchemaApi`
12
+
13
+ ---
14
+
15
+ ## 1. Requisitos previos
16
+
17
+ - Node.js `>= 18` (ya está definido en `package.json` → `engines.node`).
18
+ - Tener una cuenta en el registry donde quieras publicar (por defecto `https://registry.npmjs.org/`).
19
+ - Tener configurado tu cliente:
20
+ - Para **npm**:
21
+ ```bash
22
+ npm login
23
+ ```
24
+ - Para **pnpm**:
25
+ ```bash
26
+ pnpm login
27
+ ```
28
+ - Para **yarn**:
29
+ ```bash
30
+ yarn npm login
31
+ ```
32
+
33
+ Todos ellos acaban hablando con el mismo registry (npmjs) salvo que configures otro.
34
+
35
+ ---
36
+
37
+ ## 2. Revisar `package.json`
38
+
39
+ Puntos importantes del `package.json` actual:
40
+
41
+ - `name`: pon aquí el nombre definitivo del paquete en npm.
42
+ - Ejemplo: `"name": "schemaapi"` o `"name": "@tu-org/schemaapi"`.
43
+ - Entradas de build ya configuradas:
44
+ - `"main": "dist/schemaapi.cjs.js"` (CommonJS)
45
+ - `"module": "dist/schemaapi.esm.js"` (ESM)
46
+ - `"browser": "dist/schemaapi.umd.js"` (bundle UMD)
47
+ - `"types": "dist/index.d.ts"` (tipos TypeScript)
48
+ - `"bin": { "schemaapi": "bin/schemaapi" }` (CLI global)
49
+ - Scripts:
50
+ - `"build": "rollup -c"`
51
+ - `"test": "vitest"`
52
+ - `"lint": "eslint ."`
53
+
54
+ Antes de publicar:
55
+
56
+ 1. Asegúrate de que `name`, `version`, `description`, `repository`, `author` y `license` son los definitivos.
57
+ 2. Si quieres controlar qué ficheros se publican, usa:
58
+ - Campo `"files"` en `package.json`, o
59
+ - Un `.npmignore`.
60
+
61
+ ---
62
+
63
+ ## 3. Pasos de build y verificación
64
+
65
+ Desde la raíz del proyecto:
66
+
67
+ 1. Instalar dependencias (si no están ya):
68
+
69
+ ```bash
70
+ npm install
71
+ # o
72
+ pnpm install
73
+ # o
74
+ yarn install
75
+ ```
76
+
77
+ 2. Ejecutar los tests:
78
+
79
+ ```bash
80
+ npm test
81
+ ```
82
+
83
+ 3. Ejecutar el linter (opcional pero recomendado):
84
+
85
+ ```bash
86
+ npm run lint
87
+ ```
88
+
89
+ 4. Generar el build:
90
+
91
+ ```bash
92
+ npm run build
93
+ ```
94
+
95
+ Esto generará:
96
+
97
+ - `dist/schemaapi.cjs.js`
98
+ - `dist/schemaapi.esm.js`
99
+ - `dist/schemaapi.umd.js`
100
+ - `dist/index.d.ts`
101
+ - `dist/core/...` (tipos intermedios)
102
+
103
+ 5. Validar que el CLI funciona con el build:
104
+
105
+ ```bash
106
+ node bin/schemaapi
107
+ node bin/schemaapi generate docs
108
+ ```
109
+
110
+ En un proyecto consumidor (fuera de este repo) podrás ejecutar:
111
+
112
+ ```bash
113
+ npx schemaapi generate docs
114
+ ```
115
+
116
+ ---
117
+
118
+ ## 4. Publicar en npm (registry por defecto)
119
+
120
+ ### 4.1. Login
121
+
122
+ Si no lo has hecho ya:
123
+
124
+ ```bash
125
+ npm login
126
+ ```
127
+
128
+ Introduce usuario, contraseña y email de tu cuenta de npm.
129
+
130
+ ### 4.2. Subir la versión
131
+
132
+ 1. Decide el número de versión siguiendo **semver**:
133
+ - `1.0.0` → versión inicial estable
134
+ - `1.0.1` → bugfix
135
+ - `1.1.0` → nuevas features que no rompen compatibilidad
136
+ - `2.0.0` → cambios rompientes
137
+
138
+ 2. Actualiza la versión en `package.json` (puedes usar comandos de npm):
139
+
140
+ ```bash
141
+ # Ejemplos:
142
+ npm version patch # 1.0.0 -> 1.0.1
143
+ npm version minor # 1.0.0 -> 1.1.0
144
+ npm version major # 1.0.0 -> 2.0.0
145
+ ```
146
+
147
+ Esto actualiza `package.json` y crea un tag git (si el repo está bajo git).
148
+
149
+ 3. Publicar:
150
+
151
+ ```bash
152
+ npm publish
153
+ ```
154
+
155
+ - Si usas un **scope** público (ej. `@tu-org/schemaapi`), asegúrate de tener `"publishConfig": { "access": "public" }` si es necesario.
156
+ - Si quieres una etiqueta distinta de `latest`, puedes usar:
157
+
158
+ ```bash
159
+ npm publish --tag next
160
+ ```
161
+
162
+ ---
163
+
164
+ ## 5. Usar el paquete publicado con npm, pnpm, yarn
165
+
166
+ Una vez publicado en npm, podrás instalarlo desde cualquier cliente:
167
+
168
+ - Con **npm**:
169
+
170
+ ```bash
171
+ npm install schemaapi
172
+ # o
173
+ npm install @tu-org/schemaapi
174
+ ```
175
+
176
+ - Con **pnpm**:
177
+
178
+ ```bash
179
+ pnpm add schemaapi
180
+ # o
181
+ pnpm add @tu-org/schemaapi
182
+ ```
183
+
184
+ - Con **yarn**:
185
+
186
+ ```bash
187
+ yarn add schemaapi
188
+ # o
189
+ yarn add @tu-org/schemaapi
190
+ ```
191
+
192
+ El contenido publicado (dist, bin, types) será el mismo; solo cambia el cliente que lo descarga.
193
+
194
+ ---
195
+
196
+ ## 6. Publicar en otros registries (GitHub Packages, privados, etc.)
197
+
198
+ El proceso es muy similar; cambia principalmente:
199
+
200
+ - El `registry` que configuramos.
201
+ - El nombre del paquete (por ejemplo, GitHub Packages suele usar `@OWNER/NAME`).
202
+
203
+ Ejemplo básico para **GitHub Packages**:
204
+
205
+ 1. En tu `~/.npmrc` o `.npmrc` del proyecto:
206
+
207
+ ```ini
208
+ @tu-org:registry=https://npm.pkg.github.com
209
+ //npm.pkg.github.com/:_authToken=GITHUB_PERSONAL_ACCESS_TOKEN
210
+ ```
211
+
212
+ 2. En `package.json`:
213
+
214
+ ```json
215
+ {
216
+ "name": "@tu-org/schemaapi",
217
+ "publishConfig": {
218
+ "registry": "https://npm.pkg.github.com"
219
+ }
220
+ }
221
+ ```
222
+
223
+ 3. Mismo flujo:
224
+
225
+ ```bash
226
+ npm run build
227
+ npm publish
228
+ ```
229
+
230
+ ---
231
+
232
+ ## 7. Checklist rápido antes de publicar
233
+
234
+ 1. `npm test` pasa.
235
+ 2. `npm run build` genera los artefactos en `dist/`.
236
+ 3. `node bin/schemaapi` muestra la ayuda sin errores.
237
+ 4. `node bin/schemaapi generate docs` funciona en un proyecto de prueba.
238
+ 5. `package.json` tiene:
239
+ - `name` correcto (sin conflictos en el registry).
240
+ - `version` según semver.
241
+ - `main`, `module`, `browser`, `types`, `bin` apuntando a `dist/` y `bin/`.
242
+ - Datos de `repository`, `author`, `license` rellenados.
243
+ 6. Has hecho `npm login` (o el login equivalente si usas otro registry).
244
+
245
+ Con esto deberías tener todo listo para subir la librería a npm y consumirla desde npm/pnpm/yarn como cualquier paquete profesional.
246
+
@@ -0,0 +1,4 @@
1
+ export declare function createContract(schema: any): {
2
+ handle(endpoint: string, handler: Function): Function;
3
+ schema: any;
4
+ };
@@ -0,0 +1 @@
1
+ export * from "./core/contract";
@@ -0,0 +1,13 @@
1
+ 'use strict';
2
+
3
+ function createContract(schema) {
4
+ return {
5
+ handle(endpoint, handler) {
6
+ return handler;
7
+ },
8
+ schema,
9
+ };
10
+ }
11
+
12
+ exports.createContract = createContract;
13
+ //# sourceMappingURL=schemaapi.cjs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schemaapi.cjs.js","sources":["../src/core/contract.ts"],"sourcesContent":["import { z } from \"zod\";\n\nexport function createContract(schema: any) {\n return {\n handle(endpoint: string, handler: Function) {\n return handler;\n },\n schema,\n };\n}\n"],"names":[],"mappings":";;AAEM,SAAU,cAAc,CAAC,MAAW,EAAA;IACxC,OAAO;QACL,MAAM,CAAC,QAAgB,EAAE,OAAiB,EAAA;AACxC,YAAA,OAAO,OAAO;QAChB,CAAC;QACD,MAAM;KACP;AACH;;;;"}
@@ -0,0 +1,11 @@
1
+ function createContract(schema) {
2
+ return {
3
+ handle(endpoint, handler) {
4
+ return handler;
5
+ },
6
+ schema,
7
+ };
8
+ }
9
+
10
+ export { createContract };
11
+ //# sourceMappingURL=schemaapi.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schemaapi.esm.js","sources":["../src/core/contract.ts"],"sourcesContent":["import { z } from \"zod\";\n\nexport function createContract(schema: any) {\n return {\n handle(endpoint: string, handler: Function) {\n return handler;\n },\n schema,\n };\n}\n"],"names":[],"mappings":"AAEM,SAAU,cAAc,CAAC,MAAW,EAAA;IACxC,OAAO;QACL,MAAM,CAAC,QAAgB,EAAE,OAAiB,EAAA;AACxC,YAAA,OAAO,OAAO;QAChB,CAAC;QACD,MAAM;KACP;AACH;;;;"}
@@ -0,0 +1,19 @@
1
+ (function (global, factory) {
2
+ typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
3
+ typeof define === 'function' && define.amd ? define(['exports'], factory) :
4
+ (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.SchemaApi = {}));
5
+ })(this, (function (exports) { 'use strict';
6
+
7
+ function createContract(schema) {
8
+ return {
9
+ handle(endpoint, handler) {
10
+ return handler;
11
+ },
12
+ schema,
13
+ };
14
+ }
15
+
16
+ exports.createContract = createContract;
17
+
18
+ }));
19
+ //# sourceMappingURL=schemaapi.umd.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schemaapi.umd.js","sources":["../src/core/contract.ts"],"sourcesContent":["import { z } from \"zod\";\n\nexport function createContract(schema: any) {\n return {\n handle(endpoint: string, handler: Function) {\n return handler;\n },\n schema,\n };\n}\n"],"names":[],"mappings":";;;;;;IAEM,SAAU,cAAc,CAAC,MAAW,EAAA;QACxC,OAAO;YACL,MAAM,CAAC,QAAgB,EAAE,OAAiB,EAAA;IACxC,YAAA,OAAO,OAAO;YAChB,CAAC;YACD,MAAM;SACP;IACH;;;;;;;;"}
@@ -0,0 +1,51 @@
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.