ts-typed-api 0.1.21 → 0.1.23

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.
@@ -166,10 +166,47 @@ class SchemaRegistry {
166
166
  };
167
167
  }
168
168
  if (zodSchema instanceof zod_1.ZodArray) {
169
- const itemType = getZodType(zodSchema);
169
+ // Try multiple ways to get the array item type
170
+ let itemType;
171
+ // Method 1: Try _def.element (this is the correct property for ZodArray)
172
+ try {
173
+ const def = getZodDef(zodSchema);
174
+ if (def && def.element && typeof def.element === 'object' && def.element.constructor) {
175
+ itemType = def.element;
176
+ }
177
+ }
178
+ catch (error) {
179
+ // Continue to next method
180
+ }
181
+ // Method 2: Try getZodType if method 1 failed
182
+ if (!itemType) {
183
+ const typeResult = getZodType(zodSchema);
184
+ if (typeResult && typeof typeResult === 'object' && typeResult.constructor) {
185
+ itemType = typeResult;
186
+ }
187
+ }
188
+ // Method 3: Direct access to _def.element as fallback
189
+ if (!itemType) {
190
+ try {
191
+ const directElement = zodSchema._def?.element;
192
+ if (directElement && typeof directElement === 'object' && directElement.constructor) {
193
+ itemType = directElement;
194
+ }
195
+ }
196
+ catch (error) {
197
+ // Continue to fallback
198
+ }
199
+ }
200
+ if (itemType) {
201
+ return {
202
+ type: 'array',
203
+ items: this.zodToOpenAPI(itemType, shouldRegister)
204
+ };
205
+ }
206
+ // Ultimate fallback
170
207
  return {
171
208
  type: 'array',
172
- items: itemType ? this.zodToOpenAPI(itemType, shouldRegister) : { type: 'string' }
209
+ items: { type: 'string' }
173
210
  };
174
211
  }
175
212
  if (zodSchema instanceof zod_1.ZodObject) {
@@ -0,0 +1,66 @@
1
+ import { Hono } from 'hono';
2
+ import { RegisterHonoHandlers } from '../src';
3
+ import { PublicApiDefinition, PrivateApiDefinition } from './simple/definitions';
4
+
5
+ // Create Hono app for Cloudflare Workers
6
+ const app = new Hono();
7
+
8
+ // Example middlewares that receive endpoint information
9
+ const loggingMiddleware = async (req: any, res: any, next: any, endpointInfo: any) => {
10
+ console.log(`[${new Date().toISOString()}] ${req.method} ${req.path} - Endpoint: ${endpointInfo.domain}.${endpointInfo.routeKey}`);
11
+ await next();
12
+ };
13
+
14
+ const authMiddleware = async (req: any, res: any, next: any) => {
15
+ // Example auth logic for Workers
16
+ const authHeader = req.headers.get('authorization');
17
+ if (!authHeader || !authHeader.startsWith('Bearer ')) {
18
+ console.log(`Auth failed - No valid auth header`);
19
+ return res.status(401).json({ error: [{ field: "authorization", type: "general", message: "Unauthorized" }] });
20
+ }
21
+ console.log(`Auth passed`);
22
+ await next();
23
+ };
24
+
25
+ // Register public handlers (same as Express version)
26
+ RegisterHonoHandlers(app, PublicApiDefinition, {
27
+ common: {
28
+ ping: async (req, res) => {
29
+ res.respond(200, "pong");
30
+ }
31
+ },
32
+ status: {
33
+ probe1: async (req, res) => {
34
+ if (req.query.match) {
35
+ return res.respond(201, { status: true });
36
+ }
37
+ res.respond(200, "pong");
38
+ },
39
+ probe2: async (req, res) => {
40
+ res.respond(200, "pong");
41
+ }
42
+ }
43
+ }, [loggingMiddleware]);
44
+
45
+ // Register private handlers with auth
46
+ RegisterHonoHandlers(app, PrivateApiDefinition, {
47
+ user: {
48
+ get: async (req, res) => {
49
+ console.log('Fetching user', req.params.id);
50
+ res.respond(200, "ok");
51
+ }
52
+ }
53
+ }, [loggingMiddleware, authMiddleware]);
54
+
55
+ // Export for Cloudflare Workers
56
+ export default app;
57
+
58
+ // For local development/testing (commented out for Workers compatibility)
59
+ // if (typeof process !== 'undefined' && process.env.NODE_ENV === 'development') {
60
+ // console.log('Hono Cloudflare Worker example running locally');
61
+ // console.log('Available routes:');
62
+ // console.log('- GET /api/v1/public/ping');
63
+ // console.log('- GET /api/v1/public/status/probe1');
64
+ // console.log('- GET /api/v1/public/status/probe2');
65
+ // console.log('- GET /api/v1/private/user/:id (requires Bearer token)');
66
+ // }
@@ -0,0 +1,125 @@
1
+ import { Hono } from 'hono';
2
+ import http from 'http';
3
+ import { PublicApiDefinition as SimplePublicApiDefinition, PrivateApiDefinition as SimplePrivateApiDefinition } from './examples/simple/definitions';
4
+ import { RegisterHonoHandlers } from './src';
5
+
6
+ const HONO_PORT = 3004;
7
+
8
+ async function startHonoServer() {
9
+ console.log('Starting Hono server...');
10
+
11
+ const app = new Hono();
12
+
13
+ console.log('Registering handlers...');
14
+
15
+ // Register public handlers using Hono
16
+ RegisterHonoHandlers(app, SimplePublicApiDefinition, {
17
+ common: {
18
+ ping: async (req, res) => {
19
+ console.log('Handling ping request');
20
+ res.respond(200, "pong");
21
+ }
22
+ },
23
+ status: {
24
+ probe1: async (req, res) => {
25
+ console.log('Handling probe1 request, query:', req.query);
26
+ if (req.query.match) {
27
+ return res.respond(201, { status: true });
28
+ }
29
+ res.respond(200, "pong");
30
+ },
31
+ probe2: async (req, res) => {
32
+ console.log('Handling probe2 request');
33
+ res.respond(200, "pong");
34
+ }
35
+ }
36
+ });
37
+
38
+ // Register private handlers using Hono
39
+ RegisterHonoHandlers(app, SimplePrivateApiDefinition, {
40
+ user: {
41
+ get: async (req, res) => {
42
+ console.log('Handling user get request, params:', req.params);
43
+ res.respond(200, "ok");
44
+ }
45
+ }
46
+ });
47
+
48
+ console.log('Creating HTTP server wrapper...');
49
+
50
+ // Create HTTP server from Hono app
51
+ const server = app.fetch;
52
+
53
+ // Create a simple HTTP server wrapper for Hono
54
+ const honoServer = http.createServer(async (req: any, res: any) => {
55
+ console.log(`Incoming request: ${req.method} ${req.url}`);
56
+
57
+ try {
58
+ // Read the request body for non-GET/HEAD methods
59
+ let body: ReadableStream | undefined;
60
+ if (req.method !== 'GET' && req.method !== 'HEAD') {
61
+ console.log('Reading request body...');
62
+ const chunks: Buffer[] = [];
63
+ for await (const chunk of req) {
64
+ chunks.push(chunk);
65
+ }
66
+ const buffer = Buffer.concat(chunks);
67
+ console.log('Request body length:', buffer.length);
68
+ body = new ReadableStream({
69
+ start(controller) {
70
+ controller.enqueue(buffer);
71
+ controller.close();
72
+ }
73
+ });
74
+ }
75
+
76
+ console.log('Creating Web API Request...');
77
+ const request = new Request(`http://localhost:${HONO_PORT}${req.url}`, {
78
+ method: req.method,
79
+ headers: req.headers,
80
+ body: body
81
+ });
82
+
83
+ console.log('Calling Hono app.fetch...');
84
+ const response = await server(request);
85
+
86
+ console.log('Response status:', response.status);
87
+ console.log('Response headers:', Object.fromEntries(response.headers.entries()));
88
+
89
+ res.statusCode = response.status;
90
+ for (const [key, value] of response.headers) {
91
+ res.setHeader(key, value);
92
+ }
93
+
94
+ const responseBody = await response.text();
95
+ console.log('Response body:', responseBody);
96
+ res.end(responseBody);
97
+ } catch (error) {
98
+ console.error('Hono server error:', error);
99
+ res.statusCode = 500;
100
+ res.end('Internal Server Error');
101
+ }
102
+ });
103
+
104
+ console.log(`Starting server on port ${HONO_PORT}...`);
105
+ honoServer.listen(HONO_PORT, () => {
106
+ console.log(`Hono server listening on port ${HONO_PORT}`);
107
+ console.log('Available endpoints:');
108
+ console.log(' GET /api/v1/public/ping');
109
+ console.log(' GET /api/v1/public/status/probe1');
110
+ console.log(' GET /api/v1/public/status/probe1?match=true');
111
+ console.log(' GET /api/v1/public/status/probe2');
112
+ console.log(' GET /api/v1/private/user/:id');
113
+ });
114
+
115
+ // Graceful shutdown
116
+ process.on('SIGINT', () => {
117
+ console.log('Shutting down server...');
118
+ honoServer.close(() => {
119
+ console.log('Server closed');
120
+ process.exit(0);
121
+ });
122
+ });
123
+ }
124
+
125
+ startHonoServer().catch(console.error);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ts-typed-api",
3
- "version": "0.1.21",
3
+ "version": "0.1.23",
4
4
  "description": "A lightweight, type-safe RPC library for TypeScript with Zod validation",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -48,6 +48,7 @@
48
48
  "@types/multer": "^1.4.13",
49
49
  "@types/node": "^24.0.3",
50
50
  "express": "^5.1.0",
51
+ "hono": "^4.10.0",
51
52
  "multer": "^2.0.1",
52
53
  "zod": "^4.0.5"
53
54
  },
@@ -77,4 +78,4 @@
77
78
  "url": "https://github.com/PeterOsinski/ts-typed-api/issues"
78
79
  },
79
80
  "homepage": "https://github.com/PeterOsinski/ts-typed-api#readme"
80
- }
81
+ }