1+ #!/usr/bin/env node
2+
3+ import express from 'express' ;
4+ import { createProxyMiddleware } from 'http-proxy-middleware' ;
5+
6+ // ========== Default Config ==========
7+ const defaultPort = 9017 ;
8+ const defaultTarget = 'https://api.openai.com' ;
9+
10+ // ========== Core Proxy App ==========
11+ function createProxyApp ( target ) {
12+ const app = express ( ) ;
13+
14+ app . use ( '/' , createProxyMiddleware ( {
15+ target : target ,
16+ changeOrigin : true ,
17+ on : {
18+ proxyReq : ( proxyReq , req , res ) => {
19+ proxyReq . removeHeader ( 'x-forwarded-for' ) ;
20+ proxyReq . removeHeader ( 'x-real-ip' ) ;
21+ } ,
22+ proxyRes : ( proxyRes , req , res ) => {
23+ proxyRes . headers [ 'Access-Control-Allow-Origin' ] = '*' ;
24+ proxyRes . headers [ 'Access-Control-Allow-Headers' ] = 'Origin, X-Requested-With, Content-Type, Accept, Authorization' ;
25+ } ,
26+ error : ( err , req , res ) => {
27+ console . error ( 'Proxy error:' , err ) ;
28+ res . status ( 500 ) . send ( 'Proxy error' ) ;
29+ } ,
30+ } ,
31+ } ) ) ;
32+
33+ return app ;
34+ }
35+
36+ // ========== Main App ==========
37+ const parseArguments = ( ) => {
38+ const args = process . argv . slice ( 2 ) ;
39+ const result = { } ;
40+
41+ args . forEach ( arg => {
42+ if ( arg . startsWith ( '--port=' ) ) {
43+ result . port = arg . split ( '=' ) [ 1 ] ;
44+ } else if ( arg . startsWith ( '--target=' ) ) {
45+ result . target = arg . split ( '=' ) [ 1 ] ;
46+ }
47+ } ) ;
48+
49+ return result ;
50+ } ;
51+
52+ const validatePort = ( port ) => {
53+ const portNum = parseInt ( port ) ;
54+ if ( isNaN ( portNum ) ) throw new Error ( `Invalid port: ${ port } ` ) ;
55+ if ( portNum < 1 || portNum > 65535 ) throw new Error ( `Port out of range: ${ port } ` ) ;
56+ return portNum ;
57+ } ;
58+
59+ const validateTarget = ( target ) => {
60+ try {
61+ new URL ( target ) ;
62+ return target ;
63+ } catch {
64+ throw new Error ( `Invalid target URL: ${ target } ` ) ;
65+ }
66+ } ;
67+
68+ const runProxy = ( ) => {
69+ try {
70+ const args = parseArguments ( ) ;
71+ const port = args . port || process . env . PORT || defaultPort ;
72+ const target = args . target || process . env . TARGET || defaultTarget ;
73+
74+ const validatedPort = validatePort ( port ) ;
75+ const validatedTarget = validateTarget ( target ) ;
76+
77+ const app = createProxyApp ( validatedTarget ) ;
78+
79+ const server = app . listen ( validatedPort , ( ) => {
80+ console . log ( 'API Proxy running:' ) ;
81+ console . log ( ` Local: http://localhost:${ validatedPort } ` ) ;
82+ console . log ( ` Target: ${ validatedTarget } ` ) ;
83+ console . log ( '\nPress Ctrl+C to stop' ) ;
84+ } ) ;
85+
86+ server . on ( 'error' , ( err ) => {
87+ if ( err . code === 'EADDRINUSE' ) {
88+ console . error ( `❌ Port ${ validatedPort } is already in use` ) ;
89+ } else {
90+ console . error ( `❌ Server error: ${ err . message } ` ) ;
91+ }
92+ process . exit ( 1 ) ;
93+ } ) ;
94+
95+ process . on ( 'SIGINT' , ( ) => {
96+ console . log ( '\nShutting down proxy...' ) ;
97+ server . close ( ( ) => process . exit ( 0 ) ) ;
98+ } ) ;
99+
100+ } catch ( error ) {
101+ console . error ( `❌ Error: ${ error . message } ` ) ;
102+ process . exit ( 1 ) ;
103+ }
104+ } ;
105+
106+ runProxy ( ) ;
0 commit comments