UNPKG

@xtr-dev/zod-rpc

Version:

Simple, type-safe RPC library with Zod validation and automatic TypeScript inference

116 lines 4.61 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const express_1 = __importDefault(require("express")); const zod_rpc_1 = require("@xtr-dev/zod-rpc"); const shared_1 = require("./shared"); // In-memory user storage const users = new Map([ ['1', { id: '1', name: 'Alice', email: 'alice@example.com', age: 30 }], ['2', { id: '2', name: 'Bob', email: 'bob@example.com', age: 25 }], ['3', { id: '3', name: 'Charlie', email: 'charlie@example.com', age: 35 }], ]); let nextUserId = 4; async function startExpressServer() { const app = (0, express_1.default)(); const port = parseInt(process.env.PORT || '3000', 10); // Body parser middleware for JSON app.use(express_1.default.json()); // CORS middleware for browser clients app.use((req, res, next) => { res.header('Access-Control-Allow-Origin', '*'); res.header('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS'); res.header('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept, Authorization'); if (req.method === 'OPTIONS') { res.sendStatus(200); } else { next(); } }); // Create channel for local method invocation // No transport needed - local methods bypass transport layer const channel = new zod_rpc_1.Channel('server'); // Implement and publish user service (simplified API) channel.publishService(shared_1.userService, { get: async ({ userId }) => { console.log(`📨 Getting user: ${userId}`); const user = users.get(userId); if (!user) { throw new Error(`User ${userId} not found`); } return user; }, create: async ({ name, email, age }) => { console.log(`📨 Creating user: ${name} (${email})`); const id = String(nextUserId++); const user = { id, name, email, age }; users.set(id, user); return { id, success: true }; }, list: async ({ page, limit }) => { console.log(`📨 Listing users: page ${page}, limit ${limit}`); const allUsers = Array.from(users.values()); const start = (page - 1) * limit; const end = start + limit; const pageUsers = allUsers.slice(start, end); return { users: pageUsers.map(({ id, name, email }) => ({ id, name, email })), total: allUsers.length, hasMore: end < allUsers.length, }; }, }); // Implement and publish math service (simplified API) channel.publishService(shared_1.mathService, { add: async ({ a, b }) => { console.log(`📨 Adding: ${a} + ${b}`); return { result: a + b }; }, calculate: async ({ expression, precision = 2, }) => { console.log(`📨 Calculating: ${expression}`); try { // Simple expression evaluator (you might want to use a proper library like mathjs) const result = eval(expression); return { result: Number(result.toFixed(precision)), expression, }; } catch (_error) { throw new Error(`Invalid expression: ${expression}`); } }, }); // Mount RPC middleware at /rpc endpoint app.use('/rpc', (0, zod_rpc_1.zodRpc)(channel)); // Health check endpoint app.get('/health', (req, res) => { res.json({ status: 'ok', timestamp: new Date().toISOString() }); }); // API info endpoint app.get('/', (req, res) => { res.json({ name: 'zod-rpc HTTP Example', version: '1.0.0', endpoints: { rpc: '/rpc', health: '/health', }, services: ['user', 'math'], }); }); // Start server app.listen(port, () => { console.log(`🚀 Express server with zod-rpc running on http://localhost:${port}`); console.log(`📡 RPC endpoint: http://localhost:${port}/rpc`); console.log(`🏥 Health check: http://localhost:${port}/health`); console.log('📋 Available services: user, math'); }); } if (require.main === module) { startExpressServer().catch(console.error); } //# sourceMappingURL=express-server.js.map