vector-framework 0.9.3 → 0.9.5
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.
- package/README.md +9 -5
- package/dist/cli/index.js +42 -15
- package/dist/cli/index.js.map +1 -1
- package/dist/cli.js +33 -112
- package/dist/core/config-loader.d.ts +2 -3
- package/dist/core/config-loader.d.ts.map +1 -1
- package/dist/core/config-loader.js +27 -126
- package/dist/core/config-loader.js.map +1 -1
- package/dist/core/vector.d.ts +7 -7
- package/dist/core/vector.d.ts.map +1 -1
- package/dist/core/vector.js +25 -26
- package/dist/core/vector.js.map +1 -1
- package/dist/dev/route-generator.d.ts.map +1 -1
- package/dist/dev/route-generator.js +0 -1
- package/dist/dev/route-generator.js.map +1 -1
- package/dist/dev/route-scanner.d.ts.map +1 -1
- package/dist/dev/route-scanner.js +0 -6
- package/dist/dev/route-scanner.js.map +1 -1
- package/dist/index.js +3 -3
- package/dist/index.mjs +3 -3
- package/dist/types/index.d.ts +5 -18
- package/dist/types/index.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/cli/index.ts +53 -16
- package/src/core/config-loader.ts +36 -138
- package/src/core/vector.ts +40 -29
- package/src/dev/route-generator.ts +0 -1
- package/src/dev/route-scanner.ts +0 -6
- package/src/types/index.ts +8 -27
package/dist/index.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
var li=Object.defineProperty;var ai=(i,f)=>{for(var l in f)li(i,l,{get:f[l],enumerable:!0,configurable:!0,set:(E)=>f[l]=()=>E})};var R=(i,f)=>()=>(i&&(f=i(i=0)),f);var H=(i="text/plain; charset=utf-8",f)=>(l,E={})=>{if(l===void 0||l instanceof Response)return l;let A=new Response(f?.(l)??l,E.url?void 0:E);return A.headers.set("content-type",i),A},Hi,bi,Si,xi,Gi,Fi,k=async(i)=>{i.content=i.body?await i.clone().json().catch(()=>i.clone().formData()).catch(()=>i.text()):void 0},m=(i)=>{i.cookies=(i.headers.get("Cookie")||"").split(/;\s*/).map((f)=>f.split(/=(.+)/)).reduce((f,[l,E])=>E?(f[l]=E,f):f,{})},F=(i={})=>{let{origin:f="*",credentials:l=!1,allowMethods:E="*",allowHeaders:A,exposeHeaders:a,maxAge:d}=i,_=(w)=>{let O=w?.headers.get("origin");return f===!0?O:f instanceof RegExp?f.test(O)?O:void 0:Array.isArray(f)?f.includes(O)?O:void 0:f instanceof Function?f(O):f=="*"&&l?O:f},N=(w,O)=>{for(let[I,L]of Object.entries(O))L&&w.headers.append(I,L);return w};return{corsify:(w,O)=>w?.headers?.get("access-control-allow-origin")||w.status==101?w:N(w.clone(),{"access-control-allow-origin":_(O),"access-control-allow-credentials":l}),preflight:(w)=>{if(w.method=="OPTIONS"){let O=new Response(null,{status:204});return N(O,{"access-control-allow-origin":_(w),"access-control-allow-methods":E?.join?.(",")??E,"access-control-expose-headers":a?.join?.(",")??a,"access-control-allow-headers":A?.join?.(",")??A??w.headers.get("access-control-request-headers"),"access-control-max-age":d,"access-control-allow-credentials":l})}}}};var Y=R(()=>{Hi=H("application/json; charset=utf-8",JSON.stringify),bi=H("text/plain; charset=utf-8",String),Si=H("text/html"),xi=H("image/jpeg"),Gi=H("image/png"),Fi=H("image/webp")});var $,Q,j;var V=R(()=>{$={OK:200,CREATED:201,ACCEPTED:202,NON_AUTHORITATIVE_INFORMATION:203,NO_CONTENT:204,RESET_CONTENT:205,PARTIAL_CONTENT:206,MULTI_STATUS:207,ALREADY_REPORTED:208,IM_USED:226,MULTIPLE_CHOICES:300,MOVED_PERMANENTLY:301,FOUND:302,SEE_OTHER:303,NOT_MODIFIED:304,USE_PROXY:305,TEMPORARY_REDIRECT:307,PERMANENT_REDIRECT:308,BAD_REQUEST:400,UNAUTHORIZED:401,PAYMENT_REQUIRED:402,FORBIDDEN:403,NOT_FOUND:404,METHOD_NOT_ALLOWED:405,NOT_ACCEPTABLE:406,PROXY_AUTHENTICATION_REQUIRED:407,REQUEST_TIMEOUT:408,CONFLICT:409,GONE:410,LENGTH_REQUIRED:411,PRECONDITION_FAILED:412,PAYLOAD_TOO_LARGE:413,URI_TOO_LONG:414,UNSUPPORTED_MEDIA_TYPE:415,RANGE_NOT_SATISFIABLE:416,EXPECTATION_FAILED:417,IM_A_TEAPOT:418,MISDIRECTED_REQUEST:421,UNPROCESSABLE_ENTITY:422,LOCKED:423,FAILED_DEPENDENCY:424,TOO_EARLY:425,UPGRADE_REQUIRED:426,PRECONDITION_REQUIRED:428,TOO_MANY_REQUESTS:429,REQUEST_HEADER_FIELDS_TOO_LARGE:431,UNAVAILABLE_FOR_LEGAL_REASONS:451,INTERNAL_SERVER_ERROR:500,NOT_IMPLEMENTED:501,BAD_GATEWAY:502,SERVICE_UNAVAILABLE:503,GATEWAY_TIMEOUT:504,HTTP_VERSION_NOT_SUPPORTED:505,VARIANT_ALSO_NEGOTIATES:506,INSUFFICIENT_STORAGE:507,LOOP_DETECTED:508,NOT_EXTENDED:510,NETWORK_AUTHENTICATION_REQUIRED:511},Q={PORT:3000,HOSTNAME:"localhost",ROUTES_DIR:"./routes",CACHE_TTL:0,CORS_MAX_AGE:86400},j={JSON:"application/json",TEXT:"text/plain",HTML:"text/html",FORM_URLENCODED:"application/x-www-form-urlencoded",MULTIPART:"multipart/form-data"}});class c{protectedHandler=null;setProtectedHandler(i){this.protectedHandler=i}async authenticate(i){if(!this.protectedHandler)throw new Error("Protected handler not configured. Use vector.protected() to set authentication handler.");try{let f=await this.protectedHandler(i);return i.authUser=f,f}catch(f){throw new Error(`Authentication failed: ${f instanceof Error?f.message:String(f)}`)}}isAuthenticated(i){return!!i.authUser}getUser(i){return i.authUser||null}}class X{cacheHandler=null;memoryCache=new Map;cleanupInterval=null;setCacheHandler(i){this.cacheHandler=i}async get(i,f,l=Q.CACHE_TTL){if(l<=0)return f();if(this.cacheHandler)return this.cacheHandler(i,f,l);return this.getFromMemoryCache(i,f,l)}async getFromMemoryCache(i,f,l){let E=Date.now(),A=this.memoryCache.get(i);if(this.isCacheValid(A,E))return A.value;let a=await f();return this.setInMemoryCache(i,a,l),a}isCacheValid(i,f){return i!==void 0&&i.expires>f}setInMemoryCache(i,f,l){let E=Date.now()+l*1000;this.memoryCache.set(i,{value:f,expires:E}),this.scheduleCleanup()}scheduleCleanup(){if(this.cleanupInterval)return;this.cleanupInterval=setInterval(()=>{this.cleanupExpired()},60000)}cleanupExpired(){let i=Date.now();for(let[f,l]of this.memoryCache.entries())if(l.expires<=i)this.memoryCache.delete(f);if(this.memoryCache.size===0&&this.cleanupInterval)clearInterval(this.cleanupInterval),this.cleanupInterval=null}clear(){if(this.memoryCache.clear(),this.cleanupInterval)clearInterval(this.cleanupInterval),this.cleanupInterval=null}async set(i,f,l=Q.CACHE_TTL){if(l<=0)return;if(this.cacheHandler){await this.cacheHandler(i,async()=>f,l);return}this.setInMemoryCache(i,f,l)}delete(i){return this.memoryCache.delete(i)}has(i){let f=this.memoryCache.get(i);if(!f)return!1;if(f.expires<=Date.now())return this.memoryCache.delete(i),!1;return!0}generateKey(i,f){let l=new URL(i.url);return[i.method,l.pathname,l.search,f?.authUser?.id||"anonymous"].join(":")}}var u=R(()=>{V()});function U(i){if(typeof i!=="string")throw new TypeError("Path must be a string. Received "+JSON.stringify(i))}function n(i,f){var l="",E=0,A=-1,a=0,d;for(var _=0;_<=i.length;++_){if(_<i.length)d=i.charCodeAt(_);else if(d===47)break;else d=47;if(d===47){if(A===_-1||a===1);else if(A!==_-1&&a===2){if(l.length<2||E!==2||l.charCodeAt(l.length-1)!==46||l.charCodeAt(l.length-2)!==46){if(l.length>2){var N=l.lastIndexOf("/");if(N!==l.length-1){if(N===-1)l="",E=0;else l=l.slice(0,N),E=l.length-1-l.lastIndexOf("/");A=_,a=0;continue}}else if(l.length===2||l.length===1){l="",E=0,A=_,a=0;continue}}if(f){if(l.length>0)l+="/..";else l="..";E=2}}else{if(l.length>0)l+="/"+i.slice(A+1,_);else l=i.slice(A+1,_);E=_-A-1}A=_,a=0}else if(d===46&&a!==-1)++a;else a=-1}return l}function Ei(i,f){var l=f.dir||f.root,E=f.base||(f.name||"")+(f.ext||"");if(!l)return E;if(l===f.root)return l+E;return l+i+E}function x(){var i="",f=!1,l;for(var E=arguments.length-1;E>=-1&&!f;E--){var A;if(E>=0)A=arguments[E];else{if(l===void 0)l=process.cwd();A=l}if(U(A),A.length===0)continue;i=A+"/"+i,f=A.charCodeAt(0)===47}if(i=n(i,!f),f)if(i.length>0)return"/"+i;else return"/";else if(i.length>0)return i;else return"."}function r(i){if(U(i),i.length===0)return".";var f=i.charCodeAt(0)===47,l=i.charCodeAt(i.length-1)===47;if(i=n(i,!f),i.length===0&&!f)i=".";if(i.length>0&&l)i+="/";if(f)return"/"+i;return i}function Ai(i){return U(i),i.length>0&&i.charCodeAt(0)===47}function J(){if(arguments.length===0)return".";var i;for(var f=0;f<arguments.length;++f){var l=arguments[f];if(U(l),l.length>0)if(i===void 0)i=l;else i+="/"+l}if(i===void 0)return".";return r(i)}function G(i,f){if(U(i),U(f),i===f)return"";if(i=x(i),f=x(f),i===f)return"";var l=1;for(;l<i.length;++l)if(i.charCodeAt(l)!==47)break;var E=i.length,A=E-l,a=1;for(;a<f.length;++a)if(f.charCodeAt(a)!==47)break;var d=f.length,_=d-a,N=A<_?A:_,w=-1,O=0;for(;O<=N;++O){if(O===N){if(_>N){if(f.charCodeAt(a+O)===47)return f.slice(a+O+1);else if(O===0)return f.slice(a+O)}else if(A>N){if(i.charCodeAt(l+O)===47)w=O;else if(O===0)w=0}break}var I=i.charCodeAt(l+O),L=f.charCodeAt(a+O);if(I!==L)break;else if(I===47)w=O}var P="";for(O=l+w+1;O<=E;++O)if(O===E||i.charCodeAt(O)===47)if(P.length===0)P+="..";else P+="/..";if(P.length>0)return P+f.slice(a+w);else{if(a+=w,f.charCodeAt(a)===47)++a;return f.slice(a)}}function _i(i){return i}function M(i){if(U(i),i.length===0)return".";var f=i.charCodeAt(0),l=f===47,E=-1,A=!0;for(var a=i.length-1;a>=1;--a)if(f=i.charCodeAt(a),f===47){if(!A){E=a;break}}else A=!1;if(E===-1)return l?"/":".";if(l&&E===1)return"//";return i.slice(0,E)}function di(i,f){if(f!==void 0&&typeof f!=="string")throw new TypeError('"ext" argument must be a string');U(i);var l=0,E=-1,A=!0,a;if(f!==void 0&&f.length>0&&f.length<=i.length){if(f.length===i.length&&f===i)return"";var d=f.length-1,_=-1;for(a=i.length-1;a>=0;--a){var N=i.charCodeAt(a);if(N===47){if(!A){l=a+1;break}}else{if(_===-1)A=!1,_=a+1;if(d>=0)if(N===f.charCodeAt(d)){if(--d===-1)E=a}else d=-1,E=_}}if(l===E)E=_;else if(E===-1)E=i.length;return i.slice(l,E)}else{for(a=i.length-1;a>=0;--a)if(i.charCodeAt(a)===47){if(!A){l=a+1;break}}else if(E===-1)A=!1,E=a+1;if(E===-1)return"";return i.slice(l,E)}}function Oi(i){U(i);var f=-1,l=0,E=-1,A=!0,a=0;for(var d=i.length-1;d>=0;--d){var _=i.charCodeAt(d);if(_===47){if(!A){l=d+1;break}continue}if(E===-1)A=!1,E=d+1;if(_===46){if(f===-1)f=d;else if(a!==1)a=1}else if(f!==-1)a=-1}if(f===-1||E===-1||a===0||a===1&&f===E-1&&f===l+1)return"";return i.slice(f,E)}function Ni(i){if(i===null||typeof i!=="object")throw new TypeError('The "pathObject" argument must be of type Object. Received type '+typeof i);return Ei("/",i)}function Di(i){U(i);var f={root:"",dir:"",base:"",ext:"",name:""};if(i.length===0)return f;var l=i.charCodeAt(0),E=l===47,A;if(E)f.root="/",A=1;else A=0;var a=-1,d=0,_=-1,N=!0,w=i.length-1,O=0;for(;w>=A;--w){if(l=i.charCodeAt(w),l===47){if(!N){d=w+1;break}continue}if(_===-1)N=!1,_=w+1;if(l===46){if(a===-1)a=w;else if(O!==1)O=1}else if(a!==-1)O=-1}if(a===-1||_===-1||O===0||O===1&&a===_-1&&a===d+1){if(_!==-1)if(d===0&&E)f.base=f.name=i.slice(1,_);else f.base=f.name=i.slice(d,_)}else{if(d===0&&E)f.name=i.slice(1,a),f.base=i.slice(1,_);else f.name=i.slice(d,a),f.base=i.slice(d,_);f.ext=i.slice(a,_)}if(d>0)f.dir=i.slice(0,d-1);else if(E)f.dir="/";return f}var W="/",wi=":",Qi;var z=R(()=>{Qi=((i)=>(i.posix=i,i))({resolve:x,normalize:r,isAbsolute:Ai,join:J,relative:G,_makeLong:_i,dirname:M,basename:di,extname:Oi,format:Ni,parse:Di,sep:W,delimiter:wi,win32:null,posix:null})});var{promises:s}=(()=>({}));class K{outputPath;constructor(i="./.vector/routes.generated.ts"){this.outputPath=i}async generate(i){let f=M(this.outputPath);await s.mkdir(f,{recursive:!0});let l=[],E=new Map;for(let _ of i){if(!E.has(_.path))E.set(_.path,[]);E.get(_.path).push(_)}let A=0,a=[];for(let[_,N]of E){let w=G(M(this.outputPath),_).replace(/\\/g,"/").replace(/\.(ts|js)$/,""),O=`route_${A++}`,I=N.filter((L)=>L.name!=="default").map((L)=>L.name);if(N.some((L)=>L.name==="default"))if(I.length>0)l.push(`import ${O}, { ${I.join(", ")} } from '${w}';`);else l.push(`import ${O} from '${w}';`);else if(I.length>0)l.push(`import { ${I.join(", ")} } from '${w}';`);for(let L of N){let P=L.name==="default"?O:L.name;a.push(` ${P},`)}}let d=`// This file is auto-generated. Do not edit manually.
|
|
1
|
+
var li=Object.defineProperty;var ai=(i,f)=>{for(var l in f)li(i,l,{get:f[l],enumerable:!0,configurable:!0,set:(E)=>f[l]=()=>E})};var U=(i,f)=>()=>(i&&(f=i(i=0)),f);var H=(i="text/plain; charset=utf-8",f)=>(l,E={})=>{if(l===void 0||l instanceof Response)return l;let A=new Response(f?.(l)??l,E.url?void 0:E);return A.headers.set("content-type",i),A},Hi,bi,Si,xi,Gi,Fi,k=async(i)=>{i.content=i.body?await i.clone().json().catch(()=>i.clone().formData()).catch(()=>i.text()):void 0},m=(i)=>{i.cookies=(i.headers.get("Cookie")||"").split(/;\s*/).map((f)=>f.split(/=(.+)/)).reduce((f,[l,E])=>E?(f[l]=E,f):f,{})},F=(i={})=>{let{origin:f="*",credentials:l=!1,allowMethods:E="*",allowHeaders:A,exposeHeaders:a,maxAge:O}=i,_=(w)=>{let d=w?.headers.get("origin");return f===!0?d:f instanceof RegExp?f.test(d)?d:void 0:Array.isArray(f)?f.includes(d)?d:void 0:f instanceof Function?f(d):f=="*"&&l?d:f},N=(w,d)=>{for(let[I,L]of Object.entries(d))L&&w.headers.append(I,L);return w};return{corsify:(w,d)=>w?.headers?.get("access-control-allow-origin")||w.status==101?w:N(w.clone(),{"access-control-allow-origin":_(d),"access-control-allow-credentials":l}),preflight:(w)=>{if(w.method=="OPTIONS"){let d=new Response(null,{status:204});return N(d,{"access-control-allow-origin":_(w),"access-control-allow-methods":E?.join?.(",")??E,"access-control-expose-headers":a?.join?.(",")??a,"access-control-allow-headers":A?.join?.(",")??A??w.headers.get("access-control-request-headers"),"access-control-max-age":O,"access-control-allow-credentials":l})}}}};var Y=U(()=>{Hi=H("application/json; charset=utf-8",JSON.stringify),bi=H("text/plain; charset=utf-8",String),Si=H("text/html"),xi=H("image/jpeg"),Gi=H("image/png"),Fi=H("image/webp")});var R,Q,j;var V=U(()=>{R={OK:200,CREATED:201,ACCEPTED:202,NON_AUTHORITATIVE_INFORMATION:203,NO_CONTENT:204,RESET_CONTENT:205,PARTIAL_CONTENT:206,MULTI_STATUS:207,ALREADY_REPORTED:208,IM_USED:226,MULTIPLE_CHOICES:300,MOVED_PERMANENTLY:301,FOUND:302,SEE_OTHER:303,NOT_MODIFIED:304,USE_PROXY:305,TEMPORARY_REDIRECT:307,PERMANENT_REDIRECT:308,BAD_REQUEST:400,UNAUTHORIZED:401,PAYMENT_REQUIRED:402,FORBIDDEN:403,NOT_FOUND:404,METHOD_NOT_ALLOWED:405,NOT_ACCEPTABLE:406,PROXY_AUTHENTICATION_REQUIRED:407,REQUEST_TIMEOUT:408,CONFLICT:409,GONE:410,LENGTH_REQUIRED:411,PRECONDITION_FAILED:412,PAYLOAD_TOO_LARGE:413,URI_TOO_LONG:414,UNSUPPORTED_MEDIA_TYPE:415,RANGE_NOT_SATISFIABLE:416,EXPECTATION_FAILED:417,IM_A_TEAPOT:418,MISDIRECTED_REQUEST:421,UNPROCESSABLE_ENTITY:422,LOCKED:423,FAILED_DEPENDENCY:424,TOO_EARLY:425,UPGRADE_REQUIRED:426,PRECONDITION_REQUIRED:428,TOO_MANY_REQUESTS:429,REQUEST_HEADER_FIELDS_TOO_LARGE:431,UNAVAILABLE_FOR_LEGAL_REASONS:451,INTERNAL_SERVER_ERROR:500,NOT_IMPLEMENTED:501,BAD_GATEWAY:502,SERVICE_UNAVAILABLE:503,GATEWAY_TIMEOUT:504,HTTP_VERSION_NOT_SUPPORTED:505,VARIANT_ALSO_NEGOTIATES:506,INSUFFICIENT_STORAGE:507,LOOP_DETECTED:508,NOT_EXTENDED:510,NETWORK_AUTHENTICATION_REQUIRED:511},Q={PORT:3000,HOSTNAME:"localhost",ROUTES_DIR:"./routes",CACHE_TTL:0,CORS_MAX_AGE:86400},j={JSON:"application/json",TEXT:"text/plain",HTML:"text/html",FORM_URLENCODED:"application/x-www-form-urlencoded",MULTIPART:"multipart/form-data"}});class X{protectedHandler=null;setProtectedHandler(i){this.protectedHandler=i}async authenticate(i){if(!this.protectedHandler)throw new Error("Protected handler not configured. Use vector.protected() to set authentication handler.");try{let f=await this.protectedHandler(i);return i.authUser=f,f}catch(f){throw new Error(`Authentication failed: ${f instanceof Error?f.message:String(f)}`)}}isAuthenticated(i){return!!i.authUser}getUser(i){return i.authUser||null}}class J{cacheHandler=null;memoryCache=new Map;cleanupInterval=null;setCacheHandler(i){this.cacheHandler=i}async get(i,f,l=Q.CACHE_TTL){if(l<=0)return f();if(this.cacheHandler)return this.cacheHandler(i,f,l);return this.getFromMemoryCache(i,f,l)}async getFromMemoryCache(i,f,l){let E=Date.now(),A=this.memoryCache.get(i);if(this.isCacheValid(A,E))return A.value;let a=await f();return this.setInMemoryCache(i,a,l),a}isCacheValid(i,f){return i!==void 0&&i.expires>f}setInMemoryCache(i,f,l){let E=Date.now()+l*1000;this.memoryCache.set(i,{value:f,expires:E}),this.scheduleCleanup()}scheduleCleanup(){if(this.cleanupInterval)return;this.cleanupInterval=setInterval(()=>{this.cleanupExpired()},60000)}cleanupExpired(){let i=Date.now();for(let[f,l]of this.memoryCache.entries())if(l.expires<=i)this.memoryCache.delete(f);if(this.memoryCache.size===0&&this.cleanupInterval)clearInterval(this.cleanupInterval),this.cleanupInterval=null}clear(){if(this.memoryCache.clear(),this.cleanupInterval)clearInterval(this.cleanupInterval),this.cleanupInterval=null}async set(i,f,l=Q.CACHE_TTL){if(l<=0)return;if(this.cacheHandler){await this.cacheHandler(i,async()=>f,l);return}this.setInMemoryCache(i,f,l)}delete(i){return this.memoryCache.delete(i)}has(i){let f=this.memoryCache.get(i);if(!f)return!1;if(f.expires<=Date.now())return this.memoryCache.delete(i),!1;return!0}generateKey(i,f){let l=new URL(i.url);return[i.method,l.pathname,l.search,f?.authUser?.id||"anonymous"].join(":")}}var u=U(()=>{V()});function $(i){if(typeof i!=="string")throw new TypeError("Path must be a string. Received "+JSON.stringify(i))}function r(i,f){var l="",E=0,A=-1,a=0,O;for(var _=0;_<=i.length;++_){if(_<i.length)O=i.charCodeAt(_);else if(O===47)break;else O=47;if(O===47){if(A===_-1||a===1);else if(A!==_-1&&a===2){if(l.length<2||E!==2||l.charCodeAt(l.length-1)!==46||l.charCodeAt(l.length-2)!==46){if(l.length>2){var N=l.lastIndexOf("/");if(N!==l.length-1){if(N===-1)l="",E=0;else l=l.slice(0,N),E=l.length-1-l.lastIndexOf("/");A=_,a=0;continue}}else if(l.length===2||l.length===1){l="",E=0,A=_,a=0;continue}}if(f){if(l.length>0)l+="/..";else l="..";E=2}}else{if(l.length>0)l+="/"+i.slice(A+1,_);else l=i.slice(A+1,_);E=_-A-1}A=_,a=0}else if(O===46&&a!==-1)++a;else a=-1}return l}function Ei(i,f){var l=f.dir||f.root,E=f.base||(f.name||"")+(f.ext||"");if(!l)return E;if(l===f.root)return l+E;return l+i+E}function x(){var i="",f=!1,l;for(var E=arguments.length-1;E>=-1&&!f;E--){var A;if(E>=0)A=arguments[E];else{if(l===void 0)l=process.cwd();A=l}if($(A),A.length===0)continue;i=A+"/"+i,f=A.charCodeAt(0)===47}if(i=r(i,!f),f)if(i.length>0)return"/"+i;else return"/";else if(i.length>0)return i;else return"."}function n(i){if($(i),i.length===0)return".";var f=i.charCodeAt(0)===47,l=i.charCodeAt(i.length-1)===47;if(i=r(i,!f),i.length===0&&!f)i=".";if(i.length>0&&l)i+="/";if(f)return"/"+i;return i}function Ai(i){return $(i),i.length>0&&i.charCodeAt(0)===47}function W(){if(arguments.length===0)return".";var i;for(var f=0;f<arguments.length;++f){var l=arguments[f];if($(l),l.length>0)if(i===void 0)i=l;else i+="/"+l}if(i===void 0)return".";return n(i)}function G(i,f){if($(i),$(f),i===f)return"";if(i=x(i),f=x(f),i===f)return"";var l=1;for(;l<i.length;++l)if(i.charCodeAt(l)!==47)break;var E=i.length,A=E-l,a=1;for(;a<f.length;++a)if(f.charCodeAt(a)!==47)break;var O=f.length,_=O-a,N=A<_?A:_,w=-1,d=0;for(;d<=N;++d){if(d===N){if(_>N){if(f.charCodeAt(a+d)===47)return f.slice(a+d+1);else if(d===0)return f.slice(a+d)}else if(A>N){if(i.charCodeAt(l+d)===47)w=d;else if(d===0)w=0}break}var I=i.charCodeAt(l+d),L=f.charCodeAt(a+d);if(I!==L)break;else if(I===47)w=d}var P="";for(d=l+w+1;d<=E;++d)if(d===E||i.charCodeAt(d)===47)if(P.length===0)P+="..";else P+="/..";if(P.length>0)return P+f.slice(a+w);else{if(a+=w,f.charCodeAt(a)===47)++a;return f.slice(a)}}function _i(i){return i}function M(i){if($(i),i.length===0)return".";var f=i.charCodeAt(0),l=f===47,E=-1,A=!0;for(var a=i.length-1;a>=1;--a)if(f=i.charCodeAt(a),f===47){if(!A){E=a;break}}else A=!1;if(E===-1)return l?"/":".";if(l&&E===1)return"//";return i.slice(0,E)}function Oi(i,f){if(f!==void 0&&typeof f!=="string")throw new TypeError('"ext" argument must be a string');$(i);var l=0,E=-1,A=!0,a;if(f!==void 0&&f.length>0&&f.length<=i.length){if(f.length===i.length&&f===i)return"";var O=f.length-1,_=-1;for(a=i.length-1;a>=0;--a){var N=i.charCodeAt(a);if(N===47){if(!A){l=a+1;break}}else{if(_===-1)A=!1,_=a+1;if(O>=0)if(N===f.charCodeAt(O)){if(--O===-1)E=a}else O=-1,E=_}}if(l===E)E=_;else if(E===-1)E=i.length;return i.slice(l,E)}else{for(a=i.length-1;a>=0;--a)if(i.charCodeAt(a)===47){if(!A){l=a+1;break}}else if(E===-1)A=!1,E=a+1;if(E===-1)return"";return i.slice(l,E)}}function di(i){$(i);var f=-1,l=0,E=-1,A=!0,a=0;for(var O=i.length-1;O>=0;--O){var _=i.charCodeAt(O);if(_===47){if(!A){l=O+1;break}continue}if(E===-1)A=!1,E=O+1;if(_===46){if(f===-1)f=O;else if(a!==1)a=1}else if(f!==-1)a=-1}if(f===-1||E===-1||a===0||a===1&&f===E-1&&f===l+1)return"";return i.slice(f,E)}function Ni(i){if(i===null||typeof i!=="object")throw new TypeError('The "pathObject" argument must be of type Object. Received type '+typeof i);return Ei("/",i)}function Di(i){$(i);var f={root:"",dir:"",base:"",ext:"",name:""};if(i.length===0)return f;var l=i.charCodeAt(0),E=l===47,A;if(E)f.root="/",A=1;else A=0;var a=-1,O=0,_=-1,N=!0,w=i.length-1,d=0;for(;w>=A;--w){if(l=i.charCodeAt(w),l===47){if(!N){O=w+1;break}continue}if(_===-1)N=!1,_=w+1;if(l===46){if(a===-1)a=w;else if(d!==1)d=1}else if(a!==-1)d=-1}if(a===-1||_===-1||d===0||d===1&&a===_-1&&a===O+1){if(_!==-1)if(O===0&&E)f.base=f.name=i.slice(1,_);else f.base=f.name=i.slice(O,_)}else{if(O===0&&E)f.name=i.slice(1,a),f.base=i.slice(1,_);else f.name=i.slice(O,a),f.base=i.slice(O,_);f.ext=i.slice(a,_)}if(O>0)f.dir=i.slice(0,O-1);else if(E)f.dir="/";return f}var z="/",wi=":",Qi;var c=U(()=>{Qi=((i)=>(i.posix=i,i))({resolve:x,normalize:n,isAbsolute:Ai,join:W,relative:G,_makeLong:_i,dirname:M,basename:Oi,extname:di,format:Ni,parse:Di,sep:z,delimiter:wi,win32:null,posix:null})});var{promises:s}=(()=>({}));class K{outputPath;constructor(i="./.vector/routes.generated.ts"){this.outputPath=i}async generate(i){let f=M(this.outputPath);await s.mkdir(f,{recursive:!0});let l=[],E=new Map;for(let _ of i){if(!E.has(_.path))E.set(_.path,[]);E.get(_.path).push(_)}let A=0,a=[];for(let[_,N]of E){let w=G(M(this.outputPath),_).replace(/\\/g,"/").replace(/\.(ts|js)$/,""),d=`route_${A++}`,I=N.filter((L)=>L.name!=="default").map((L)=>L.name);if(N.some((L)=>L.name==="default"))if(I.length>0)l.push(`import ${d}, { ${I.join(", ")} } from '${w}';`);else l.push(`import ${d} from '${w}';`);else if(I.length>0)l.push(`import { ${I.join(", ")} } from '${w}';`);for(let L of N){let P=L.name==="default"?d:L.name;a.push(` ${P},`)}}let O=`// This file is auto-generated. Do not edit manually.
|
|
2
2
|
// Generated at: ${new Date().toISOString()}
|
|
3
3
|
|
|
4
4
|
${l.join(`
|
|
@@ -10,7 +10,7 @@ ${a.join(`
|
|
|
10
10
|
];
|
|
11
11
|
|
|
12
12
|
export default routes;
|
|
13
|
-
`;await s.writeFile(this.outputPath,
|
|
13
|
+
`;await s.writeFile(this.outputPath,O,"utf-8")}async generateDynamic(i){let f=[];for(let l of i){let E=JSON.stringify({method:l.method,path:l.options.path,options:l.options});f.push(` await import('${l.path}').then(m => ({
|
|
14
14
|
...${E},
|
|
15
15
|
handler: m.${l.name==="default"?"default":l.name}
|
|
16
16
|
}))`)}return`export const loadRoutes = async () => {
|
|
@@ -18,4 +18,4 @@ export default routes;
|
|
|
18
18
|
${f.join(`,
|
|
19
19
|
`)}
|
|
20
20
|
]);
|
|
21
|
-
};`}}var y=R(()=>{z()});var{existsSync:Ii,promises:q}=(()=>({}));class Z{routesDir;constructor(i="./routes"){this.routesDir=x(process.cwd(),i)}async scan(){let i=[];if(!Ii(this.routesDir))return console.log(` → Routes directory not found: ${this.routesDir}`),console.log(" → No routes will be auto-discovered"),[];try{if(console.log(` → Scanning routes from: ${this.routesDir}`),await this.scanDirectory(this.routesDir,i),i.length>0)console.log(` ✓ Found ${i.length} route${i.length===1?"":"s"}`)}catch(f){if(f.code==="ENOENT")return console.warn(` ✗ Routes directory not accessible: ${this.routesDir}`),[];throw f}return i}async scanDirectory(i,f,l=""){let E=await q.readdir(i);for(let A of E){let a=J(i,A);if((await q.stat(a)).isDirectory()){let _=l?`${l}/${A}`:A;await this.scanDirectory(a,f,_)}else if(A.endsWith(".ts")||A.endsWith(".js")){let _=G(this.routesDir,a).replace(/\.(ts|js)$/,"").split(W).join("/");try{let w=await import(process.platform==="win32"?`file:///${a.replace(/\\/g,"/")}`:a);if(w.default&&typeof w.default==="function")f.push({name:"default",path:a,method:"GET",options:{method:"GET",path:`/${_}`,expose:!0}});for(let[O,I]of Object.entries(w)){if(O==="default")continue;if(I&&typeof I==="object"&&"entry"in I&&"options"in I&&"handler"in I){let L=I;f.push({name:O,path:a,method:L.options.method,options:L.options})}else if(Array.isArray(I)&&I.length>=4){let[L,,,P]=I;f.push({name:O,path:a,method:L,options:{method:L,path:P,expose:!0}})}}}catch(N){console.error(`Failed to load route from ${a}:`,N)}}}}enableWatch(i){if(typeof Bun!=="undefined"&&Bun.env.NODE_ENV==="development")console.log(`Watching for route changes in ${this.routesDir}`),setInterval(async()=>{await i()},1000)}}var t=R(()=>{z()});class T{beforeHandlers=[];finallyHandlers=[];addBefore(...i){this.beforeHandlers.push(...i)}addFinally(...i){this.finallyHandlers.push(...i)}async executeBefore(i){let f=i;for(let l of this.beforeHandlers){let E=await l(f);if(E instanceof Response)return E;f=E}return f}async executeFinally(i,f){let l=i;for(let E of this.finallyHandlers)l=await E(l,f);return l}clone(){let i=new T;return i.beforeHandlers=[...this.beforeHandlers],i.finallyHandlers=[...this.finallyHandlers],i}clear(){this.beforeHandlers=[],this.finallyHandlers=[]}}function o(i){return process.platform==="win32"?`file:///${i.replace(/\\/g,"/")}`:i}class v{middlewareManager;authManager;cacheManager;routes=[];constructor(i,f,l){this.middlewareManager=i,this.authManager=f,this.cacheManager=l}getRouteSpecificity(i){let a=0,d=i.split("/").filter(Boolean);for(let _ of d)if(this.isStaticSegment(_))a+=1000;else if(this.isParamSegment(_))a+=10;else if(this.isWildcardSegment(_))a+=1;if(a+=i.length,this.isExactPath(i))a+=1e4;return a}isStaticSegment(i){return!i.startsWith(":")&&!i.includes("*")}isParamSegment(i){return i.startsWith(":")}isWildcardSegment(i){return i.includes("*")}isExactPath(i){return!i.includes(":")&&!i.includes("*")}sortRoutes(){this.routes.sort((i,f)=>{let l=this.extractPath(i),E=this.extractPath(f),A=this.getRouteSpecificity(l);return this.getRouteSpecificity(E)-A})}extractPath(i){return i[3]||""}route(i,f){let l=this.wrapHandler(i,f),E=[i.method.toUpperCase(),this.createRouteRegex(i.path),[l],i.path];return this.routes.push(E),this.sortRoutes(),E}createRouteRegex(i){return RegExp(`^${i.replace(/\/+(\/|$)/g,"$1").replace(/(\/?\.?):(\w+)\+/g,"($1(?<$2>*))").replace(/(\/?\.?):(\w+)/g,"($1(?<$2>[^$1/]+?))").replace(/\./g,"\\.").replace(/(\/?)\*/g,"($1.*)?")}/*$`)}wrapHandler(i,f){return async(l)=>{let E=l;if(!E.context)E.context={};if(!E.query&&E.url){let A=new URL(E.url),a={};for(let[d,_]of A.searchParams)a[d]=a[d]?[].concat(a[d],_):_;E.query=a}if(i.metadata)E.metadata=i.metadata;l=E;try{if(i.expose===!1)return C.forbidden("Forbidden");let A=await this.middlewareManager.executeBefore(l);if(A instanceof Response)return A;if(l=A,i.auth)try{await this.authManager.authenticate(l)}catch(N){return C.unauthorized(N instanceof Error?N.message:"Authentication failed",i.responseContentType)}if(!i.rawRequest&&l.method!=="GET"&&l.method!=="HEAD")try{let N=l.headers.get("content-type");if(N?.includes("application/json"))l.content=await l.json();else if(N?.includes("application/x-www-form-urlencoded"))l.content=Object.fromEntries(await l.formData());else if(N?.includes("multipart/form-data"))l.content=await l.formData();else l.content=await l.text()}catch{l.content=null}let a,d=i.cache;if(d&&typeof d==="number"&&d>0){let N=this.cacheManager.generateKey(l,{authUser:l.authUser});a=await this.cacheManager.get(N,()=>f(l),d)}else if(d&&typeof d==="object"&&d.ttl){let N=d.key||this.cacheManager.generateKey(l,{authUser:l.authUser});a=await this.cacheManager.get(N,()=>f(l),d.ttl)}else a=await f(l);let _;if(i.rawResponse||a instanceof Response)_=a instanceof Response?a:new Response(a);else _=b(200,a,i.responseContentType);return _=await this.middlewareManager.executeFinally(_,l),_}catch(A){if(A instanceof Response)return A;return console.error("Route handler error:",A),C.internalServerError(A instanceof Error?A.message:String(A),i.responseContentType)}}}addRoute(i){this.routes.push(i),this.sortRoutes()}getRoutes(){return this.routes}async handle(i){let l=new URL(i.url).pathname;for(let[E,A,a]of this.routes)if(i.method==="OPTIONS"||i.method===E){let d=l.match(A);if(d){let _=i;if(!_.context)_.context={};_.params=d.groups||{};for(let N of a){let w=await N(_);if(w)return w}}}return C.notFound("Route not found")}clearRoutes(){this.routes=[]}}var p=R(()=>{B()});class g{server=null;router;config;corsHandler;constructor(i,f){if(this.router=i,this.config=f,f.cors){let{preflight:l,corsify:E}=F(this.normalizeCorsOptions(f.cors));this.corsHandler={preflight:l,corsify:E}}}normalizeCorsOptions(i){return{origin:i.origin||"*",credentials:i.credentials!==!1,allowHeaders:Array.isArray(i.allowHeaders)?i.allowHeaders.join(", "):i.allowHeaders||"Content-Type, Authorization",allowMethods:Array.isArray(i.allowMethods)?i.allowMethods.join(", "):i.allowMethods||"GET, POST, PUT, PATCH, DELETE, OPTIONS",exposeHeaders:Array.isArray(i.exposeHeaders)?i.exposeHeaders.join(", "):i.exposeHeaders||"Authorization",maxAge:i.maxAge||86400}}async start(){let i=this.config.port||3000,f=this.config.hostname||"localhost",l=async(E)=>{try{if(this.corsHandler&&E.method==="OPTIONS")return this.corsHandler.preflight(E);let A=await this.router.handle(E);if(this.corsHandler)A=this.corsHandler.corsify(A,E);return A}catch(A){return console.error("Server error:",A),new Response("Internal Server Error",{status:500})}};return this.server=Bun.serve({port:i,hostname:f,reusePort:this.config.reusePort!==!1,fetch:l,error:(E)=>{return console.error("[ERROR] Server error:",E),new Response("Internal Server Error",{status:500})}}),console.log(`→ Vector server running at http://${f}:${i}`),this.server}stop(){if(this.server)this.server.stop(),this.server=null,console.log("Server stopped")}getServer(){return this.server}getPort(){return this.server?.port||this.config.port||3000}getHostname(){return this.server?.hostname||this.config.hostname||"localhost"}getUrl(){let i=this.getPort();return`http://${this.getHostname()}:${i}`}}var e=R(()=>{Y()});var ii={};ai(ii,{getVectorInstance:()=>Li,Vector:()=>h});class h{static instance;router;server=null;middlewareManager;authManager;cacheManager;config={};routeScanner=null;routeGenerator=null;_protectedHandler=null;_cacheHandler=null;constructor(){this.middlewareManager=new T,this.authManager=new c,this.cacheManager=new X,this.router=new v(this.middlewareManager,this.authManager,this.cacheManager)}static getInstance(){if(!h.instance)h.instance=new h;return h.instance}setProtectedHandler(i){this._protectedHandler=i,this.authManager.setProtectedHandler(i)}getProtectedHandler(){return this._protectedHandler}setCacheHandler(i){this._cacheHandler=i,this.cacheManager.setCacheHandler(i)}getCacheHandler(){return this._cacheHandler}addRoute(i,f){return this.router.route(i,f)}async startServer(i){if(this.config={...this.config,...i},this.middlewareManager.clear(),i?.before)this.middlewareManager.addBefore(...i.before);if(i?.finally)this.middlewareManager.addFinally(...i.finally);if(this.config.autoDiscover!==!1)await this.discoverRoutes();return this.server=new g(this.router,this.config),await this.server.start()}async discoverRoutes(){let i=this.config.routesDir||"./routes";if(this.routeScanner=new Z(i),!this.routeGenerator)this.routeGenerator=new K;try{let f=await this.routeScanner.scan();if(f.length>0){if(this.config.development)await this.routeGenerator.generate(f);for(let l of f)try{let A=await import(o(l.path)),a=l.name==="default"?A.default:A[l.name];if(a){if(this.isRouteDefinition(a)){let d=a;this.router.route(d.options,d.handler),this.logRouteLoaded(d.options)}else if(this.isRouteEntry(a))this.router.addRoute(a),this.logRouteLoaded(a);else if(typeof a==="function")this.router.route(l.options,a),this.logRouteLoaded(l.options)}}catch(E){console.error(`Failed to load route ${l.name} from ${l.path}:`,E)}this.router.sortRoutes(),console.log(`✅ Loaded ${f.length} routes from ${i}`)}}catch(f){if(f.code!=="ENOENT"&&f.code!=="ENOTDIR")console.error("Failed to discover routes:",f)}}async loadRoute(i){if(typeof i==="function"){let f=i();if(Array.isArray(f))this.router.addRoute(f)}else if(i&&typeof i==="object"){for(let[,f]of Object.entries(i))if(typeof f==="function"){let l=f();if(Array.isArray(l))this.router.addRoute(l)}}}isRouteEntry(i){return Array.isArray(i)&&i.length>=3}isRouteDefinition(i){return i&&typeof i==="object"&&"entry"in i&&"options"in i&&"handler"in i}logRouteLoaded(i){if(Array.isArray(i))console.log(` ✓ Loaded route: ${i[0]} ${i[3]||i[1]}`);else console.log(` ✓ Loaded route: ${i.method} ${i.path}`)}stop(){if(this.server)this.server.stop(),this.server=null;this.router.clearRoutes()}getServer(){return this.server}getRouter(){return this.router}getCacheManager(){return this.cacheManager}getAuthManager(){return this.authManager}static resetInstance(){h.instance=null}}var Li;var fi=R(()=>{u();y();t();p();e();Li=h.getInstance});function $i(i,f){let l=Pi(i,f);return{entry:[i.method.toUpperCase(),RegExp(`^${i.path.replace(/\/+(\/|$)/g,"$1").replace(/(\/?\.?):(\w+)\+/g,"($1(?<$2>*))").replace(/(\/?\.?):(\w+)/g,"($1(?<$2>[^$1/]+?))").replace(/\./g,"\\.").replace(/(\/?)\*/g,"($1.*)?")}/*$`),[l],i.path],options:i,handler:f}}function Ri(i){return JSON.stringify(i??null,(f,l)=>typeof l==="bigint"?l.toString():l)}function D(i,f,l){let E={error:!0,message:f,statusCode:i,timestamp:new Date().toISOString()};return b(i,E,l)}function b(i,f,l=j.JSON){let E=l===j.JSON?Ri(f):f;return new Response(E,{status:i,headers:{"content-type":l}})}function Pi(i,f){let{auth:l=!1,expose:E=!1,rawRequest:A=!1,rawResponse:a=!1,responseContentType:d=j.JSON}=i;return async(_)=>{if(!E)return C.forbidden("Forbidden");try{if(l)await Ci(_,d);if(!A)await k(_);m(_);let N=await f(_);return a?N:Ui.success(N,d)}catch(N){if(N instanceof Response)return N;return C.internalServerError(String(N),d)}}}var lf,af,Ui,C,Ci=async(i,f)=>{let{getVectorInstance:l}=await Promise.resolve().then(() => (fi(),ii)),A=l().getProtectedHandler();if(!A)throw C.unauthorized("Authentication not configured",f);try{let a=await A(i);i.authUser=a}catch(a){throw C.unauthorized(a instanceof Error?a.message:"Authentication failed",f)}};var B=R(()=>{Y();V();({preflight:lf,corsify:af}=F({origin:"*",credentials:!0,allowHeaders:"Content-Type, Authorization",allowMethods:"GET, POST, PUT, PATCH, DELETE, OPTIONS",exposeHeaders:"Authorization",maxAge:86400}));Ui={success:(i,f)=>b($.OK,i,f),created:(i,f)=>b($.CREATED,i,f)};C={badRequest:(i="Bad Request",f)=>D($.BAD_REQUEST,i,f),unauthorized:(i="Unauthorized",f)=>D($.UNAUTHORIZED,i,f),paymentRequired:(i="Payment Required",f)=>D(402,i,f),forbidden:(i="Forbidden",f)=>D($.FORBIDDEN,i,f),notFound:(i="Not Found",f)=>D($.NOT_FOUND,i,f),methodNotAllowed:(i="Method Not Allowed",f)=>D(405,i,f),notAcceptable:(i="Not Acceptable",f)=>D(406,i,f),requestTimeout:(i="Request Timeout",f)=>D(408,i,f),conflict:(i="Conflict",f)=>D($.CONFLICT,i,f),gone:(i="Gone",f)=>D(410,i,f),lengthRequired:(i="Length Required",f)=>D(411,i,f),preconditionFailed:(i="Precondition Failed",f)=>D(412,i,f),payloadTooLarge:(i="Payload Too Large",f)=>D(413,i,f),uriTooLong:(i="URI Too Long",f)=>D(414,i,f),unsupportedMediaType:(i="Unsupported Media Type",f)=>D(415,i,f),rangeNotSatisfiable:(i="Range Not Satisfiable",f)=>D(416,i,f),expectationFailed:(i="Expectation Failed",f)=>D(417,i,f),imATeapot:(i="I'm a teapot",f)=>D(418,i,f),misdirectedRequest:(i="Misdirected Request",f)=>D(421,i,f),unprocessableEntity:(i="Unprocessable Entity",f)=>D($.UNPROCESSABLE_ENTITY,i,f),locked:(i="Locked",f)=>D(423,i,f),failedDependency:(i="Failed Dependency",f)=>D(424,i,f),tooEarly:(i="Too Early",f)=>D(425,i,f),upgradeRequired:(i="Upgrade Required",f)=>D(426,i,f),preconditionRequired:(i="Precondition Required",f)=>D(428,i,f),tooManyRequests:(i="Too Many Requests",f)=>D(429,i,f),requestHeaderFieldsTooLarge:(i="Request Header Fields Too Large",f)=>D(431,i,f),unavailableForLegalReasons:(i="Unavailable For Legal Reasons",f)=>D(451,i,f),internalServerError:(i="Internal Server Error",f)=>D($.INTERNAL_SERVER_ERROR,i,f),notImplemented:(i="Not Implemented",f)=>D(501,i,f),badGateway:(i="Bad Gateway",f)=>D(502,i,f),serviceUnavailable:(i="Service Unavailable",f)=>D(503,i,f),gatewayTimeout:(i="Gateway Timeout",f)=>D(504,i,f),httpVersionNotSupported:(i="HTTP Version Not Supported",f)=>D(505,i,f),variantAlsoNegotiates:(i="Variant Also Negotiates",f)=>D(506,i,f),insufficientStorage:(i="Insufficient Storage",f)=>D(507,i,f),loopDetected:(i="Loop Detected",f)=>D(508,i,f),notExtended:(i="Not Extended",f)=>D(510,i,f),networkAuthenticationRequired:(i="Network Authentication Required",f)=>D(511,i,f),invalidArgument:(i="Invalid Argument",f)=>D($.UNPROCESSABLE_ENTITY,i,f),rateLimitExceeded:(i="Rate Limit Exceeded",f)=>D(429,i,f),maintenance:(i="Service Under Maintenance",f)=>D(503,i,f),custom:(i,f,l)=>D(i,f,l)}});B();B();export{$i as route,b as createResponse,C as APIError};
|
|
21
|
+
};`}}var y=U(()=>{c()});var{existsSync:Ii,promises:q}=(()=>({}));class Z{routesDir;constructor(i="./routes"){this.routesDir=x(process.cwd(),i)}async scan(){let i=[];if(!Ii(this.routesDir))return[];try{await this.scanDirectory(this.routesDir,i)}catch(f){if(f.code==="ENOENT")return console.warn(` ✗ Routes directory not accessible: ${this.routesDir}`),[];throw f}return i}async scanDirectory(i,f,l=""){let E=await q.readdir(i);for(let A of E){let a=W(i,A);if((await q.stat(a)).isDirectory()){let _=l?`${l}/${A}`:A;await this.scanDirectory(a,f,_)}else if(A.endsWith(".ts")||A.endsWith(".js")){let _=G(this.routesDir,a).replace(/\.(ts|js)$/,"").split(z).join("/");try{let w=await import(process.platform==="win32"?`file:///${a.replace(/\\/g,"/")}`:a);if(w.default&&typeof w.default==="function")f.push({name:"default",path:a,method:"GET",options:{method:"GET",path:`/${_}`,expose:!0}});for(let[d,I]of Object.entries(w)){if(d==="default")continue;if(I&&typeof I==="object"&&"entry"in I&&"options"in I&&"handler"in I){let L=I;f.push({name:d,path:a,method:L.options.method,options:L.options})}else if(Array.isArray(I)&&I.length>=4){let[L,,,P]=I;f.push({name:d,path:a,method:L,options:{method:L,path:P,expose:!0}})}}}catch(N){console.error(`Failed to load route from ${a}:`,N)}}}}enableWatch(i){if(typeof Bun!=="undefined"&&Bun.env.NODE_ENV==="development")console.log(`Watching for route changes in ${this.routesDir}`),setInterval(async()=>{await i()},1000)}}var t=U(()=>{c()});class T{beforeHandlers=[];finallyHandlers=[];addBefore(...i){this.beforeHandlers.push(...i)}addFinally(...i){this.finallyHandlers.push(...i)}async executeBefore(i){let f=i;for(let l of this.beforeHandlers){let E=await l(f);if(E instanceof Response)return E;f=E}return f}async executeFinally(i,f){let l=i;for(let E of this.finallyHandlers)l=await E(l,f);return l}clone(){let i=new T;return i.beforeHandlers=[...this.beforeHandlers],i.finallyHandlers=[...this.finallyHandlers],i}clear(){this.beforeHandlers=[],this.finallyHandlers=[]}}function o(i){return process.platform==="win32"?`file:///${i.replace(/\\/g,"/")}`:i}class v{middlewareManager;authManager;cacheManager;routes=[];constructor(i,f,l){this.middlewareManager=i,this.authManager=f,this.cacheManager=l}getRouteSpecificity(i){let a=0,O=i.split("/").filter(Boolean);for(let _ of O)if(this.isStaticSegment(_))a+=1000;else if(this.isParamSegment(_))a+=10;else if(this.isWildcardSegment(_))a+=1;if(a+=i.length,this.isExactPath(i))a+=1e4;return a}isStaticSegment(i){return!i.startsWith(":")&&!i.includes("*")}isParamSegment(i){return i.startsWith(":")}isWildcardSegment(i){return i.includes("*")}isExactPath(i){return!i.includes(":")&&!i.includes("*")}sortRoutes(){this.routes.sort((i,f)=>{let l=this.extractPath(i),E=this.extractPath(f),A=this.getRouteSpecificity(l);return this.getRouteSpecificity(E)-A})}extractPath(i){return i[3]||""}route(i,f){let l=this.wrapHandler(i,f),E=[i.method.toUpperCase(),this.createRouteRegex(i.path),[l],i.path];return this.routes.push(E),this.sortRoutes(),E}createRouteRegex(i){return RegExp(`^${i.replace(/\/+(\/|$)/g,"$1").replace(/(\/?\.?):(\w+)\+/g,"($1(?<$2>*))").replace(/(\/?\.?):(\w+)/g,"($1(?<$2>[^$1/]+?))").replace(/\./g,"\\.").replace(/(\/?)\*/g,"($1.*)?")}/*$`)}wrapHandler(i,f){return async(l)=>{let E=l;if(!E.context)E.context={};if(!E.query&&E.url){let A=new URL(E.url),a={};for(let[O,_]of A.searchParams)a[O]=a[O]?[].concat(a[O],_):_;E.query=a}if(i.metadata)E.metadata=i.metadata;l=E;try{if(i.expose===!1)return C.forbidden("Forbidden");let A=await this.middlewareManager.executeBefore(l);if(A instanceof Response)return A;if(l=A,i.auth)try{await this.authManager.authenticate(l)}catch(N){return C.unauthorized(N instanceof Error?N.message:"Authentication failed",i.responseContentType)}if(!i.rawRequest&&l.method!=="GET"&&l.method!=="HEAD")try{let N=l.headers.get("content-type");if(N?.includes("application/json"))l.content=await l.json();else if(N?.includes("application/x-www-form-urlencoded"))l.content=Object.fromEntries(await l.formData());else if(N?.includes("multipart/form-data"))l.content=await l.formData();else l.content=await l.text()}catch{l.content=null}let a,O=i.cache;if(O&&typeof O==="number"&&O>0){let N=this.cacheManager.generateKey(l,{authUser:l.authUser});a=await this.cacheManager.get(N,()=>f(l),O)}else if(O&&typeof O==="object"&&O.ttl){let N=O.key||this.cacheManager.generateKey(l,{authUser:l.authUser});a=await this.cacheManager.get(N,()=>f(l),O.ttl)}else a=await f(l);let _;if(i.rawResponse||a instanceof Response)_=a instanceof Response?a:new Response(a);else _=b(200,a,i.responseContentType);return _=await this.middlewareManager.executeFinally(_,l),_}catch(A){if(A instanceof Response)return A;return console.error("Route handler error:",A),C.internalServerError(A instanceof Error?A.message:String(A),i.responseContentType)}}}addRoute(i){this.routes.push(i),this.sortRoutes()}getRoutes(){return this.routes}async handle(i){let l=new URL(i.url).pathname;for(let[E,A,a]of this.routes)if(i.method==="OPTIONS"||i.method===E){let O=l.match(A);if(O){let _=i;if(!_.context)_.context={};_.params=O.groups||{};for(let N of a){let w=await N(_);if(w)return w}}}return C.notFound("Route not found")}clearRoutes(){this.routes=[]}}var p=U(()=>{B()});class g{server=null;router;config;corsHandler;constructor(i,f){if(this.router=i,this.config=f,f.cors){let{preflight:l,corsify:E}=F(this.normalizeCorsOptions(f.cors));this.corsHandler={preflight:l,corsify:E}}}normalizeCorsOptions(i){return{origin:i.origin||"*",credentials:i.credentials!==!1,allowHeaders:Array.isArray(i.allowHeaders)?i.allowHeaders.join(", "):i.allowHeaders||"Content-Type, Authorization",allowMethods:Array.isArray(i.allowMethods)?i.allowMethods.join(", "):i.allowMethods||"GET, POST, PUT, PATCH, DELETE, OPTIONS",exposeHeaders:Array.isArray(i.exposeHeaders)?i.exposeHeaders.join(", "):i.exposeHeaders||"Authorization",maxAge:i.maxAge||86400}}async start(){let i=this.config.port||3000,f=this.config.hostname||"localhost",l=async(E)=>{try{if(this.corsHandler&&E.method==="OPTIONS")return this.corsHandler.preflight(E);let A=await this.router.handle(E);if(this.corsHandler)A=this.corsHandler.corsify(A,E);return A}catch(A){return console.error("Server error:",A),new Response("Internal Server Error",{status:500})}};return this.server=Bun.serve({port:i,hostname:f,reusePort:this.config.reusePort!==!1,fetch:l,error:(E)=>{return console.error("[ERROR] Server error:",E),new Response("Internal Server Error",{status:500})}}),console.log(`→ Vector server running at http://${f}:${i}`),this.server}stop(){if(this.server)this.server.stop(),this.server=null,console.log("Server stopped")}getServer(){return this.server}getPort(){return this.server?.port||this.config.port||3000}getHostname(){return this.server?.hostname||this.config.hostname||"localhost"}getUrl(){let i=this.getPort();return`http://${this.getHostname()}:${i}`}}var e=U(()=>{Y()});var ii={};ai(ii,{getVectorInstance:()=>Li,Vector:()=>h});class h{static instance;router;server=null;middlewareManager;authManager;cacheManager;config={};routeScanner=null;routeGenerator=null;_protectedHandler=null;_cacheHandler=null;constructor(){this.middlewareManager=new T,this.authManager=new X,this.cacheManager=new J,this.router=new v(this.middlewareManager,this.authManager,this.cacheManager)}static getInstance(){if(!h.instance)h.instance=new h;return h.instance}setProtectedHandler(i){this._protectedHandler=i,this.authManager.setProtectedHandler(i)}getProtectedHandler(){return this._protectedHandler}setCacheHandler(i){this._cacheHandler=i,this.cacheManager.setCacheHandler(i)}getCacheHandler(){return this._cacheHandler}addRoute(i,f){return this.router.route(i,f)}async startServer(i){if(this.config={...this.config,...i},this.middlewareManager.clear(),i?.before)this.middlewareManager.addBefore(...i.before);if(i?.finally)this.middlewareManager.addFinally(...i.finally);if(this.config.autoDiscover!==!1)await this.discoverRoutes();return this.server=new g(this.router,this.config),await this.server.start()}async discoverRoutes(){let i=this.config.routesDir||"./routes";if(this.routeScanner=new Z(i),!this.routeGenerator)this.routeGenerator=new K;try{let f=await this.routeScanner.scan();if(f.length>0){if(this.config.development)await this.routeGenerator.generate(f);for(let l of f)try{let A=await import(o(l.path)),a=l.name==="default"?A.default:A[l.name];if(a){if(this.isRouteDefinition(a)){let O=a;this.router.route(O.options,O.handler),this.logRouteLoaded(O.options)}else if(this.isRouteEntry(a))this.router.addRoute(a),this.logRouteLoaded(a);else if(typeof a==="function")this.router.route(l.options,a),this.logRouteLoaded(l.options)}}catch(E){console.error(`Failed to load route ${l.name} from ${l.path}:`,E)}this.router.sortRoutes()}}catch(f){if(f.code!=="ENOENT"&&f.code!=="ENOTDIR")console.error("Failed to discover routes:",f)}}async loadRoute(i){if(typeof i==="function"){let f=i();if(Array.isArray(f))this.router.addRoute(f)}else if(i&&typeof i==="object"){for(let[,f]of Object.entries(i))if(typeof f==="function"){let l=f();if(Array.isArray(l))this.router.addRoute(l)}}}isRouteEntry(i){return Array.isArray(i)&&i.length>=3}isRouteDefinition(i){return i&&typeof i==="object"&&"entry"in i&&"options"in i&&"handler"in i}logRouteLoaded(i){}stop(){if(this.server)this.server.stop(),this.server=null;this.router.clearRoutes()}getServer(){return this.server}getRouter(){return this.router}getCacheManager(){return this.cacheManager}getAuthManager(){return this.authManager}static resetInstance(){h.instance=null}}var Li;var fi=U(()=>{u();y();t();p();e();Li=h.getInstance});function Ri(i,f){let l=Pi(i,f);return{entry:[i.method.toUpperCase(),RegExp(`^${i.path.replace(/\/+(\/|$)/g,"$1").replace(/(\/?\.?):(\w+)\+/g,"($1(?<$2>*))").replace(/(\/?\.?):(\w+)/g,"($1(?<$2>[^$1/]+?))").replace(/\./g,"\\.").replace(/(\/?)\*/g,"($1.*)?")}/*$`),[l],i.path],options:i,handler:f}}function Ui(i){return JSON.stringify(i??null,(f,l)=>typeof l==="bigint"?l.toString():l)}function D(i,f,l){let E={error:!0,message:f,statusCode:i,timestamp:new Date().toISOString()};return b(i,E,l)}function b(i,f,l=j.JSON){let E=l===j.JSON?Ui(f):f;return new Response(E,{status:i,headers:{"content-type":l}})}function Pi(i,f){let{auth:l=!1,expose:E=!1,rawRequest:A=!1,rawResponse:a=!1,responseContentType:O=j.JSON}=i;return async(_)=>{if(!E)return C.forbidden("Forbidden");try{if(l)await Ci(_,O);if(!A)await k(_);m(_);let N=await f(_);return a?N:$i.success(N,O)}catch(N){if(N instanceof Response)return N;return C.internalServerError(String(N),O)}}}var lf,af,$i,C,Ci=async(i,f)=>{let{getVectorInstance:l}=await Promise.resolve().then(() => (fi(),ii)),A=l().getProtectedHandler();if(!A)throw C.unauthorized("Authentication not configured",f);try{let a=await A(i);i.authUser=a}catch(a){throw C.unauthorized(a instanceof Error?a.message:"Authentication failed",f)}};var B=U(()=>{Y();V();({preflight:lf,corsify:af}=F({origin:"*",credentials:!0,allowHeaders:"Content-Type, Authorization",allowMethods:"GET, POST, PUT, PATCH, DELETE, OPTIONS",exposeHeaders:"Authorization",maxAge:86400}));$i={success:(i,f)=>b(R.OK,i,f),created:(i,f)=>b(R.CREATED,i,f)};C={badRequest:(i="Bad Request",f)=>D(R.BAD_REQUEST,i,f),unauthorized:(i="Unauthorized",f)=>D(R.UNAUTHORIZED,i,f),paymentRequired:(i="Payment Required",f)=>D(402,i,f),forbidden:(i="Forbidden",f)=>D(R.FORBIDDEN,i,f),notFound:(i="Not Found",f)=>D(R.NOT_FOUND,i,f),methodNotAllowed:(i="Method Not Allowed",f)=>D(405,i,f),notAcceptable:(i="Not Acceptable",f)=>D(406,i,f),requestTimeout:(i="Request Timeout",f)=>D(408,i,f),conflict:(i="Conflict",f)=>D(R.CONFLICT,i,f),gone:(i="Gone",f)=>D(410,i,f),lengthRequired:(i="Length Required",f)=>D(411,i,f),preconditionFailed:(i="Precondition Failed",f)=>D(412,i,f),payloadTooLarge:(i="Payload Too Large",f)=>D(413,i,f),uriTooLong:(i="URI Too Long",f)=>D(414,i,f),unsupportedMediaType:(i="Unsupported Media Type",f)=>D(415,i,f),rangeNotSatisfiable:(i="Range Not Satisfiable",f)=>D(416,i,f),expectationFailed:(i="Expectation Failed",f)=>D(417,i,f),imATeapot:(i="I'm a teapot",f)=>D(418,i,f),misdirectedRequest:(i="Misdirected Request",f)=>D(421,i,f),unprocessableEntity:(i="Unprocessable Entity",f)=>D(R.UNPROCESSABLE_ENTITY,i,f),locked:(i="Locked",f)=>D(423,i,f),failedDependency:(i="Failed Dependency",f)=>D(424,i,f),tooEarly:(i="Too Early",f)=>D(425,i,f),upgradeRequired:(i="Upgrade Required",f)=>D(426,i,f),preconditionRequired:(i="Precondition Required",f)=>D(428,i,f),tooManyRequests:(i="Too Many Requests",f)=>D(429,i,f),requestHeaderFieldsTooLarge:(i="Request Header Fields Too Large",f)=>D(431,i,f),unavailableForLegalReasons:(i="Unavailable For Legal Reasons",f)=>D(451,i,f),internalServerError:(i="Internal Server Error",f)=>D(R.INTERNAL_SERVER_ERROR,i,f),notImplemented:(i="Not Implemented",f)=>D(501,i,f),badGateway:(i="Bad Gateway",f)=>D(502,i,f),serviceUnavailable:(i="Service Unavailable",f)=>D(503,i,f),gatewayTimeout:(i="Gateway Timeout",f)=>D(504,i,f),httpVersionNotSupported:(i="HTTP Version Not Supported",f)=>D(505,i,f),variantAlsoNegotiates:(i="Variant Also Negotiates",f)=>D(506,i,f),insufficientStorage:(i="Insufficient Storage",f)=>D(507,i,f),loopDetected:(i="Loop Detected",f)=>D(508,i,f),notExtended:(i="Not Extended",f)=>D(510,i,f),networkAuthenticationRequired:(i="Network Authentication Required",f)=>D(511,i,f),invalidArgument:(i="Invalid Argument",f)=>D(R.UNPROCESSABLE_ENTITY,i,f),rateLimitExceeded:(i="Rate Limit Exceeded",f)=>D(429,i,f),maintenance:(i="Service Under Maintenance",f)=>D(503,i,f),custom:(i,f,l)=>D(i,f,l)}});B();B();export{Ri as route,b as createResponse,C as APIError};
|
package/dist/types/index.d.ts
CHANGED
|
@@ -59,26 +59,13 @@ export interface VectorConfig<TTypes extends VectorTypes = DefaultVectorTypes> {
|
|
|
59
59
|
autoDiscover?: boolean;
|
|
60
60
|
}
|
|
61
61
|
export interface VectorConfigSchema<TTypes extends VectorTypes = DefaultVectorTypes> {
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
};
|
|
68
|
-
routes?: {
|
|
69
|
-
dir?: string;
|
|
70
|
-
autoDiscover?: boolean;
|
|
71
|
-
};
|
|
72
|
-
middleware?: {
|
|
73
|
-
before?: string[];
|
|
74
|
-
after?: string[];
|
|
75
|
-
};
|
|
62
|
+
port?: number;
|
|
63
|
+
hostname?: string;
|
|
64
|
+
reusePort?: boolean;
|
|
65
|
+
development?: boolean;
|
|
66
|
+
routesDir?: string;
|
|
76
67
|
before?: BeforeMiddlewareHandler<TTypes>[];
|
|
77
68
|
after?: AfterMiddlewareHandler<TTypes>[];
|
|
78
|
-
handlers?: {
|
|
79
|
-
auth?: string;
|
|
80
|
-
cache?: string;
|
|
81
|
-
};
|
|
82
69
|
auth?: ProtectedHandler<TTypes>;
|
|
83
70
|
cache?: CacheHandler;
|
|
84
71
|
cors?: CorsOptions | boolean;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAG5C,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IACvB,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC;CACpB;AAID,MAAM,WAAW,WAAW;IAC1B,IAAI,CAAC,EAAE,GAAG,CAAC;IACX,OAAO,CAAC,EAAE,GAAG,CAAC;IACd,KAAK,CAAC,EAAE,GAAG,CAAC;IACZ,QAAQ,CAAC,EAAE,GAAG,CAAC;CAChB;AAGD,MAAM,WAAW,kBAAmB,SAAQ,WAAW;IACrD,IAAI,EAAE,eAAe,CAAC;IACtB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC7B,KAAK,EAAE,GAAG,CAAC;IACX,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;CAC/B;AAGD,MAAM,MAAM,WAAW,CAAC,CAAC,SAAS,WAAW,IAAI,CAAC,CAAC,MAAM,CAAC,SAAS,SAAS,GACxE,eAAe,GACf,CAAC,CAAC,MAAM,CAAC,CAAC;AAEd,MAAM,MAAM,cAAc,CAAC,CAAC,SAAS,WAAW,IAAI,CAAC,CAAC,SAAS,CAAC,SAAS,SAAS,GAC9E,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GACnB,CAAC,CAAC,SAAS,CAAC,CAAC;AAEjB,MAAM,MAAM,YAAY,CAAC,CAAC,SAAS,WAAW,IAAI,CAAC,CAAC,OAAO,CAAC,SAAS,SAAS,GAAG,GAAG,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC;AAElG,MAAM,MAAM,eAAe,CAAC,CAAC,SAAS,WAAW,IAAI,CAAC,CAAC,UAAU,CAAC,SAAS,SAAS,GAChF,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GACnB,CAAC,CAAC,UAAU,CAAC,CAAC;AAGlB,MAAM,MAAM,QAAQ,GAAG,eAAe,CAAC;AAEvC,MAAM,WAAW,aAAa,CAAC,MAAM,SAAS,WAAW,GAAG,kBAAkB,CAC5E,SAAQ,IAAI,CAAC,QAAQ,EAAE,QAAQ,CAAC;IAChC,QAAQ,CAAC,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IAC/B,OAAO,EAAE,cAAc,CAAC,MAAM,CAAC,CAAC;IAChC,QAAQ,CAAC,EAAE,eAAe,CAAC,MAAM,CAAC,CAAC;IACnC,OAAO,CAAC,EAAE,GAAG,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC;CACpB;AAED,MAAM,WAAW,YAAY;IAC3B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,YAAY,CAAC,MAAM,SAAS,WAAW,GAAG,kBAAkB;IAC3E,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,YAAY,GAAG,MAAM,CAAC;IAC9B,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,EAAE,eAAe,CAAC,MAAM,CAAC,CAAC;CACpC;AAGD,MAAM,WAAW,YAAY,CAAC,MAAM,SAAS,WAAW,GAAG,kBAAkB;IAC3E,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,IAAI,CAAC,EAAE,WAAW,CAAC;IACnB,MAAM,CAAC,EAAE,uBAAuB,CAAC,MAAM,CAAC,EAAE,CAAC;IAC3C,OAAO,CAAC,EAAE,sBAAsB,CAAC,MAAM,CAAC,EAAE,CAAC;IAC3C,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB;AAGD,MAAM,WAAW,kBAAkB,CAAC,MAAM,SAAS,WAAW,GAAG,kBAAkB;IAEjF,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;IAGnB,MAAM,CAAC,EAAE,uBAAuB,CAAC,MAAM,CAAC,EAAE,CAAC;IAC3C,KAAK,CAAC,EAAE,sBAAsB,CAAC,MAAM,CAAC,EAAE,CAAC;IAGzC,IAAI,CAAC,EAAE,gBAAgB,CAAC,MAAM,CAAC,CAAC;IAChC,KAAK,CAAC,EAAE,YAAY,CAAC;IAGrB,IAAI,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC;IAG7B,KAAK,CAAC,EAAE,WAAW,CAAC;CACrB;AAED,MAAM,WAAW,WAAW;IAC1B,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,CAAC,CAAC,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC,CAAC;IAC3D,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,YAAY,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IACjC,YAAY,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IACjC,aAAa,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IAClC,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,MAAM,uBAAuB,CAAC,MAAM,SAAS,WAAW,GAAG,kBAAkB,IAAI,CACrF,OAAO,EAAE,aAAa,CAAC,MAAM,CAAC,KAC3B,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,GAAG,QAAQ,CAAC,GAAG,aAAa,CAAC,MAAM,CAAC,GAAG,QAAQ,CAAC;AAElF,MAAM,MAAM,sBAAsB,CAAC,MAAM,SAAS,WAAW,GAAG,kBAAkB,IAAI,CACpF,QAAQ,EAAE,QAAQ,EAClB,OAAO,EAAE,aAAa,CAAC,MAAM,CAAC,KAC3B,OAAO,CAAC,QAAQ,CAAC,GAAG,QAAQ,CAAC;AAClC,MAAM,MAAM,iBAAiB,GAAG,uBAAuB,GAAG,sBAAsB,CAAC;AAEjF,MAAM,MAAM,YAAY,CAAC,MAAM,SAAS,WAAW,GAAG,kBAAkB,IAAI,CAC1E,OAAO,EAAE,aAAa,CAAC,MAAM,CAAC,KAC3B,OAAO,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC;AAExB,MAAM,MAAM,gBAAgB,CAAC,MAAM,SAAS,WAAW,GAAG,kBAAkB,IAAI,CAC9E,OAAO,EAAE,aAAa,CAAC,MAAM,CAAC,KAC3B,OAAO,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC;AAExD,MAAM,MAAM,YAAY,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,OAAO,CAAC,GAAG,CAAC,EAAE,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,GAAG,CAAC,CAAC;AAEnG,MAAM,WAAW,eAAe,CAAC,MAAM,SAAS,WAAW,GAAG,kBAAkB;IAC9E,OAAO,EAAE,YAAY,CAAC,MAAM,CAAC,CAAC;IAC9B,OAAO,EAAE,YAAY,CAAC,MAAM,CAAC,CAAC;CAC/B;AAED,MAAM,WAAW,cAAc,CAAC,MAAM,SAAS,WAAW,GAAG,kBAAkB;IAC7E,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,YAAY,CAAC,MAAM,CAAC,CAAC;CAC/B"}
|
package/package.json
CHANGED
package/src/cli/index.ts
CHANGED
|
@@ -6,7 +6,8 @@ import { getVectorInstance } from "../core/vector";
|
|
|
6
6
|
import { ConfigLoader } from "../core/config-loader";
|
|
7
7
|
|
|
8
8
|
// Compatibility layer for both Node and Bun
|
|
9
|
-
const args =
|
|
9
|
+
const args =
|
|
10
|
+
typeof Bun !== "undefined" ? Bun.argv.slice(2) : process.argv.slice(2);
|
|
10
11
|
|
|
11
12
|
const { values, positionals } = parseArgs({
|
|
12
13
|
args,
|
|
@@ -63,8 +64,8 @@ async function runDev() {
|
|
|
63
64
|
config.port = config.port ?? Number.parseInt(values.port as string);
|
|
64
65
|
config.hostname = config.hostname ?? (values.host as string);
|
|
65
66
|
config.routesDir = config.routesDir ?? (values.routes as string);
|
|
66
|
-
config.development = isDev;
|
|
67
|
-
config.autoDiscover = true;
|
|
67
|
+
config.development = config.development ?? isDev;
|
|
68
|
+
config.autoDiscover = true; // Always auto-discover routes
|
|
68
69
|
|
|
69
70
|
// Apply CLI CORS option if not set in config
|
|
70
71
|
if (!config.cors && values.cors) {
|
|
@@ -101,16 +102,20 @@ async function runDev() {
|
|
|
101
102
|
const cyan = "\x1b[36m";
|
|
102
103
|
const green = "\x1b[32m";
|
|
103
104
|
|
|
104
|
-
console.log(
|
|
105
|
+
console.log(
|
|
106
|
+
` ${gray}Config${reset} ${
|
|
107
|
+
configSource === "user" ? "User config loaded" : "Using defaults"
|
|
108
|
+
}`
|
|
109
|
+
);
|
|
105
110
|
console.log(` ${gray}Routes${reset} ${config.routesDir}`);
|
|
106
111
|
if (isDev && values.watch) {
|
|
107
112
|
console.log(` ${gray}Watching${reset} All project files`);
|
|
108
113
|
}
|
|
109
114
|
console.log(
|
|
110
|
-
` ${gray}CORS${reset} ${
|
|
115
|
+
` ${gray}CORS${reset} ${config.cors ? "Enabled" : "Disabled"}`
|
|
111
116
|
);
|
|
112
117
|
console.log(
|
|
113
|
-
` ${gray}Mode${reset} ${
|
|
118
|
+
` ${gray}Mode${reset} ${config.development ? "Development" : "Production"}\n`
|
|
114
119
|
);
|
|
115
120
|
console.log(
|
|
116
121
|
` ${green}Ready${reset} → ${cyan}http://${config.hostname}:${config.port}${reset}\n`
|
|
@@ -132,31 +137,53 @@ async function runDev() {
|
|
|
132
137
|
if (isDev && values.watch) {
|
|
133
138
|
try {
|
|
134
139
|
let reloadTimeout: any = null;
|
|
140
|
+
let isReloading = false;
|
|
141
|
+
const changedFiles = new Set<string>();
|
|
142
|
+
let lastReloadTime = 0;
|
|
135
143
|
|
|
136
144
|
// Watch entire project directory for changes
|
|
137
145
|
watch(process.cwd(), { recursive: true }, async (_, filename) => {
|
|
146
|
+
// Skip if already reloading or if it's too soon after last reload
|
|
147
|
+
const now = Date.now();
|
|
148
|
+
if (isReloading || now - lastReloadTime < 1000) return;
|
|
149
|
+
|
|
138
150
|
if (
|
|
139
151
|
filename &&
|
|
140
152
|
(filename.endsWith(".ts") ||
|
|
141
153
|
filename.endsWith(".js") ||
|
|
142
154
|
filename.endsWith(".json")) &&
|
|
143
155
|
!filename.includes("node_modules") &&
|
|
144
|
-
!filename.includes(".git")
|
|
156
|
+
!filename.includes(".git") &&
|
|
157
|
+
!filename.includes(".vector") && // Ignore generated files
|
|
158
|
+
!filename.includes("dist") && // Ignore dist folder
|
|
159
|
+
!filename.includes("bun.lockb") && // Ignore lock files
|
|
160
|
+
!filename.endsWith(".generated.ts") // Ignore generated files
|
|
145
161
|
) {
|
|
162
|
+
// Track changed files
|
|
163
|
+
changedFiles.add(filename);
|
|
164
|
+
|
|
146
165
|
// Debounce reload to avoid multiple restarts
|
|
147
166
|
if (reloadTimeout) {
|
|
148
167
|
clearTimeout(reloadTimeout);
|
|
149
168
|
}
|
|
150
169
|
|
|
151
170
|
reloadTimeout = setTimeout(async () => {
|
|
152
|
-
|
|
153
|
-
|
|
171
|
+
if (isReloading || changedFiles.size === 0) return;
|
|
172
|
+
|
|
173
|
+
isReloading = true;
|
|
174
|
+
lastReloadTime = Date.now();
|
|
175
|
+
|
|
176
|
+
// Clear changed files
|
|
177
|
+
changedFiles.clear();
|
|
154
178
|
|
|
155
179
|
// Stop the current server
|
|
156
180
|
if (vector) {
|
|
157
181
|
vector.stop();
|
|
158
182
|
}
|
|
159
183
|
|
|
184
|
+
// Small delay to ensure file system operations complete
|
|
185
|
+
await new Promise((resolve) => setTimeout(resolve, 100));
|
|
186
|
+
|
|
160
187
|
// Clear module cache to ensure fresh imports
|
|
161
188
|
for (const key in require.cache) {
|
|
162
189
|
if (!key.includes("node_modules")) {
|
|
@@ -168,10 +195,16 @@ async function runDev() {
|
|
|
168
195
|
try {
|
|
169
196
|
const result = await startServer();
|
|
170
197
|
server = result.server;
|
|
198
|
+
vector = result.vector;
|
|
171
199
|
} catch (error) {
|
|
172
200
|
console.error(" ❌ Failed to reload server:", error);
|
|
201
|
+
} finally {
|
|
202
|
+
// Reset flag after a delay
|
|
203
|
+
setTimeout(() => {
|
|
204
|
+
isReloading = false;
|
|
205
|
+
}, 2000); // 2 second cooldown
|
|
173
206
|
}
|
|
174
|
-
},
|
|
207
|
+
}, 500); // Increased debounce to 500ms
|
|
175
208
|
}
|
|
176
209
|
});
|
|
177
210
|
} catch (err) {
|
|
@@ -200,7 +233,7 @@ async function runBuild() {
|
|
|
200
233
|
console.log(` Generated ${routes.length} routes`);
|
|
201
234
|
|
|
202
235
|
// Use spawn based on runtime
|
|
203
|
-
if (typeof Bun !==
|
|
236
|
+
if (typeof Bun !== "undefined") {
|
|
204
237
|
const buildProcess = Bun.spawn([
|
|
205
238
|
"bun",
|
|
206
239
|
"build",
|
|
@@ -212,11 +245,15 @@ async function runBuild() {
|
|
|
212
245
|
await buildProcess.exited;
|
|
213
246
|
} else {
|
|
214
247
|
// For Node.js, use child_process
|
|
215
|
-
const { spawnSync } = await import(
|
|
216
|
-
spawnSync(
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
248
|
+
const { spawnSync } = await import("child_process");
|
|
249
|
+
spawnSync(
|
|
250
|
+
"bun",
|
|
251
|
+
["build", "src/index.ts", "--outdir", "dist", "--minify"],
|
|
252
|
+
{
|
|
253
|
+
stdio: "inherit",
|
|
254
|
+
shell: true,
|
|
255
|
+
}
|
|
256
|
+
);
|
|
220
257
|
}
|
|
221
258
|
|
|
222
259
|
console.log("\n ✓ Build complete\n");
|
|
@@ -1,9 +1,7 @@
|
|
|
1
|
-
import { existsSync } from
|
|
2
|
-
import { resolve } from
|
|
3
|
-
import { toFileUrl } from
|
|
1
|
+
import { existsSync } from "node:fs";
|
|
2
|
+
import { resolve } from "node:path";
|
|
3
|
+
import { toFileUrl } from "../utils/path";
|
|
4
4
|
import type {
|
|
5
|
-
AfterMiddlewareHandler,
|
|
6
|
-
BeforeMiddlewareHandler,
|
|
7
5
|
CacheHandler,
|
|
8
6
|
CorsOptions,
|
|
9
7
|
DefaultVectorTypes,
|
|
@@ -11,14 +9,14 @@ import type {
|
|
|
11
9
|
VectorConfig,
|
|
12
10
|
VectorConfigSchema,
|
|
13
11
|
VectorTypes,
|
|
14
|
-
} from
|
|
12
|
+
} from "../types";
|
|
15
13
|
|
|
16
14
|
export class ConfigLoader<TTypes extends VectorTypes = DefaultVectorTypes> {
|
|
17
15
|
private configPath: string;
|
|
18
16
|
private config: VectorConfigSchema<TTypes> | null = null;
|
|
19
|
-
private configSource:
|
|
17
|
+
private configSource: "user" | "default" = "default";
|
|
20
18
|
|
|
21
|
-
constructor(configPath =
|
|
19
|
+
constructor(configPath = "vector.config.ts") {
|
|
22
20
|
// Always resolve from the current working directory (user's project)
|
|
23
21
|
this.configPath = resolve(process.cwd(), configPath);
|
|
24
22
|
}
|
|
@@ -28,69 +26,62 @@ export class ConfigLoader<TTypes extends VectorTypes = DefaultVectorTypes> {
|
|
|
28
26
|
if (existsSync(this.configPath)) {
|
|
29
27
|
try {
|
|
30
28
|
console.log(`→ Loading config from: ${this.configPath}`);
|
|
31
|
-
|
|
29
|
+
|
|
32
30
|
// Use explicit file:// URL to ensure correct resolution
|
|
33
31
|
const userConfigPath = toFileUrl(this.configPath);
|
|
34
32
|
const userConfig = await import(userConfigPath);
|
|
35
33
|
this.config = userConfig.default || userConfig;
|
|
36
|
-
this.configSource =
|
|
37
|
-
|
|
38
|
-
console.log(
|
|
34
|
+
this.configSource = "user";
|
|
35
|
+
|
|
36
|
+
console.log(" ✓ User config loaded successfully");
|
|
39
37
|
} catch (error) {
|
|
40
|
-
console.error(
|
|
41
|
-
|
|
38
|
+
console.error(
|
|
39
|
+
` ✗ Failed to load config from ${this.configPath}:`,
|
|
40
|
+
error
|
|
41
|
+
);
|
|
42
|
+
console.log(" → Using default configuration");
|
|
42
43
|
this.config = {};
|
|
43
44
|
}
|
|
44
45
|
} else {
|
|
45
46
|
// Config file doesn't exist, use defaults
|
|
46
47
|
console.log(` → No config file found at: ${this.configPath}`);
|
|
47
|
-
console.log(
|
|
48
|
+
console.log(" → Using default configuration");
|
|
48
49
|
this.config = {};
|
|
49
50
|
}
|
|
50
51
|
|
|
51
52
|
// Convert new config schema to legacy VectorConfig format
|
|
52
53
|
return await this.buildLegacyConfig();
|
|
53
54
|
}
|
|
54
|
-
|
|
55
|
-
getConfigSource():
|
|
55
|
+
|
|
56
|
+
getConfigSource(): "user" | "default" {
|
|
56
57
|
return this.configSource;
|
|
57
58
|
}
|
|
58
59
|
|
|
59
60
|
private async buildLegacyConfig(): Promise<VectorConfig<TTypes>> {
|
|
60
61
|
const config: VectorConfig<TTypes> = {};
|
|
61
62
|
|
|
62
|
-
//
|
|
63
|
-
if (this.config
|
|
64
|
-
config.port = this.config.
|
|
65
|
-
config.hostname = this.config.
|
|
66
|
-
config.reusePort = this.config.
|
|
67
|
-
config.development = this.config.
|
|
63
|
+
// Direct mapping - schemas are now the same (flat)
|
|
64
|
+
if (this.config) {
|
|
65
|
+
config.port = this.config.port;
|
|
66
|
+
config.hostname = this.config.hostname;
|
|
67
|
+
config.reusePort = this.config.reusePort;
|
|
68
|
+
config.development = this.config.development;
|
|
69
|
+
config.routesDir = this.config.routesDir || "./routes";
|
|
68
70
|
}
|
|
69
71
|
|
|
70
|
-
//
|
|
71
|
-
|
|
72
|
-
// New format: { routes: { dir: string } }
|
|
73
|
-
config.routesDir = this.config.routes.dir || './routes';
|
|
74
|
-
config.autoDiscover = this.config.routes.autoDiscover !== false;
|
|
75
|
-
} else if ((this.config as any)?.routesDir) {
|
|
76
|
-
// Legacy format: { routesDir: string }
|
|
77
|
-
config.routesDir = (this.config as any).routesDir;
|
|
78
|
-
config.autoDiscover = (this.config as any).autoDiscover !== false;
|
|
79
|
-
} else {
|
|
80
|
-
config.routesDir = './routes';
|
|
81
|
-
config.autoDiscover = true;
|
|
82
|
-
}
|
|
72
|
+
// Always auto-discover routes
|
|
73
|
+
config.autoDiscover = true;
|
|
83
74
|
|
|
84
75
|
// CORS configuration
|
|
85
76
|
if (this.config?.cors) {
|
|
86
|
-
if (typeof this.config.cors ===
|
|
77
|
+
if (typeof this.config.cors === "boolean") {
|
|
87
78
|
config.cors = this.config.cors
|
|
88
79
|
? {
|
|
89
|
-
origin:
|
|
80
|
+
origin: "*",
|
|
90
81
|
credentials: true,
|
|
91
|
-
allowHeaders:
|
|
92
|
-
allowMethods:
|
|
93
|
-
exposeHeaders:
|
|
82
|
+
allowHeaders: "Content-Type, Authorization",
|
|
83
|
+
allowMethods: "GET, POST, PUT, PATCH, DELETE, OPTIONS",
|
|
84
|
+
exposeHeaders: "Authorization",
|
|
94
85
|
maxAge: 86400,
|
|
95
86
|
}
|
|
96
87
|
: undefined;
|
|
@@ -99,120 +90,27 @@ export class ConfigLoader<TTypes extends VectorTypes = DefaultVectorTypes> {
|
|
|
99
90
|
}
|
|
100
91
|
}
|
|
101
92
|
|
|
102
|
-
//
|
|
93
|
+
// Middleware mapping (VectorConfig uses 'finally' instead of 'after')
|
|
103
94
|
if (this.config?.before) {
|
|
104
|
-
// Direct functions provided
|
|
105
|
-
console.log('Using direct before middleware functions:', this.config.before.length);
|
|
106
95
|
config.before = this.config.before;
|
|
107
|
-
} else if (this.config?.middleware?.before) {
|
|
108
|
-
// File paths provided (legacy)
|
|
109
|
-
console.log('Loading before middleware from file paths:', this.config.middleware.before);
|
|
110
|
-
config.before = await this.loadMiddleware<BeforeMiddlewareHandler<TTypes>>(
|
|
111
|
-
this.config.middleware.before
|
|
112
|
-
);
|
|
113
|
-
console.log('Loaded before middleware:', config.before?.length);
|
|
114
96
|
}
|
|
115
97
|
|
|
116
98
|
if (this.config?.after) {
|
|
117
|
-
// Direct functions provided
|
|
118
|
-
console.log('Using direct after middleware functions:', this.config.after.length);
|
|
119
99
|
config.finally = this.config.after;
|
|
120
|
-
} else if (this.config?.middleware?.after) {
|
|
121
|
-
// File paths provided (legacy)
|
|
122
|
-
console.log('Loading after middleware from file paths:', this.config.middleware.after);
|
|
123
|
-
config.finally = await this.loadMiddleware<AfterMiddlewareHandler<TTypes>>(
|
|
124
|
-
this.config.middleware.after
|
|
125
|
-
);
|
|
126
|
-
console.log('Loaded after middleware:', config.finally?.length);
|
|
127
100
|
}
|
|
128
101
|
|
|
129
102
|
return config;
|
|
130
103
|
}
|
|
131
104
|
|
|
132
|
-
private async loadMiddleware<T>(paths: string[]): Promise<T[]> {
|
|
133
|
-
const middleware: T[] = [];
|
|
134
|
-
|
|
135
|
-
for (const path of paths) {
|
|
136
|
-
try {
|
|
137
|
-
const modulePath = resolve(process.cwd(), path);
|
|
138
|
-
const importPath = toFileUrl(modulePath);
|
|
139
|
-
const module = await import(importPath);
|
|
140
|
-
const handler = module.default || module;
|
|
141
|
-
|
|
142
|
-
if (typeof handler === 'function') {
|
|
143
|
-
middleware.push(handler as T);
|
|
144
|
-
} else {
|
|
145
|
-
console.warn(`Middleware at ${path} does not export a function`);
|
|
146
|
-
}
|
|
147
|
-
} catch (error) {
|
|
148
|
-
console.error(`Failed to load middleware from ${path}:`, error);
|
|
149
|
-
}
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
return middleware;
|
|
153
|
-
}
|
|
154
|
-
|
|
155
105
|
async loadAuthHandler(): Promise<ProtectedHandler<TTypes> | null> {
|
|
156
|
-
|
|
157
|
-
if (this.config?.auth) {
|
|
158
|
-
console.log('Using direct auth handler function');
|
|
159
|
-
return this.config.auth;
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
// File path provided (legacy)
|
|
163
|
-
if (!this.config?.handlers?.auth) {
|
|
164
|
-
return null;
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
try {
|
|
168
|
-
const modulePath = resolve(process.cwd(), this.config.handlers.auth);
|
|
169
|
-
const importPath = toFileUrl(modulePath);
|
|
170
|
-
const module = await import(importPath);
|
|
171
|
-
const handler = module.default || module;
|
|
172
|
-
|
|
173
|
-
if (typeof handler === 'function') {
|
|
174
|
-
return handler as ProtectedHandler<TTypes>;
|
|
175
|
-
} else {
|
|
176
|
-
console.warn(`Auth handler at ${this.config.handlers.auth} does not export a function`);
|
|
177
|
-
return null;
|
|
178
|
-
}
|
|
179
|
-
} catch (error) {
|
|
180
|
-
console.error(`Failed to load auth handler from ${this.config.handlers.auth}:`, error);
|
|
181
|
-
return null;
|
|
182
|
-
}
|
|
106
|
+
return this.config?.auth || null;
|
|
183
107
|
}
|
|
184
108
|
|
|
185
109
|
async loadCacheHandler(): Promise<CacheHandler | null> {
|
|
186
|
-
|
|
187
|
-
if (this.config?.cache) {
|
|
188
|
-
console.log('Using direct cache handler function');
|
|
189
|
-
return this.config.cache;
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
// File path provided (legacy)
|
|
193
|
-
if (!this.config?.handlers?.cache) {
|
|
194
|
-
return null;
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
try {
|
|
198
|
-
const modulePath = resolve(process.cwd(), this.config.handlers.cache);
|
|
199
|
-
const importPath = toFileUrl(modulePath);
|
|
200
|
-
const module = await import(importPath);
|
|
201
|
-
const handler = module.default || module;
|
|
202
|
-
|
|
203
|
-
if (typeof handler === 'function') {
|
|
204
|
-
return handler as CacheHandler;
|
|
205
|
-
} else {
|
|
206
|
-
console.warn(`Cache handler at ${this.config.handlers.cache} does not export a function`);
|
|
207
|
-
return null;
|
|
208
|
-
}
|
|
209
|
-
} catch (error) {
|
|
210
|
-
console.error(`Failed to load cache handler from ${this.config.handlers.cache}:`, error);
|
|
211
|
-
return null;
|
|
212
|
-
}
|
|
110
|
+
return this.config?.cache || null;
|
|
213
111
|
}
|
|
214
112
|
|
|
215
113
|
getConfig(): VectorConfigSchema<TTypes> | null {
|
|
216
114
|
return this.config;
|
|
217
115
|
}
|
|
218
|
-
}
|
|
116
|
+
}
|