vector-framework 1.2.0 → 1.2.1
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 +19 -0
- package/dist/auth/protected.d.ts +1 -0
- package/dist/auth/protected.d.ts.map +1 -1
- package/dist/auth/protected.js +3 -0
- package/dist/auth/protected.js.map +1 -1
- package/dist/cache/manager.d.ts +1 -0
- package/dist/cache/manager.d.ts.map +1 -1
- package/dist/cache/manager.js +3 -0
- package/dist/cache/manager.js.map +1 -1
- package/dist/cli/graceful-shutdown.d.ts +15 -0
- package/dist/cli/graceful-shutdown.d.ts.map +1 -0
- package/dist/cli/graceful-shutdown.js +42 -0
- package/dist/cli/graceful-shutdown.js.map +1 -0
- package/dist/cli/index.js +37 -43
- package/dist/cli/index.js.map +1 -1
- package/dist/cli.js +877 -218
- package/dist/core/config-loader.d.ts.map +1 -1
- package/dist/core/config-loader.js +5 -2
- package/dist/core/config-loader.js.map +1 -1
- package/dist/core/server.d.ts +3 -0
- package/dist/core/server.d.ts.map +1 -1
- package/dist/core/server.js +227 -7
- package/dist/core/server.js.map +1 -1
- package/dist/core/vector.d.ts +4 -2
- package/dist/core/vector.d.ts.map +1 -1
- package/dist/core/vector.js +32 -2
- package/dist/core/vector.js.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +147 -41
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +147 -41
- package/dist/openapi/docs-ui.d.ts +1 -1
- package/dist/openapi/docs-ui.d.ts.map +1 -1
- package/dist/openapi/docs-ui.js +147 -35
- package/dist/openapi/docs-ui.js.map +1 -1
- package/dist/openapi/generator.d.ts.map +1 -1
- package/dist/openapi/generator.js +233 -4
- package/dist/openapi/generator.js.map +1 -1
- package/dist/start-vector.d.ts +3 -0
- package/dist/start-vector.d.ts.map +1 -0
- package/dist/start-vector.js +38 -0
- package/dist/start-vector.js.map +1 -0
- package/dist/types/index.d.ts +25 -0
- package/dist/types/index.d.ts.map +1 -1
- package/dist/utils/logger.js +1 -1
- package/dist/utils/validation.d.ts.map +1 -1
- package/dist/utils/validation.js +2 -0
- package/dist/utils/validation.js.map +1 -1
- package/package.json +3 -1
- package/src/auth/protected.ts +4 -0
- package/src/cache/manager.ts +4 -0
- package/src/cli/graceful-shutdown.ts +60 -0
- package/src/cli/index.ts +42 -49
- package/src/core/config-loader.ts +5 -2
- package/src/core/server.ts +289 -7
- package/src/core/vector.ts +38 -4
- package/src/index.ts +4 -3
- package/src/openapi/assets/favicon/android-chrome-192x192.png +0 -0
- package/src/openapi/assets/favicon/android-chrome-512x512.png +0 -0
- package/src/openapi/assets/favicon/apple-touch-icon.png +0 -0
- package/src/openapi/assets/favicon/favicon-16x16.png +0 -0
- package/src/openapi/assets/favicon/favicon-32x32.png +0 -0
- package/src/openapi/assets/favicon/favicon.ico +0 -0
- package/src/openapi/assets/favicon/site.webmanifest +11 -0
- package/src/openapi/assets/logo.svg +12 -0
- package/src/openapi/assets/logo_dark.svg +6 -0
- package/src/openapi/assets/logo_icon.png +0 -0
- package/src/openapi/assets/logo_white.svg +6 -0
- package/src/openapi/docs-ui.ts +153 -35
- package/src/openapi/generator.ts +231 -4
- package/src/start-vector.ts +50 -0
- package/src/types/index.ts +34 -0
- package/src/utils/logger.ts +1 -1
- package/src/utils/validation.ts +2 -0
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
var{defineProperty
|
|
1
|
+
var{defineProperty:$,getOwnPropertyNames:Re,getOwnPropertyDescriptor:Ue}=Object,_e=Object.prototype.hasOwnProperty;var se=new WeakMap,$e=(e)=>{var t=se.get(e),n;if(t)return t;if(t=$({},"__esModule",{value:!0}),e&&typeof e==="object"||typeof e==="function")Re(e).map((d)=>!_e.call(t,d)&&$(t,d,{get:()=>e[d],enumerable:!(n=Ue(e,d))||n.enumerable}));return se.set(e,t),t};var Je=(e,t)=>{for(var n in t)$(e,n,{get:t[n],enumerable:!0,configurable:!0,set:(d)=>t[n]=()=>d})};var Tt={};Je(Tt,{startVector:()=>Te,route:()=>Oe,createResponse:()=>I,APIError:()=>w});module.exports=$e(Tt);var E={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},D={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"};var T={NOT_FOUND:new Response(JSON.stringify({error:!0,message:"Not Found",statusCode:404}),{status:404,headers:{"content-type":"application/json"}})};class V{protectedHandler=null;setProtectedHandler(e){this.protectedHandler=e}clearProtectedHandler(){this.protectedHandler=null}async authenticate(e){if(!this.protectedHandler)throw new Error("Protected handler not configured. Use vector.protected() to set authentication handler.");try{let t=await this.protectedHandler(e);return e.authUser=t,t}catch(t){throw new Error(`Authentication failed: ${t instanceof Error?t.message:String(t)}`)}}isAuthenticated(e){return!!e.authUser}getUser(e){return e.authUser||null}}class F{cacheHandler=null;memoryCache=new Map;cleanupInterval=null;inflight=new Map;setCacheHandler(e){this.cacheHandler=e}clearCacheHandler(){this.cacheHandler=null}async get(e,t,n=D.CACHE_TTL){if(n<=0)return t();if(this.cacheHandler)return this.cacheHandler(e,t,n);return this.getFromMemoryCache(e,t,n)}async getFromMemoryCache(e,t,n){let d=Date.now(),r=this.memoryCache.get(e);if(this.isCacheValid(r,d))return r.value;if(this.inflight.has(e))return await this.inflight.get(e);let a=(async()=>{let i=await t();return this.setInMemoryCache(e,i,n),i})();this.inflight.set(e,a);try{return await a}finally{this.inflight.delete(e)}}isCacheValid(e,t){return e!==void 0&&e.expires>t}setInMemoryCache(e,t,n){let d=Date.now()+n*1000;this.memoryCache.set(e,{value:t,expires:d}),this.scheduleCleanup()}scheduleCleanup(){if(this.cleanupInterval)return;this.cleanupInterval=setInterval(()=>{this.cleanupExpired()},60000)}cleanupExpired(){let e=Date.now();for(let[t,n]of this.memoryCache.entries())if(n.expires<=e)this.memoryCache.delete(t);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(e,t,n=D.CACHE_TTL){if(n<=0)return;if(this.cacheHandler){await this.cacheHandler(e,async()=>t,n);return}this.setInMemoryCache(e,t,n)}delete(e){return this.memoryCache.delete(e)}has(e){let t=this.memoryCache.get(e);if(!t)return!1;if(t.expires<=Date.now())return this.memoryCache.delete(e),!1;return!0}generateKey(e,t){let n=e._parsedUrl??new URL(e.url),d=t?.authUser?.id!=null?String(t.authUser.id):"anonymous";return`${e.method}:${n.pathname}:${n.search}:${d}`}}var G=(()=>({}));function v(e){if(typeof e!=="string")throw new TypeError("Path must be a string. Received "+JSON.stringify(e))}function le(e,t){var n="",d=0,r=-1,a=0,i;for(var o=0;o<=e.length;++o){if(o<e.length)i=e.charCodeAt(o);else if(i===47)break;else i=47;if(i===47){if(r===o-1||a===1);else if(r!==o-1&&a===2){if(n.length<2||d!==2||n.charCodeAt(n.length-1)!==46||n.charCodeAt(n.length-2)!==46){if(n.length>2){var s=n.lastIndexOf("/");if(s!==n.length-1){if(s===-1)n="",d=0;else n=n.slice(0,s),d=n.length-1-n.lastIndexOf("/");r=o,a=0;continue}}else if(n.length===2||n.length===1){n="",d=0,r=o,a=0;continue}}if(t){if(n.length>0)n+="/..";else n="..";d=2}}else{if(n.length>0)n+="/"+e.slice(r+1,o);else n=e.slice(r+1,o);d=o-r-1}r=o,a=0}else if(i===46&&a!==-1)++a;else a=-1}return n}function Ve(e,t){var n=t.dir||t.root,d=t.base||(t.name||"")+(t.ext||"");if(!n)return d;if(n===t.root)return n+d;return n+e+d}function B(){var e="",t=!1,n;for(var d=arguments.length-1;d>=-1&&!t;d--){var r;if(d>=0)r=arguments[d];else{if(n===void 0)n=process.cwd();r=n}if(v(r),r.length===0)continue;e=r+"/"+e,t=r.charCodeAt(0)===47}if(e=le(e,!t),t)if(e.length>0)return"/"+e;else return"/";else if(e.length>0)return e;else return"."}function ce(e){if(v(e),e.length===0)return".";var t=e.charCodeAt(0)===47,n=e.charCodeAt(e.length-1)===47;if(e=le(e,!t),e.length===0&&!t)e=".";if(e.length>0&&n)e+="/";if(t)return"/"+e;return e}function z(e){return v(e),e.length>0&&e.charCodeAt(0)===47}function j(){if(arguments.length===0)return".";var e;for(var t=0;t<arguments.length;++t){var n=arguments[t];if(v(n),n.length>0)if(e===void 0)e=n;else e+="/"+n}if(e===void 0)return".";return ce(e)}function N(e,t){if(v(e),v(t),e===t)return"";if(e=B(e),t=B(t),e===t)return"";var n=1;for(;n<e.length;++n)if(e.charCodeAt(n)!==47)break;var d=e.length,r=d-n,a=1;for(;a<t.length;++a)if(t.charCodeAt(a)!==47)break;var i=t.length,o=i-a,s=r<o?r:o,c=-1,l=0;for(;l<=s;++l){if(l===s){if(o>s){if(t.charCodeAt(a+l)===47)return t.slice(a+l+1);else if(l===0)return t.slice(a+l)}else if(r>s){if(e.charCodeAt(n+l)===47)c=l;else if(l===0)c=0}break}var u=e.charCodeAt(n+l),m=t.charCodeAt(a+l);if(u!==m)break;else if(u===47)c=l}var h="";for(l=n+c+1;l<=d;++l)if(l===d||e.charCodeAt(l)===47)if(h.length===0)h+="..";else h+="/..";if(h.length>0)return h+t.slice(a+c);else{if(a+=c,t.charCodeAt(a)===47)++a;return t.slice(a)}}function Fe(e){return e}function S(e){if(v(e),e.length===0)return".";var t=e.charCodeAt(0),n=t===47,d=-1,r=!0;for(var a=e.length-1;a>=1;--a)if(t=e.charCodeAt(a),t===47){if(!r){d=a;break}}else r=!1;if(d===-1)return n?"/":".";if(n&&d===1)return"//";return e.slice(0,d)}function ze(e,t){if(t!==void 0&&typeof t!=="string")throw new TypeError('"ext" argument must be a string');v(e);var n=0,d=-1,r=!0,a;if(t!==void 0&&t.length>0&&t.length<=e.length){if(t.length===e.length&&t===e)return"";var i=t.length-1,o=-1;for(a=e.length-1;a>=0;--a){var s=e.charCodeAt(a);if(s===47){if(!r){n=a+1;break}}else{if(o===-1)r=!1,o=a+1;if(i>=0)if(s===t.charCodeAt(i)){if(--i===-1)d=a}else i=-1,d=o}}if(n===d)d=o;else if(d===-1)d=e.length;return e.slice(n,d)}else{for(a=e.length-1;a>=0;--a)if(e.charCodeAt(a)===47){if(!r){n=a+1;break}}else if(d===-1)r=!1,d=a+1;if(d===-1)return"";return e.slice(n,d)}}function Ge(e){v(e);var t=-1,n=0,d=-1,r=!0,a=0;for(var i=e.length-1;i>=0;--i){var o=e.charCodeAt(i);if(o===47){if(!r){n=i+1;break}continue}if(d===-1)r=!1,d=i+1;if(o===46){if(t===-1)t=i;else if(a!==1)a=1}else if(t!==-1)a=-1}if(t===-1||d===-1||a===0||a===1&&t===d-1&&t===n+1)return"";return e.slice(t,d)}function Qe(e){if(e===null||typeof e!=="object")throw new TypeError('The "pathObject" argument must be of type Object. Received type '+typeof e);return Ve("/",e)}function Ye(e){v(e);var t={root:"",dir:"",base:"",ext:"",name:""};if(e.length===0)return t;var n=e.charCodeAt(0),d=n===47,r;if(d)t.root="/",r=1;else r=0;var a=-1,i=0,o=-1,s=!0,c=e.length-1,l=0;for(;c>=r;--c){if(n=e.charCodeAt(c),n===47){if(!s){i=c+1;break}continue}if(o===-1)s=!1,o=c+1;if(n===46){if(a===-1)a=c;else if(l!==1)l=1}else if(a!==-1)l=-1}if(a===-1||o===-1||l===0||l===1&&a===o-1&&a===i+1){if(o!==-1)if(i===0&&d)t.base=t.name=e.slice(1,o);else t.base=t.name=e.slice(i,o)}else{if(i===0&&d)t.name=e.slice(1,a),t.base=e.slice(1,o);else t.name=e.slice(i,a),t.base=e.slice(i,o);t.ext=e.slice(a,o)}if(i>0)t.dir=e.slice(0,i-1);else if(d)t.dir="/";return t}var P="/",Xe=":",$t=((e)=>(e.posix=e,e))({resolve:B,normalize:ce,isAbsolute:z,join:j,relative:N,_makeLong:Fe,dirname:S,basename:ze,extname:Ge,format:Qe,parse:Ye,sep:P,delimiter:Xe,win32:null,posix:null});class Q{outputPath;constructor(e="./.vector/routes.generated.ts"){this.outputPath=e}async generate(e){let t=S(this.outputPath);await G.promises.mkdir(t,{recursive:!0});let n=[],d=new Map;for(let o of e){if(!d.has(o.path))d.set(o.path,[]);d.get(o.path).push(o)}let r=0,a=[];for(let[o,s]of d){let c=N(S(this.outputPath),o).replace(/\\/g,"/").replace(/\.(ts|js)$/,""),l=`route_${r++}`,u=s.filter((m)=>m.name!=="default").map((m)=>m.name);if(s.some((m)=>m.name==="default"))if(u.length>0)n.push(`import ${l}, { ${u.join(", ")} } from '${c}';`);else n.push(`import ${l} from '${c}';`);else if(u.length>0)n.push(`import { ${u.join(", ")} } from '${c}';`);for(let m of s){let h=m.name==="default"?l:m.name;a.push(` ${h},`)}}let i=`// This file is auto-generated. Do not edit manually.
|
|
2
2
|
// Generated at: ${new Date().toISOString()}
|
|
3
3
|
|
|
4
4
|
${n.join(`
|
|
@@ -10,7 +10,7 @@ ${a.join(`
|
|
|
10
10
|
];
|
|
11
11
|
|
|
12
12
|
export default routes;
|
|
13
|
-
`;await
|
|
13
|
+
`;await G.promises.writeFile(this.outputPath,i,"utf-8")}async generateDynamic(e){let t=[];for(let n of e){let d=JSON.stringify({method:n.method,path:n.options.path,options:n.options});t.push(` await import('${n.path}').then(m => ({
|
|
14
14
|
...${d},
|
|
15
15
|
handler: m.${n.name==="default"?"default":n.name}
|
|
16
16
|
}))`)}return`export const loadRoutes = async () => {
|
|
@@ -18,12 +18,16 @@ export default routes;
|
|
|
18
18
|
${t.join(`,
|
|
19
19
|
`)}
|
|
20
20
|
]);
|
|
21
|
-
};`}}var A=(()=>({}));class N{routesDir;excludePatterns;static DEFAULT_EXCLUDE_PATTERNS=["*.test.ts","*.test.js","*.test.tsx","*.test.jsx","*.spec.ts","*.spec.js","*.spec.tsx","*.spec.jsx","*.tests.ts","*.tests.js","**/__tests__/**","*.interface.ts","*.type.ts","*.d.ts"];constructor(e="./routes",t){this.routesDir=I(process.cwd(),e),this.excludePatterns=t||N.DEFAULT_EXCLUDE_PATTERNS}async scan(){let e=[];if(!A.existsSync(this.routesDir))return[];try{await this.scanDirectory(this.routesDir,e)}catch(t){if(t.code==="ENOENT")return console.warn(` ✗ Routes directory not accessible: ${this.routesDir}`),[];throw t}return e}isExcluded(e){let t=E(this.routesDir,e);for(let n of this.excludePatterns){let d=n.replace(/\./g,"\\.").replace(/\*\*/g,"__GLOBSTAR__").replace(/\*/g,"[^/]*").replace(/__GLOBSTAR__/g,".*").replace(/\?/g,"."),r=new RegExp(`^${d}$`),a=t.split(D).pop()||"";if(r.test(t)||r.test(a))return!0}return!1}async scanDirectory(e,t,n=""){let d=await A.promises.readdir(e);for(let r of d){let a=B(e,r);if((await A.promises.stat(a)).isDirectory()){let l=n?`${n}/${r}`:r;await this.scanDirectory(a,t,l)}else if(r.endsWith(".ts")||r.endsWith(".js")){if(this.isExcluded(a))continue;let l=E(this.routesDir,a).replace(/\.(ts|js)$/,"").split(D).join("/");try{let b=await import(process.platform==="win32"?`file:///${a.replace(/\\/g,"/")}`:a);if(b.default&&typeof b.default==="function")t.push({name:"default",path:a,method:"GET",options:{method:"GET",path:`/${l}`,expose:!0}});for(let[s,u]of Object.entries(b)){if(s==="default")continue;if(u&&typeof u==="object"&&"entry"in u&&"options"in u&&"handler"in u){let m=u;t.push({name:s,path:a,method:m.options.method,options:m.options})}else if(Array.isArray(u)&&u.length>=4){let[m,,,h]=u;t.push({name:s,path:a,method:m,options:{method:m,path:h,expose:!0}})}}}catch(i){console.error(`Failed to load route from ${a}:`,i)}}}}enableWatch(e){if(typeof Bun!=="undefined"&&Bun.env.NODE_ENV==="development")console.log(`Watching for route changes in ${this.routesDir}`),setInterval(async()=>{await e()},1000)}}class S{beforeHandlers=[];finallyHandlers=[];addBefore(...e){this.beforeHandlers.push(...e)}addFinally(...e){this.finallyHandlers.push(...e)}async executeBefore(e){if(this.beforeHandlers.length===0)return e;let t=e;for(let n of this.beforeHandlers){let d=await n(t);if(d instanceof Response)return d;t=d}return t}async executeFinally(e,t){if(this.finallyHandlers.length===0)return e;let n=e;for(let d of this.finallyHandlers)try{n=await d(n,t)}catch(r){console.error("After middleware error:",r)}return n}clone(){let e=new S;return e.beforeHandlers=[...this.beforeHandlers],e.finallyHandlers=[...this.finallyHandlers],e}clear(){this.beforeHandlers=[],this.finallyHandlers=[]}}function W(e){return process.platform==="win32"?`file:///${e.replace(/\\/g,"/")}`:e}function U(e){return RegExp(`^${e.replace(/\/+(\/|$)/g,"$1").replace(/(\/?\.?):(\w+)\+/g,"($1(?<$2>[\\s\\S]+))").replace(/(\/?\.?):(\w+)/g,"($1(?<$2>[^$1/]+?))").replace(/\./g,"\\.").replace(/(\/?)\*/g,"($1.*)?")}/*$`)}function K(e){let t=e?.["~standard"];return!!t&&typeof t==="object"&&typeof t.validate==="function"&&t.version===1}async function Z(e,t){let n=await e["~standard"].validate(t),d=n?.issues;if(Array.isArray(d)&&d.length>0)return{success:!1,issues:d};return{success:!0,value:n?.value}}function q(e){if(Array.isArray(e))return e;if(e&&typeof e==="object"&&Array.isArray(e.issues))return e.issues;if(e&&typeof e==="object"&&e.cause&&Array.isArray(e.cause.issues))return e.cause.issues;return null}function Be(e){if(!Array.isArray(e))return[];let t=[];for(let n=0;n<e.length;n++){let d=e[n],r=d;if(d&&typeof d==="object"&&"key"in d)r=d.key;if(typeof r==="string"||typeof r==="number")t.push(r);else if(typeof r==="symbol")t.push(String(r));else if(r!==void 0&&r!==null)t.push(String(r))}return t}function F(e,t){let n=[];for(let d=0;d<e.length;d++){let r=e[d],a=r,o={message:typeof a?.message==="string"&&a.message.length>0?a.message:"Invalid value",path:Be(a?.path)};if(typeof a?.code==="string")o.code=a.code;if(t)o.raw=r;n.push(o)}return n}function J(e,t){return{error:!0,message:"Validation failed",statusCode:422,source:"validation",target:e,issues:t,timestamp:new Date().toISOString()}}class L{middlewareManager;authManager;cacheManager;routeBooleanDefaults={};developmentMode=void 0;routeDefinitions=[];routeTable=Object.create(null);routeMatchers=[];corsHeadersEntries=null;corsHandler=null;constructor(e,t,n){this.middlewareManager=e,this.authManager=t,this.cacheManager=n}setCorsHeaders(e){this.corsHeadersEntries=e}setCorsHandler(e){this.corsHandler=e}setRouteBooleanDefaults(e){this.routeBooleanDefaults={...e}}setDevelopmentMode(e){this.developmentMode=e}applyRouteBooleanDefaults(e){let t={...e},n=this.routeBooleanDefaults,d=["auth","expose","rawRequest","validate","rawResponse"];for(let r of d)if(t[r]===void 0&&n[r]!==void 0)t[r]=n[r];return t}route(e,t){let n=this.applyRouteBooleanDefaults(e),d=n.method.toUpperCase(),r=n.path,a=this.wrapHandler(n,t),o=this.getOrCreateMethodMap(r);o[d]=a,this.routeDefinitions.push({method:d,path:r,options:n})}addRoute(e){let[t,,n,d]=e;if(!d)return;let r=this.getOrCreateMethodMap(d);r[t.toUpperCase()]=n[0];let a=t.toUpperCase();this.routeDefinitions.push({method:a,path:d,options:{method:a,path:d,expose:!0}})}bulkAddRoutes(e){for(let t of e)this.addRoute(t)}addStaticRoute(e,t){let n=this.routeTable[e];if(n&&!(n instanceof Response))throw new Error(`Cannot register static route for path "${e}" because method routes already exist.`);this.routeTable[e]=t,this.removeRouteMatcher(e)}getRouteTable(){return this.routeTable}getRoutes(){let e=[];for(let t of this.routeMatchers){let n=this.routeTable[t.path];if(!n||n instanceof Response)continue;for(let[d,r]of Object.entries(n))e.push([d,t.regex,[r],t.path])}return e}getRouteDefinitions(){return[...this.routeDefinitions]}clearRoutes(){this.routeTable=Object.create(null),this.routeMatchers=[],this.routeDefinitions=[]}sortRoutes(){}async handle(e){let t;try{t=new URL(e.url)}catch{return x.badRequest("Malformed request URL")}e._parsedUrl=t;let n=t.pathname;for(let d of this.routeMatchers){let r=d.path,a=this.routeTable[r];if(!a)continue;if(a instanceof Response)continue;let o=a;if(e.method==="OPTIONS"||e.method in o){let l=n.match(d.regex);if(l){try{e.params=l.groups??{}}catch{}let i=o[e.method]??o.GET;if(i){let b=await i(e);if(b)return b}}}}return C.NOT_FOUND.clone()}prepareRequest(e,t){if(!e.context)e.context={};let n=!!e.params&&typeof e.params==="object"&&!Array.isArray(e.params)&&Object.keys(e.params).length===0;if(t?.params!==void 0&&(e.params===void 0||n))try{e.params=t.params}catch{}if(t?.route!==void 0)e.route=t.route;if(t?.metadata!==void 0)e.metadata=t.metadata;if(e.query==null&&e.url)try{Object.defineProperty(e,"query",{get(){let d=this._parsedUrl??new URL(this.url),r=L.parseQuery(d);return Object.defineProperty(this,"query",{value:r,writable:!0,configurable:!0,enumerable:!0}),r},set(d){Object.defineProperty(this,"query",{value:d,writable:!0,configurable:!0,enumerable:!0})},configurable:!0,enumerable:!0})}catch{let d=e._parsedUrl??new URL(e.url);try{e.query=L.parseQuery(d)}catch{}}if(!Object.getOwnPropertyDescriptor(e,"cookies"))Object.defineProperty(e,"cookies",{get(){let d=this.headers.get("cookie")??"",r={};if(d)for(let a of d.split(";")){let o=a.indexOf("=");if(o>0)r[a.slice(0,o).trim()]=a.slice(o+1).trim()}return Object.defineProperty(this,"cookies",{value:r,writable:!0,configurable:!0,enumerable:!0}),r},configurable:!0,enumerable:!0})}resolveFallbackParams(e,t){if(!t)return;let n=e.params;if(n&&typeof n==="object"&&!Array.isArray(n)&&Object.keys(n).length>0)return;let d;try{d=(e._parsedUrl??new URL(e.url)).pathname}catch{return}let r=d.match(t);if(!r?.groups)return;return r.groups}wrapHandler(e,t){let n=e.path,d=n.includes(":")?U(n):null;return async(r)=>{let a=r,o=this.resolveFallbackParams(r,d);this.prepareRequest(a,{params:o,route:n,metadata:e.metadata});try{if(e.expose===!1)return x.forbidden("Forbidden");let l=await this.middlewareManager.executeBefore(a);if(l instanceof Response)return l;let i=l;if(e.auth)try{await this.authManager.authenticate(i)}catch(f){return x.unauthorized(f instanceof Error?f.message:"Authentication failed",e.responseContentType)}if(!e.rawRequest&&i.method!=="GET"&&i.method!=="HEAD"){let f=null;try{let p=i.headers.get("content-type");if(p?.startsWith("application/json"))f=await i.json();else if(p?.startsWith("application/x-www-form-urlencoded"))f=Object.fromEntries(await i.formData());else if(p?.startsWith("multipart/form-data"))f=await i.formData();else f=await i.text()}catch{f=null}this.setContentAndBodyAlias(i,f)}let b=await this.validateInputSchema(i,e);if(b)return b;let s,u=e.cache;if(u&&typeof u==="number"&&u>0){let f=this.cacheManager.generateKey(i,{authUser:i.authUser});s=await this.cacheManager.get(f,async()=>{let p=await t(i);if(p instanceof Response)return{_isResponse:!0,body:await p.text(),status:p.status,headers:Object.fromEntries(p.headers.entries())};return p},u)}else if(u&&typeof u==="object"&&u.ttl){let f=u.key||this.cacheManager.generateKey(i,{authUser:i.authUser});s=await this.cacheManager.get(f,async()=>{let p=await t(i);if(p instanceof Response)return{_isResponse:!0,body:await p.text(),status:p.status,headers:Object.fromEntries(p.headers.entries())};return p},u.ttl)}else s=await t(i);if(s&&typeof s==="object"&&s._isResponse===!0)s=new Response(s.body,{status:s.status,headers:s.headers});let m;if(e.rawResponse||s instanceof Response)m=s instanceof Response?s:new Response(s);else m=v(200,s,e.responseContentType);m=await this.middlewareManager.executeFinally(m,i);let h=this.corsHeadersEntries;if(h)for(let[f,p]of h)m.headers.set(f,p);else{let f=this.corsHandler;if(f)m=f(m,i)}return m}catch(l){if(l instanceof Response)return l;return console.error("Route handler error:",l),x.internalServerError(l instanceof Error?l.message:String(l),e.responseContentType)}}}isDevelopmentMode(){if(this.developmentMode!==void 0)return this.developmentMode;return(typeof Bun!=="undefined"?Bun.env.NODE_ENV:"development")!=="production"}async buildInputValidationPayload(e,t){let n=e.content;if(t.rawRequest&&e.method!=="GET"&&e.method!=="HEAD")try{n=await e.clone().text()}catch{n=null}return{params:e.params??{},query:e.query??{},headers:Object.fromEntries(e.headers.entries()),cookies:e.cookies??{},body:n}}applyValidatedInput(e,t){if(e.validatedInput=t,!t||typeof t!=="object")return;let n=t;if("params"in n)try{e.params=n.params}catch{}if("query"in n)try{e.query=n.query}catch{}if("cookies"in n)try{e.cookies=n.cookies}catch{}if("body"in n)this.setContentAndBodyAlias(e,n.body)}setContentAndBodyAlias(e,t){try{e.content=t}catch{return}this.setBodyAlias(e,t)}setBodyAlias(e,t){try{e.body=t}catch{}}async validateInputSchema(e,t){let n=t.schema?.input;if(!n)return null;if(t.validate===!1)return null;if(!K(n))return x.internalServerError("Invalid route schema configuration",t.responseContentType);let d=this.isDevelopmentMode(),r=await this.buildInputValidationPayload(e,t);try{let a=await Z(n,r);if(a.success===!1){let o=F(a.issues,d);return v(422,J("input",o),t.responseContentType)}return this.applyValidatedInput(e,a.value),null}catch(a){let o=q(a);if(o){let l=F(o,d);return v(422,J("input",l),t.responseContentType)}return x.internalServerError(a instanceof Error?a.message:"Validation failed",t.responseContentType)}}getOrCreateMethodMap(e){let t=this.routeTable[e];if(t instanceof Response)throw new Error(`Cannot register method route for path "${e}" because a static route already exists.`);if(t)return t;let n=Object.create(null);return this.routeTable[e]=n,this.addRouteMatcher(e),n}addRouteMatcher(e){if(this.routeMatchers.some((t)=>t.path===e))return;this.routeMatchers.push({path:e,regex:U(e),specificity:this.routeSpecificityScore(e)}),this.routeMatchers.sort((t,n)=>{if(t.specificity!==n.specificity)return n.specificity-t.specificity;return t.path.localeCompare(n.path)})}removeRouteMatcher(e){this.routeMatchers=this.routeMatchers.filter((t)=>t.path!==e)}static parseQuery(e){let t={};for(let[n,d]of e.searchParams)if(n in t){let r=t[n];if(Array.isArray(r))r.push(d);else t[n]=[r,d]}else t[n]=d;return t}routeSpecificityScore(e){let a=e.split("/").filter(Boolean),o=0;for(let l of a)if(l.includes("*"))o+=1;else if(l.startsWith(":"))o+=10;else o+=1000;if(o+=e.length,!e.includes(":")&&!e.includes("*"))o+=1e4;return o}}var V=(()=>({}));function ee(e,t){if(!e){if(typeof t.origin==="string"){if(t.origin==="*"&&t.credentials)return null;return t.origin}return null}if(typeof t.origin==="string"){if(t.origin==="*")return t.credentials?e:"*";return t.origin===e?e:null}if(Array.isArray(t.origin))return t.origin.includes(e)?e:null;if(typeof t.origin==="function")return t.origin(e)?e:null;return null}function te(e){return typeof e.origin==="string"&&e.origin==="*"&&e.credentials||Array.isArray(e.origin)||typeof e.origin==="function"}function ne(e,t,n){let d={};if(e){if(d["access-control-allow-origin"]=e,d["access-control-allow-methods"]=t.allowMethods,d["access-control-allow-headers"]=t.allowHeaders,d["access-control-expose-headers"]=t.exposeHeaders,d["access-control-max-age"]=String(t.maxAge),t.credentials)d["access-control-allow-credentials"]="true";if(n)d.vary="Origin"}return d}function Ae(e,t){if(!e)return t;let n=e.split(",").map((r)=>r.trim()).filter(Boolean);if(!n.map((r)=>r.toLowerCase()).includes(t.toLowerCase()))n.push(t);return n.join(", ")}function de(e){return{preflight(t){let n=t.headers.get("origin")??void 0,d=ee(n,e),r=Boolean(n&&d&&te(e));return new Response(null,{status:204,headers:ne(d,e,r)})},corsify(t,n){let d=n.headers.get("origin")??void 0,r=ee(d,e);if(!r)return t;let a=Boolean(d&&te(e)),o=ne(r,e,a);for(let[l,i]of Object.entries(o)){if(l==="vary"){t.headers.set("vary",Ae(t.headers.get("vary"),i));continue}t.headers.set(l,i)}return t}}}function re(e,t,n){let d=JSON.stringify(e).replace(/<\/script/gi,"<\\/script"),r=JSON.stringify(t);return`<!DOCTYPE html>
|
|
21
|
+
};`}}var M=(()=>({}));class R{routesDir;excludePatterns;static DEFAULT_EXCLUDE_PATTERNS=["*.test.ts","*.test.js","*.test.tsx","*.test.jsx","*.spec.ts","*.spec.js","*.spec.tsx","*.spec.jsx","*.tests.ts","*.tests.js","**/__tests__/**","*.interface.ts","*.type.ts","*.d.ts"];constructor(e="./routes",t){this.routesDir=B(process.cwd(),e),this.excludePatterns=t||R.DEFAULT_EXCLUDE_PATTERNS}async scan(){let e=[];if(!M.existsSync(this.routesDir))return[];try{await this.scanDirectory(this.routesDir,e)}catch(t){if(t.code==="ENOENT")return console.warn(` ✗ Routes directory not accessible: ${this.routesDir}`),[];throw t}return e}isExcluded(e){let t=N(this.routesDir,e);for(let n of this.excludePatterns){let d=n.replace(/\./g,"\\.").replace(/\*\*/g,"__GLOBSTAR__").replace(/\*/g,"[^/]*").replace(/__GLOBSTAR__/g,".*").replace(/\?/g,"."),r=new RegExp(`^${d}$`),a=t.split(P).pop()||"";if(r.test(t)||r.test(a))return!0}return!1}async scanDirectory(e,t,n=""){let d=await M.promises.readdir(e);for(let r of d){let a=j(e,r);if((await M.promises.stat(a)).isDirectory()){let o=n?`${n}/${r}`:r;await this.scanDirectory(a,t,o)}else if(r.endsWith(".ts")||r.endsWith(".js")){if(this.isExcluded(a))continue;let o=N(this.routesDir,a).replace(/\.(ts|js)$/,"").split(P).join("/");try{let c=await import(process.platform==="win32"?`file:///${a.replace(/\\/g,"/")}`:a);if(c.default&&typeof c.default==="function")t.push({name:"default",path:a,method:"GET",options:{method:"GET",path:`/${o}`,expose:!0}});for(let[l,u]of Object.entries(c)){if(l==="default")continue;if(u&&typeof u==="object"&&"entry"in u&&"options"in u&&"handler"in u){let m=u;t.push({name:l,path:a,method:m.options.method,options:m.options})}else if(Array.isArray(u)&&u.length>=4){let[m,,,h]=u;t.push({name:l,path:a,method:m,options:{method:m,path:h,expose:!0}})}}}catch(s){console.error(`Failed to load route from ${a}:`,s)}}}}enableWatch(e){if(typeof Bun!=="undefined"&&Bun.env.NODE_ENV==="development")console.log(`Watching for route changes in ${this.routesDir}`),setInterval(async()=>{await e()},1000)}}class U{beforeHandlers=[];finallyHandlers=[];addBefore(...e){this.beforeHandlers.push(...e)}addFinally(...e){this.finallyHandlers.push(...e)}async executeBefore(e){if(this.beforeHandlers.length===0)return e;let t=e;for(let n of this.beforeHandlers){let d=await n(t);if(d instanceof Response)return d;t=d}return t}async executeFinally(e,t){if(this.finallyHandlers.length===0)return e;let n=e;for(let d of this.finallyHandlers)try{n=await d(n,t)}catch(r){console.error("After middleware error:",r)}return n}clone(){let e=new U;return e.beforeHandlers=[...this.beforeHandlers],e.finallyHandlers=[...this.finallyHandlers],e}clear(){this.beforeHandlers=[],this.finallyHandlers=[]}}function _(e){return process.platform==="win32"?`file:///${e.replace(/\\/g,"/")}`:e}function Y(e){return RegExp(`^${e.replace(/\/+(\/|$)/g,"$1").replace(/(\/?\.?):(\w+)\+/g,"($1(?<$2>[\\s\\S]+))").replace(/(\/?\.?):(\w+)/g,"($1(?<$2>[^$1/]+?))").replace(/\./g,"\\.").replace(/(\/?)\*/g,"($1.*)?")}/*$`)}function be(e){let t=e?.["~standard"];return!!t&&typeof t==="object"&&typeof t.validate==="function"&&t.version===1}async function ue(e,t){let n=await e["~standard"].validate(t),d=n?.issues;if(Array.isArray(d)&&d.length>0)return{success:!1,issues:d};return{success:!0,value:n?.value}}function me(e){if(Array.isArray(e))return e;if(e&&typeof e==="object"&&Array.isArray(e.issues))return e.issues;if(e&&typeof e==="object"&&e.cause&&Array.isArray(e.cause.issues))return e.cause.issues;return null}function We(e){if(!Array.isArray(e))return[];let t=[];for(let n=0;n<e.length;n++){let d=e[n],r=d;if(d&&typeof d==="object"&&"key"in d)r=d.key;if(typeof r==="string"||typeof r==="number")t.push(r);else if(typeof r==="symbol")t.push(String(r));else if(r!==void 0&&r!==null)t.push(String(r))}return t}function X(e,t){let n=[];for(let d=0;d<e.length;d++){let r=e[d],a=r,i={message:typeof a?.message==="string"&&a.message.length>0?a.message:"Invalid value",path:We(a?.path)};if(typeof a?.code==="string")i.code=a.code;if(t)i.raw=r;n.push(i)}return n}function W(e,t){return{error:!0,message:"Validation failed",statusCode:422,source:"validation",target:e,issues:t,timestamp:new Date().toISOString()}}class O{middlewareManager;authManager;cacheManager;routeBooleanDefaults={};developmentMode=void 0;routeDefinitions=[];routeTable=Object.create(null);routeMatchers=[];corsHeadersEntries=null;corsHandler=null;constructor(e,t,n){this.middlewareManager=e,this.authManager=t,this.cacheManager=n}setCorsHeaders(e){this.corsHeadersEntries=e}setCorsHandler(e){this.corsHandler=e}setRouteBooleanDefaults(e){this.routeBooleanDefaults={...e}}setDevelopmentMode(e){this.developmentMode=e}applyRouteBooleanDefaults(e){let t={...e},n=this.routeBooleanDefaults,d=["auth","expose","rawRequest","validate","rawResponse"];for(let r of d)if(t[r]===void 0&&n[r]!==void 0)t[r]=n[r];return t}route(e,t){let n=this.applyRouteBooleanDefaults(e),d=n.method.toUpperCase(),r=n.path,a=this.wrapHandler(n,t),i=this.getOrCreateMethodMap(r);i[d]=a,this.routeDefinitions.push({method:d,path:r,options:n})}addRoute(e){let[t,,n,d]=e;if(!d)return;let r=this.getOrCreateMethodMap(d);r[t.toUpperCase()]=n[0];let a=t.toUpperCase();this.routeDefinitions.push({method:a,path:d,options:{method:a,path:d,expose:!0}})}bulkAddRoutes(e){for(let t of e)this.addRoute(t)}addStaticRoute(e,t){let n=this.routeTable[e];if(n&&!(n instanceof Response))throw new Error(`Cannot register static route for path "${e}" because method routes already exist.`);this.routeTable[e]=t,this.removeRouteMatcher(e)}getRouteTable(){return this.routeTable}getRoutes(){let e=[];for(let t of this.routeMatchers){let n=this.routeTable[t.path];if(!n||n instanceof Response)continue;for(let[d,r]of Object.entries(n))e.push([d,t.regex,[r],t.path])}return e}getRouteDefinitions(){return[...this.routeDefinitions]}clearRoutes(){this.routeTable=Object.create(null),this.routeMatchers=[],this.routeDefinitions=[]}sortRoutes(){}async handle(e){let t;try{t=new URL(e.url)}catch{return w.badRequest("Malformed request URL")}e._parsedUrl=t;let n=t.pathname;for(let d of this.routeMatchers){let r=d.path,a=this.routeTable[r];if(!a)continue;if(a instanceof Response)continue;let i=a;if(e.method==="OPTIONS"||e.method in i){let o=n.match(d.regex);if(o){try{e.params=o.groups??{}}catch{}let s=i[e.method]??i.GET;if(s){let c=await s(e);if(c)return c}}}}return T.NOT_FOUND.clone()}prepareRequest(e,t){if(!e.context)e.context={};let n=!!e.params&&typeof e.params==="object"&&!Array.isArray(e.params)&&Object.keys(e.params).length===0;if(t?.params!==void 0&&(e.params===void 0||n))try{e.params=t.params}catch{}if(t?.route!==void 0)e.route=t.route;if(t?.metadata!==void 0)e.metadata=t.metadata;if(e.query==null&&e.url)try{Object.defineProperty(e,"query",{get(){let d=this._parsedUrl??new URL(this.url),r=O.parseQuery(d);return Object.defineProperty(this,"query",{value:r,writable:!0,configurable:!0,enumerable:!0}),r},set(d){Object.defineProperty(this,"query",{value:d,writable:!0,configurable:!0,enumerable:!0})},configurable:!0,enumerable:!0})}catch{let d=e._parsedUrl??new URL(e.url);try{e.query=O.parseQuery(d)}catch{}}if(!Object.getOwnPropertyDescriptor(e,"cookies"))Object.defineProperty(e,"cookies",{get(){let d=this.headers.get("cookie")??"",r={};if(d)for(let a of d.split(";")){let i=a.indexOf("=");if(i>0)r[a.slice(0,i).trim()]=a.slice(i+1).trim()}return Object.defineProperty(this,"cookies",{value:r,writable:!0,configurable:!0,enumerable:!0}),r},configurable:!0,enumerable:!0})}resolveFallbackParams(e,t){if(!t)return;let n=e.params;if(n&&typeof n==="object"&&!Array.isArray(n)&&Object.keys(n).length>0)return;let d;try{d=(e._parsedUrl??new URL(e.url)).pathname}catch{return}let r=d.match(t);if(!r?.groups)return;return r.groups}wrapHandler(e,t){let n=e.path,d=n.includes(":")?Y(n):null;return async(r)=>{let a=r,i=this.resolveFallbackParams(r,d);this.prepareRequest(a,{params:i,route:n,metadata:e.metadata});try{if(e.expose===!1)return w.forbidden("Forbidden");let o=await this.middlewareManager.executeBefore(a);if(o instanceof Response)return o;let s=o;if(e.auth)try{await this.authManager.authenticate(s)}catch(f){return w.unauthorized(f instanceof Error?f.message:"Authentication failed",e.responseContentType)}if(!e.rawRequest&&s.method!=="GET"&&s.method!=="HEAD"){let f=null;try{let p=s.headers.get("content-type");if(p?.startsWith("application/json"))f=await s.json();else if(p?.startsWith("application/x-www-form-urlencoded"))f=Object.fromEntries(await s.formData());else if(p?.startsWith("multipart/form-data"))f=await s.formData();else f=await s.text()}catch{f=null}this.setContentAndBodyAlias(s,f)}let c=await this.validateInputSchema(s,e);if(c)return c;let l,u=e.cache;if(u&&typeof u==="number"&&u>0){let f=this.cacheManager.generateKey(s,{authUser:s.authUser});l=await this.cacheManager.get(f,async()=>{let p=await t(s);if(p instanceof Response)return{_isResponse:!0,body:await p.text(),status:p.status,headers:Object.fromEntries(p.headers.entries())};return p},u)}else if(u&&typeof u==="object"&&u.ttl){let f=u.key||this.cacheManager.generateKey(s,{authUser:s.authUser});l=await this.cacheManager.get(f,async()=>{let p=await t(s);if(p instanceof Response)return{_isResponse:!0,body:await p.text(),status:p.status,headers:Object.fromEntries(p.headers.entries())};return p},u.ttl)}else l=await t(s);if(l&&typeof l==="object"&&l._isResponse===!0)l=new Response(l.body,{status:l.status,headers:l.headers});let m;if(e.rawResponse||l instanceof Response)m=l instanceof Response?l:new Response(l);else m=I(200,l,e.responseContentType);m=await this.middlewareManager.executeFinally(m,s);let h=this.corsHeadersEntries;if(h)for(let[f,p]of h)m.headers.set(f,p);else{let f=this.corsHandler;if(f)m=f(m,s)}return m}catch(o){if(o instanceof Response)return o;return console.error("Route handler error:",o),w.internalServerError(o instanceof Error?o.message:String(o),e.responseContentType)}}}isDevelopmentMode(){if(this.developmentMode!==void 0)return this.developmentMode;return(typeof Bun!=="undefined"?Bun.env.NODE_ENV:"development")!=="production"}async buildInputValidationPayload(e,t){let n=e.content;if(t.rawRequest&&e.method!=="GET"&&e.method!=="HEAD")try{n=await e.clone().text()}catch{n=null}return{params:e.params??{},query:e.query??{},headers:Object.fromEntries(e.headers.entries()),cookies:e.cookies??{},body:n}}applyValidatedInput(e,t){if(e.validatedInput=t,!t||typeof t!=="object")return;let n=t;if("params"in n)try{e.params=n.params}catch{}if("query"in n)try{e.query=n.query}catch{}if("cookies"in n)try{e.cookies=n.cookies}catch{}if("body"in n)this.setContentAndBodyAlias(e,n.body)}setContentAndBodyAlias(e,t){try{e.content=t}catch{return}this.setBodyAlias(e,t)}setBodyAlias(e,t){try{e.body=t}catch{}}async validateInputSchema(e,t){let n=t.schema?.input;if(!n)return null;if(t.validate===!1)return null;if(!be(n))return w.internalServerError("Invalid route schema configuration",t.responseContentType);let d=this.isDevelopmentMode(),r=await this.buildInputValidationPayload(e,t);try{let a=await ue(n,r);if(a.success===!1){let i=X(a.issues,d);return I(422,W("input",i),t.responseContentType)}return this.applyValidatedInput(e,a.value),null}catch(a){let i=me(a);if(i){let o=X(i,d);return I(422,W("input",o),t.responseContentType)}return w.internalServerError(a instanceof Error?a.message:"Validation failed",t.responseContentType)}}getOrCreateMethodMap(e){let t=this.routeTable[e];if(t instanceof Response)throw new Error(`Cannot register method route for path "${e}" because a static route already exists.`);if(t)return t;let n=Object.create(null);return this.routeTable[e]=n,this.addRouteMatcher(e),n}addRouteMatcher(e){if(this.routeMatchers.some((t)=>t.path===e))return;this.routeMatchers.push({path:e,regex:Y(e),specificity:this.routeSpecificityScore(e)}),this.routeMatchers.sort((t,n)=>{if(t.specificity!==n.specificity)return n.specificity-t.specificity;return t.path.localeCompare(n.path)})}removeRouteMatcher(e){this.routeMatchers=this.routeMatchers.filter((t)=>t.path!==e)}static parseQuery(e){let t={};for(let[n,d]of e.searchParams)if(n in t){let r=t[n];if(Array.isArray(r))r.push(d);else t[n]=[r,d]}else t[n]=d;return t}routeSpecificityScore(e){let a=e.split("/").filter(Boolean),i=0;for(let o of a)if(o.includes("*"))i+=1;else if(o.startsWith(":"))i+=10;else i+=1000;if(i+=e.length,!e.includes(":")&&!e.includes("*"))i+=1e4;return i}}var re=(()=>({}));function fe(e,t){if(!e){if(typeof t.origin==="string"){if(t.origin==="*"&&t.credentials)return null;return t.origin}return null}if(typeof t.origin==="string"){if(t.origin==="*")return t.credentials?e:"*";return t.origin===e?e:null}if(Array.isArray(t.origin))return t.origin.includes(e)?e:null;if(typeof t.origin==="function")return t.origin(e)?e:null;return null}function pe(e){return typeof e.origin==="string"&&e.origin==="*"&&e.credentials||Array.isArray(e.origin)||typeof e.origin==="function"}function he(e,t,n){let d={};if(e){if(d["access-control-allow-origin"]=e,d["access-control-allow-methods"]=t.allowMethods,d["access-control-allow-headers"]=t.allowHeaders,d["access-control-expose-headers"]=t.exposeHeaders,d["access-control-max-age"]=String(t.maxAge),t.credentials)d["access-control-allow-credentials"]="true";if(n)d.vary="Origin"}return d}function Ke(e,t){if(!e)return t;let n=e.split(",").map((r)=>r.trim()).filter(Boolean);if(!n.map((r)=>r.toLowerCase()).includes(t.toLowerCase()))n.push(t);return n.join(", ")}function ye(e){return{preflight(t){let n=t.headers.get("origin")??void 0,d=fe(n,e),r=Boolean(n&&d&&pe(e));return new Response(null,{status:204,headers:he(d,e,r)})},corsify(t,n){let d=n.headers.get("origin")??void 0,r=fe(d,e);if(!r)return t;let a=Boolean(d&&pe(e)),i=he(r,e,a);for(let[o,s]of Object.entries(i)){if(o==="vary"){t.headers.set("vary",Ke(t.headers.get("vary"),s));continue}t.headers.set(o,s)}return t}}}function ge(e,t,n,d,r,a,i,o,s){let c=JSON.stringify(e).replace(/<\/script/gi,"<\\/script"),l=JSON.stringify(t),u=JSON.stringify(n),m=JSON.stringify(d),h=JSON.stringify(r),f=JSON.stringify(a),p=JSON.stringify(i),Se=JSON.stringify(o),Pe=JSON.stringify(s);return`<!DOCTYPE html>
|
|
22
22
|
<html lang="en">
|
|
23
23
|
<head>
|
|
24
24
|
<meta charset="UTF-8">
|
|
25
25
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
26
26
|
<title>Vector API Documentation</title>
|
|
27
|
+
<link rel="apple-touch-icon" sizes="180x180" href=${f}>
|
|
28
|
+
<link rel="icon" type="image/png" sizes="32x32" href=${p}>
|
|
29
|
+
<link rel="icon" type="image/png" sizes="16x16" href=${Se}>
|
|
30
|
+
<link rel="manifest" href=${Pe}>
|
|
27
31
|
<script>
|
|
28
32
|
if (localStorage.getItem('theme') === 'dark' || (!('theme' in localStorage) && window.matchMedia('(prefers-color-scheme: dark)').matches)) {
|
|
29
33
|
document.documentElement.classList.add('dark');
|
|
@@ -31,7 +35,7 @@ ${t.join(`,
|
|
|
31
35
|
document.documentElement.classList.remove('dark');
|
|
32
36
|
}
|
|
33
37
|
</script>
|
|
34
|
-
<script src=${
|
|
38
|
+
<script src=${u}></script>
|
|
35
39
|
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500&display=swap" rel="stylesheet">
|
|
36
40
|
<script>
|
|
37
41
|
tailwind.config = {
|
|
@@ -39,7 +43,12 @@ ${t.join(`,
|
|
|
39
43
|
theme: {
|
|
40
44
|
extend: {
|
|
41
45
|
colors: {
|
|
42
|
-
brand:
|
|
46
|
+
brand: {
|
|
47
|
+
DEFAULT: '#00A1FF',
|
|
48
|
+
mint: '#00FF8F',
|
|
49
|
+
soft: '#E4F5FF',
|
|
50
|
+
deep: '#007BC5',
|
|
51
|
+
},
|
|
43
52
|
dark: { bg: '#0A0A0A', surface: '#111111', border: '#1F1F1F', text: '#EDEDED' },
|
|
44
53
|
light: { bg: '#FFFFFF', surface: '#F9F9F9', border: '#E5E5E5', text: '#111111' }
|
|
45
54
|
},
|
|
@@ -106,32 +115,44 @@ ${t.join(`,
|
|
|
106
115
|
from { opacity: 0; transform: translateX(-6px); }
|
|
107
116
|
to { opacity: 1; transform: translateX(0); }
|
|
108
117
|
}
|
|
118
|
+
@keyframes spin {
|
|
119
|
+
to { transform: rotate(360deg); }
|
|
120
|
+
}
|
|
121
|
+
.button-spinner {
|
|
122
|
+
display: inline-block;
|
|
123
|
+
width: 0.875rem;
|
|
124
|
+
height: 0.875rem;
|
|
125
|
+
border: 2px solid currentColor;
|
|
126
|
+
border-right-color: transparent;
|
|
127
|
+
border-radius: 9999px;
|
|
128
|
+
animation: spin 700ms linear infinite;
|
|
129
|
+
}
|
|
109
130
|
@media (prefers-reduced-motion: reduce) {
|
|
110
131
|
*, *::before, *::after {
|
|
111
132
|
animation: none !important;
|
|
112
133
|
transition: none !important;
|
|
113
134
|
}
|
|
114
135
|
}
|
|
115
|
-
.json-key { color: #
|
|
116
|
-
.json-string { color: #
|
|
117
|
-
.json-number { color: #
|
|
118
|
-
.json-boolean { color: #
|
|
119
|
-
.json-null { color: #
|
|
120
|
-
.dark .json-key { color: #
|
|
121
|
-
.dark .json-string { color: #
|
|
122
|
-
.dark .json-number { color: #
|
|
123
|
-
.dark .json-boolean { color: #
|
|
124
|
-
.dark .json-null { color: #
|
|
136
|
+
.json-key { color: #007bc5; }
|
|
137
|
+
.json-string { color: #334155; }
|
|
138
|
+
.json-number { color: #00a1ff; }
|
|
139
|
+
.json-boolean { color: #475569; }
|
|
140
|
+
.json-null { color: #64748b; }
|
|
141
|
+
.dark .json-key { color: #7dc9ff; }
|
|
142
|
+
.dark .json-string { color: #d1d9e6; }
|
|
143
|
+
.dark .json-number { color: #7dc9ff; }
|
|
144
|
+
.dark .json-boolean { color: #93a4bf; }
|
|
145
|
+
.dark .json-null { color: #7c8ba3; }
|
|
125
146
|
</style>
|
|
126
147
|
</head>
|
|
127
148
|
<body class="bg-light-bg text-light-text dark:bg-dark-bg dark:text-dark-text font-sans antialiased flex h-screen overflow-hidden">
|
|
128
149
|
<div id="mobile-backdrop" class="fixed inset-0 z-30 bg-black/40 opacity-0 pointer-events-none transition-opacity duration-300 md:hidden"></div>
|
|
129
150
|
<aside id="docs-sidebar" class="fixed inset-y-0 left-0 z-40 w-72 md:w-64 border-r border-light-border dark:border-dark-border bg-light-surface dark:bg-dark-surface flex flex-col flex-shrink-0 transition-transform duration-300 ease-out -translate-x-full md:translate-x-0 md:static md:z-auto transition-colors duration-150">
|
|
130
151
|
<div class="h-14 flex items-center px-5 border-b border-light-border dark:border-dark-border">
|
|
131
|
-
<
|
|
132
|
-
<
|
|
133
|
-
|
|
134
|
-
|
|
152
|
+
<div class="flex items-center">
|
|
153
|
+
<img src=${m} alt="Vector" class="h-6 w-auto block dark:hidden" />
|
|
154
|
+
<img src=${h} alt="Vector" class="h-6 w-auto hidden dark:block" />
|
|
155
|
+
</div>
|
|
135
156
|
<button id="sidebar-close" class="ml-auto p-1.5 rounded-full border border-light-border dark:border-dark-border bg-light-bg/90 dark:bg-dark-bg/90 opacity-90 hover:opacity-100 transition md:hidden" aria-label="Close Menu" title="Close Menu">
|
|
136
157
|
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
137
158
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"></path>
|
|
@@ -162,8 +183,8 @@ ${t.join(`,
|
|
|
162
183
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6h16M4 12h16M4 18h16"></path>
|
|
163
184
|
</svg>
|
|
164
185
|
</button>
|
|
165
|
-
<
|
|
166
|
-
<
|
|
186
|
+
<img src=${m} alt="Vector" class="h-5 w-auto block dark:hidden" />
|
|
187
|
+
<img src=${h} alt="Vector" class="h-5 w-auto hidden dark:block" />
|
|
167
188
|
</div>
|
|
168
189
|
<div class="flex-1"></div>
|
|
169
190
|
<button id="theme-toggle" class="p-2 rounded-md hover:bg-black/5 dark:hover:bg-white/5 transition-colors" aria-label="Toggle Dark Mode">
|
|
@@ -188,17 +209,22 @@ ${t.join(`,
|
|
|
188
209
|
<div class="grid grid-cols-1 lg:grid-cols-12 gap-10">
|
|
189
210
|
<div class="lg:col-span-5 space-y-8" id="params-column"></div>
|
|
190
211
|
<div class="lg:col-span-7">
|
|
191
|
-
<div class="rounded-lg border border-light-border dark:border-
|
|
192
|
-
<div class="flex items-center justify-between px-4 py-2 border-b border-light-border dark:border-
|
|
193
|
-
<span class="text-xs font-mono text-light-text/70 dark:text-
|
|
194
|
-
<button class="text-xs text-light-text/50 hover:text-light-text dark:text-
|
|
212
|
+
<div class="rounded-lg border border-light-border dark:border-dark-border bg-light-bg dark:bg-dark-bg overflow-hidden group">
|
|
213
|
+
<div class="flex items-center justify-between px-4 py-2 border-b border-light-border dark:border-dark-border bg-light-surface dark:bg-dark-surface">
|
|
214
|
+
<span class="text-xs font-mono text-light-text/70 dark:text-dark-text/70">cURL</span>
|
|
215
|
+
<button class="text-xs text-light-text/50 hover:text-light-text dark:text-dark-text/50 dark:hover:text-dark-text transition-colors" id="copy-curl">Copy</button>
|
|
195
216
|
</div>
|
|
196
|
-
<pre class="p-4 text-sm font-mono text-light-text dark:text-
|
|
217
|
+
<pre class="p-4 text-sm font-mono text-light-text dark:text-dark-text overflow-x-auto leading-relaxed"><code id="curl-code"></code></pre>
|
|
197
218
|
</div>
|
|
198
219
|
<div class="mt-4 p-4 rounded-lg border border-light-border dark:border-dark-border bg-light-surface dark:bg-dark-surface">
|
|
199
220
|
<div class="flex items-center justify-between mb-3">
|
|
200
221
|
<h4 class="text-sm font-medium">Try it out</h4>
|
|
201
|
-
<button id="send-btn" class="px-4 py-1.5 bg-
|
|
222
|
+
<button id="send-btn" class="px-4 py-1.5 bg-brand text-white text-sm font-semibold rounded hover:bg-brand-deep transition-colors">
|
|
223
|
+
<span class="inline-flex items-center gap-2">
|
|
224
|
+
<span id="send-btn-spinner" class="button-spinner hidden" aria-hidden="true"></span>
|
|
225
|
+
<span id="send-btn-label">Submit</span>
|
|
226
|
+
</span>
|
|
227
|
+
</button>
|
|
202
228
|
</div>
|
|
203
229
|
<div class="space-y-4">
|
|
204
230
|
<div>
|
|
@@ -232,7 +258,7 @@ ${t.join(`,
|
|
|
232
258
|
</div>
|
|
233
259
|
</div>
|
|
234
260
|
|
|
235
|
-
<div>
|
|
261
|
+
<div id="response-section">
|
|
236
262
|
<div class="flex items-center justify-between mb-2">
|
|
237
263
|
<p class="text-xs font-semibold uppercase tracking-wider opacity-60">Response</p>
|
|
238
264
|
</div>
|
|
@@ -259,7 +285,7 @@ ${t.join(`,
|
|
|
259
285
|
<div class="flex items-center justify-between mb-3">
|
|
260
286
|
<h3 id="expand-modal-title" class="text-sm font-semibold">Expanded View</h3>
|
|
261
287
|
<div class="flex items-center gap-2">
|
|
262
|
-
<button id="expand-apply" class="hidden text-sm px-3 py-1.5 rounded bg-
|
|
288
|
+
<button id="expand-apply" class="hidden text-sm px-3 py-1.5 rounded bg-brand text-white font-semibold hover:bg-brand-deep transition-colors">Apply</button>
|
|
263
289
|
<button id="expand-close" class="p-1.5 rounded-full border border-light-border dark:border-dark-border bg-light-bg/90 dark:bg-dark-bg/90 opacity-90 hover:opacity-100 hover:border-brand/60 transition-colors" aria-label="Close Modal" title="Close Modal">
|
|
264
290
|
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
265
291
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"></path>
|
|
@@ -276,14 +302,15 @@ ${t.join(`,
|
|
|
276
302
|
</div>
|
|
277
303
|
|
|
278
304
|
<script>
|
|
279
|
-
const spec = ${
|
|
280
|
-
const openapiPath = ${
|
|
305
|
+
const spec = ${c};
|
|
306
|
+
const openapiPath = ${l};
|
|
307
|
+
const methodBadgeDefault = "bg-black/5 text-light-text/80 dark:bg-white/10 dark:text-dark-text/80";
|
|
281
308
|
const methodBadge = {
|
|
282
|
-
GET: "bg-
|
|
283
|
-
POST: "bg-
|
|
284
|
-
PUT: "bg-
|
|
285
|
-
PATCH: "bg-
|
|
286
|
-
DELETE: "bg-
|
|
309
|
+
GET: "bg-brand-soft text-brand-deep dark:bg-brand/20 dark:text-brand",
|
|
310
|
+
POST: "bg-brand-soft text-brand-deep dark:bg-brand/20 dark:text-brand",
|
|
311
|
+
PUT: "bg-brand-soft text-brand-deep dark:bg-brand/20 dark:text-brand",
|
|
312
|
+
PATCH: "bg-brand-soft text-brand-deep dark:bg-brand/20 dark:text-brand",
|
|
313
|
+
DELETE: "bg-brand-soft text-brand-deep dark:bg-brand/20 dark:text-brand",
|
|
287
314
|
};
|
|
288
315
|
|
|
289
316
|
function getOperations() {
|
|
@@ -537,6 +564,16 @@ ${t.join(`,
|
|
|
537
564
|
return;
|
|
538
565
|
}
|
|
539
566
|
for (const [tag, ops] of groups.entries()) {
|
|
567
|
+
ops.sort((a, b) => {
|
|
568
|
+
const byName = a.name.localeCompare(b.name, undefined, { sensitivity: "base" });
|
|
569
|
+
if (byName !== 0) return byName;
|
|
570
|
+
|
|
571
|
+
const byPath = a.path.localeCompare(b.path, undefined, { sensitivity: "base" });
|
|
572
|
+
if (byPath !== 0) return byPath;
|
|
573
|
+
|
|
574
|
+
return a.method.localeCompare(b.method, undefined, { sensitivity: "base" });
|
|
575
|
+
});
|
|
576
|
+
|
|
540
577
|
const block = document.createElement("div");
|
|
541
578
|
block.innerHTML = '<h3 class="px-2 mb-2 font-semibold text-xs uppercase tracking-wider opacity-50"></h3><ul class="space-y-0.5"></ul>';
|
|
542
579
|
block.querySelector("h3").textContent = tag;
|
|
@@ -548,14 +585,14 @@ ${t.join(`,
|
|
|
548
585
|
const a = document.createElement("a");
|
|
549
586
|
a.href = "#";
|
|
550
587
|
a.className = op === selected
|
|
551
|
-
? "block px-2 py-1.5 rounded-md bg-
|
|
588
|
+
? "block px-2 py-1.5 rounded-md bg-brand-soft/70 dark:bg-brand/20 text-brand-deep dark:text-brand font-medium transition-colors"
|
|
552
589
|
: "block px-2 py-1.5 rounded-md hover:bg-black/5 dark:hover:bg-white/5 transition-colors";
|
|
553
590
|
|
|
554
591
|
const row = document.createElement("span");
|
|
555
592
|
row.className = "flex items-center gap-2";
|
|
556
593
|
|
|
557
594
|
const method = document.createElement("span");
|
|
558
|
-
method.className = "px-1.5 py-0.5 rounded text-[10px] font-mono font-semibold " + (methodBadge[op.method] ||
|
|
595
|
+
method.className = "px-1.5 py-0.5 rounded text-[10px] font-mono font-semibold " + (methodBadge[op.method] || methodBadgeDefault);
|
|
559
596
|
method.textContent = op.method;
|
|
560
597
|
|
|
561
598
|
const name = document.createElement("span");
|
|
@@ -694,6 +731,55 @@ ${t.join(`,
|
|
|
694
731
|
);
|
|
695
732
|
}
|
|
696
733
|
|
|
734
|
+
function renderResponseSchemasSection(responses) {
|
|
735
|
+
if (!responses || typeof responses !== "object") return "";
|
|
736
|
+
|
|
737
|
+
const statusCodes = Object.keys(responses).sort((a, b) => {
|
|
738
|
+
const aNum = Number(a);
|
|
739
|
+
const bNum = Number(b);
|
|
740
|
+
if (Number.isInteger(aNum) && Number.isInteger(bNum)) return aNum - bNum;
|
|
741
|
+
if (Number.isInteger(aNum)) return -1;
|
|
742
|
+
if (Number.isInteger(bNum)) return 1;
|
|
743
|
+
return a.localeCompare(b);
|
|
744
|
+
});
|
|
745
|
+
|
|
746
|
+
let sections = "";
|
|
747
|
+
for (const statusCode of statusCodes) {
|
|
748
|
+
const responseDef = responses[statusCode];
|
|
749
|
+
if (!responseDef || typeof responseDef !== "object") continue;
|
|
750
|
+
|
|
751
|
+
const jsonSchema =
|
|
752
|
+
responseDef.content &&
|
|
753
|
+
responseDef.content["application/json"] &&
|
|
754
|
+
responseDef.content["application/json"].schema;
|
|
755
|
+
|
|
756
|
+
if (!jsonSchema || typeof jsonSchema !== "object") continue;
|
|
757
|
+
|
|
758
|
+
const rootChildren = buildSchemaChildren(jsonSchema);
|
|
759
|
+
if (!rootChildren.length) continue;
|
|
760
|
+
|
|
761
|
+
let rows = "";
|
|
762
|
+
for (const child of rootChildren) {
|
|
763
|
+
rows += renderSchemaFieldNode(child, 0);
|
|
764
|
+
}
|
|
765
|
+
|
|
766
|
+
sections +=
|
|
767
|
+
'<div class="mb-4"><h4 class="text-xs font-mono uppercase tracking-wider opacity-70 mb-2">Status ' +
|
|
768
|
+
escapeHtml(statusCode) +
|
|
769
|
+
"</h4>" +
|
|
770
|
+
rows +
|
|
771
|
+
"</div>";
|
|
772
|
+
}
|
|
773
|
+
|
|
774
|
+
if (!sections) return "";
|
|
775
|
+
|
|
776
|
+
return (
|
|
777
|
+
'<div><h3 class="text-sm font-semibold mb-3 flex items-center border-b border-light-border dark:border-dark-border pb-2">Response Schemas</h3>' +
|
|
778
|
+
sections +
|
|
779
|
+
"</div>"
|
|
780
|
+
);
|
|
781
|
+
}
|
|
782
|
+
|
|
697
783
|
function renderTryItParameterInputs(pathParams, queryParams) {
|
|
698
784
|
const container = document.getElementById("request-param-inputs");
|
|
699
785
|
if (!container || !selected) return;
|
|
@@ -977,6 +1063,19 @@ ${t.join(`,
|
|
|
977
1063
|
}
|
|
978
1064
|
}
|
|
979
1065
|
|
|
1066
|
+
function setSubmitLoading(isLoading) {
|
|
1067
|
+
const sendButton = document.getElementById("send-btn");
|
|
1068
|
+
const spinner = document.getElementById("send-btn-spinner");
|
|
1069
|
+
const label = document.getElementById("send-btn-label");
|
|
1070
|
+
if (!sendButton) return;
|
|
1071
|
+
|
|
1072
|
+
sendButton.disabled = isLoading;
|
|
1073
|
+
sendButton.classList.toggle("opacity-80", isLoading);
|
|
1074
|
+
sendButton.classList.toggle("cursor-wait", isLoading);
|
|
1075
|
+
if (spinner) spinner.classList.toggle("hidden", !isLoading);
|
|
1076
|
+
if (label) label.textContent = isLoading ? "Sending..." : "Submit";
|
|
1077
|
+
}
|
|
1078
|
+
|
|
980
1079
|
function updateRequestPreview() {
|
|
981
1080
|
if (!selected) return;
|
|
982
1081
|
|
|
@@ -1040,7 +1139,7 @@ ${t.join(`,
|
|
|
1040
1139
|
document.getElementById("tag-description").textContent = op.description || "Interactive API documentation.";
|
|
1041
1140
|
const methodNode = document.getElementById("endpoint-method");
|
|
1042
1141
|
methodNode.textContent = selected.method;
|
|
1043
|
-
methodNode.className = "px-2.5 py-0.5 rounded-full text-xs font-mono font-medium " + (methodBadge[selected.method] ||
|
|
1142
|
+
methodNode.className = "px-2.5 py-0.5 rounded-full text-xs font-mono font-medium " + (methodBadge[selected.method] || methodBadgeDefault);
|
|
1044
1143
|
document.getElementById("endpoint-title").textContent = selected.name;
|
|
1045
1144
|
document.getElementById("endpoint-path").textContent = selected.path;
|
|
1046
1145
|
|
|
@@ -1053,6 +1152,7 @@ ${t.join(`,
|
|
|
1053
1152
|
html += renderParamSection("Header Parameters", headers);
|
|
1054
1153
|
|
|
1055
1154
|
html += renderRequestBodySchemaSection(reqSchema);
|
|
1155
|
+
html += renderResponseSchemasSection(op.responses);
|
|
1056
1156
|
document.getElementById("params-column").innerHTML = html || '<div class="text-sm opacity-70">No parameters</div>';
|
|
1057
1157
|
renderTryItParameterInputs(path, query);
|
|
1058
1158
|
renderHeaderInputs();
|
|
@@ -1103,14 +1203,18 @@ ${t.join(`,
|
|
|
1103
1203
|
headers["Content-Type"] = "application/json";
|
|
1104
1204
|
}
|
|
1105
1205
|
|
|
1206
|
+
setSubmitLoading(true);
|
|
1106
1207
|
try {
|
|
1208
|
+
const requestStart = performance.now();
|
|
1107
1209
|
const response = await fetch(requestPath, { method: selected.method, headers, body: body || undefined });
|
|
1108
1210
|
const text = await response.text();
|
|
1211
|
+
const responseTimeMs = Math.round(performance.now() - requestStart);
|
|
1109
1212
|
const contentType = response.headers.get("content-type") || "unknown";
|
|
1110
1213
|
const formattedResponse = formatResponseText(text);
|
|
1111
1214
|
const headerText =
|
|
1112
1215
|
"Status: " + response.status + " " + response.statusText + "\\n" +
|
|
1113
|
-
"Content-Type: " + contentType + "\\n
|
|
1216
|
+
"Content-Type: " + contentType + "\\n" +
|
|
1217
|
+
"Response Time: " + responseTimeMs + " ms\\n\\n";
|
|
1114
1218
|
setResponseContent(
|
|
1115
1219
|
headerText,
|
|
1116
1220
|
formattedResponse.text,
|
|
@@ -1118,6 +1222,8 @@ ${t.join(`,
|
|
|
1118
1222
|
);
|
|
1119
1223
|
} catch (error) {
|
|
1120
1224
|
setResponseContent("", "Request failed: " + String(error), false);
|
|
1225
|
+
} finally {
|
|
1226
|
+
setSubmitLoading(false);
|
|
1121
1227
|
}
|
|
1122
1228
|
});
|
|
1123
1229
|
|
|
@@ -1324,4 +1430,4 @@ ${t.join(`,
|
|
|
1324
1430
|
renderEndpoint();
|
|
1325
1431
|
</script>
|
|
1326
1432
|
</body>
|
|
1327
|
-
</html>`}function oe(e){let t=e?.["~standard"],n=t?.jsonSchema;return!!t&&typeof t==="object"&&t.version===1&&!!n&&typeof n.input==="function"&&typeof n.output==="function"}function le(e){let t=0,n=[];return{openapiPath:e.split("/").map((r)=>{let a=/^:([A-Za-z0-9_]+)\+$/.exec(r);if(a?.[1])return n.push(a[1]),`{${a[1]}}`;let o=/^:([A-Za-z0-9_]+)$/.exec(r);if(o?.[1])return n.push(o[1]),`{${o[1]}}`;if(r==="*"){t+=1;let l=t===1?"wildcard":`wildcard${t}`;return n.push(l),`{${l}}`}return r}).join("/"),pathParamNames:n}}function Le(e){return le(e).openapiPath}function Ce(e,t){return`${e.toLowerCase()}_${t}`.replace(/[:{}]/g,"").replace(/[^A-Za-z0-9_]+/g,"_").replace(/^_+|_+$/g,"")||`${e.toLowerCase()}_operation`}function Oe(e){let t=e.split("/").filter(Boolean);for(let n of t)if(!n.startsWith(":")&&n!=="*")return n.toLowerCase();return"default"}function De(e){return le(e).pathParamNames}function Ne(e,t){let n=new Set((e.parameters||[]).filter((d)=>d.in==="path").map((d)=>String(d.name)));for(let d of De(t)){if(n.has(d))continue;(e.parameters||=[]).push({name:d,in:"path",required:!0,schema:{type:"string"}})}}function Se(e){let t=Number(e);if(!Number.isInteger(t))return!1;return t>=100&&t<200||t===204||t===205||t===304}function je(e){if(e==="204")return"No Content";if(e==="205")return"Reset Content";if(e==="304")return"Not Modified";let t=Number(e);if(Number.isInteger(t)&&t>=100&&t<200)return"Informational";return"OK"}function Me(e,t,n,d){if(!oe(t))return null;try{return t["~standard"].jsonSchema.input({target:n})}catch(r){return d.push(`[OpenAPI] Failed input schema conversion for ${e}: ${r instanceof Error?r.message:String(r)}`),null}}function ae(e,t,n,d,r){if(!oe(n))return null;try{return n["~standard"].jsonSchema.output({target:d})}catch(a){return r.push(`[OpenAPI] Failed output schema conversion for ${e} (${t}): ${a instanceof Error?a.message:String(a)}`),null}}function w(e){return!!e&&typeof e==="object"&&!Array.isArray(e)}function Pe(e,t){if(!w(t))return;if(t.type!=="object"||!w(t.properties)){e.requestBody={required:!0,content:{"application/json":{schema:t}}};return}let n=new Set(Array.isArray(t.required)?t.required:[]),d=t.properties,r=Array.isArray(e.parameters)?e.parameters:[],a=[{key:"params",in:"path"},{key:"query",in:"query"},{key:"headers",in:"header"},{key:"cookies",in:"cookie"}];for(let l of a){let i=d[l.key];if(!w(i))continue;if(i.type!=="object"||!w(i.properties))continue;let b=new Set(Array.isArray(i.required)?i.required:[]);for(let[s,u]of Object.entries(i.properties))r.push({name:s,in:l.in,required:l.in==="path"?!0:b.has(s),schema:w(u)?u:{}})}if(r.length>0){let l=new Map;for(let i of r)l.set(`${i.in}:${i.name}`,i);e.parameters=[...l.values()]}let o=d.body;if(o)e.requestBody={required:n.has("body"),content:{"application/json":{schema:w(o)?o:{}}}}}function _e(e,t,n,d,r){let a=n.output;if(!a){e.responses={200:{description:"OK"}};return}let o={};if(typeof a==="object"&&a!==null&&"~standard"in a){let l=ae(t,"200",a,d,r);if(l)o["200"]={description:"OK",content:{"application/json":{schema:l}}};else o["200"]={description:"OK"}}else for(let[l,i]of Object.entries(a)){let b=String(l),s=ae(t,b,i,d,r),u=je(b);if(s&&!Se(b))o[b]={description:u,content:{"application/json":{schema:s}}};else o[b]={description:u}}if(Object.keys(o).length===0)o["200"]={description:"OK"};e.responses=o}function ie(e,t){let n=[],d={};for(let o of e){if(o.options.expose===!1)continue;if(!o.method||!o.path)continue;let l=o.method.toLowerCase();if(l==="options")continue;let i=Le(o.path),b={operationId:Ce(l,i),tags:[o.options.schema?.tag||Oe(o.path)]},s=Me(o.path,o.options.schema?.input,t.target,n);if(s)Pe(b,s);Ne(b,o.path),_e(b,o.path,o.options.schema||{},t.target,n),d[i]||={},d[i][l]=b}return{document:{openapi:t.target==="openapi-3.0"?"3.0.3":"3.1.0",info:{title:t.info?.title||"Vector API",version:t.info?.version||"1.0.0",...t.info?.description?{description:t.info.description}:{}},paths:d},warnings:n}}var z="/_vector/openapi/tailwindcdn.js",He=["../openapi/assets/tailwindcdn.js","../src/openapi/assets/tailwindcdn.js","../../src/openapi/assets/tailwindcdn.js"],Re=["src/openapi/assets/tailwindcdn.js","openapi/assets/tailwindcdn.js","dist/openapi/assets/tailwindcdn.js"],Te="/* OpenAPI docs runtime asset missing: tailwind disabled */";function Ue(){for(let t of He)try{let n=new URL(t,import.meta.url);if(V.existsSync(n))return Bun.file(n)}catch{}let e=process.cwd();for(let t of Re){let n=B(e,t);if(V.existsSync(n))return Bun.file(n)}return null}var se=Ue(),$="public, max-age=0, must-revalidate",ce="public, max-age=31536000, immutable";class G{server=null;router;config;openapiConfig;openapiDocCache=null;openapiDocsHtmlCache=null;openapiWarningsLogged=!1;openapiTailwindMissingLogged=!1;corsHandler=null;corsHeadersEntries=null;constructor(e,t){if(this.router=e,this.config=t,this.openapiConfig=this.normalizeOpenAPIConfig(t.openapi,t.development),t.cors){let n=this.normalizeCorsOptions(t.cors),{preflight:d,corsify:r}=de(n);if(this.corsHandler={preflight:d,corsify:r},typeof n.origin==="string"&&(n.origin!=="*"||!n.credentials)){let o={"access-control-allow-origin":n.origin,"access-control-allow-methods":n.allowMethods,"access-control-allow-headers":n.allowHeaders,"access-control-expose-headers":n.exposeHeaders,"access-control-max-age":String(n.maxAge)};if(n.credentials)o["access-control-allow-credentials"]="true";this.corsHeadersEntries=Object.entries(o)}this.router.setCorsHeaders(this.corsHeadersEntries),this.router.setCorsHandler(this.corsHeadersEntries?null:this.corsHandler.corsify)}}normalizeOpenAPIConfig(e,t){let d=t!==!1&&!0;if(e===!1)return{enabled:!1,path:"/openapi.json",target:"openapi-3.0",docs:{enabled:!1,path:"/docs"}};if(e===!0)return{enabled:!0,path:"/openapi.json",target:"openapi-3.0",docs:{enabled:!1,path:"/docs"}};let r=e||{},a=r.docs,o=typeof a==="boolean"?{enabled:a,path:"/docs"}:{enabled:a?.enabled===!0,path:a?.path||"/docs"};return{enabled:r.enabled??d,path:r.path||"/openapi.json",target:r.target||"openapi-3.0",docs:o,info:r.info}}isDocsReservedPath(e){return e===this.openapiConfig.path||this.openapiConfig.docs.enabled&&e===this.openapiConfig.docs.path}getOpenAPIDocument(){if(this.openapiDocCache)return this.openapiDocCache;let e=this.router.getRouteDefinitions().filter((n)=>!this.isDocsReservedPath(n.path)),t=ie(e,{target:this.openapiConfig.target,info:this.openapiConfig.info});if(!this.openapiWarningsLogged&&t.warnings.length>0){for(let n of t.warnings)console.warn(n);this.openapiWarningsLogged=!0}return this.openapiDocCache=t.document,this.openapiDocCache}getOpenAPIDocsHtmlCacheEntry(){if(this.openapiDocsHtmlCache)return this.openapiDocsHtmlCache;let e=re(this.getOpenAPIDocument(),this.openapiConfig.path,z),t=Bun.gzipSync(e),n=`"${Bun.hash(e).toString(16)}"`;return this.openapiDocsHtmlCache={html:e,gzip:t,etag:n},this.openapiDocsHtmlCache}requestAcceptsGzip(e){let t=e.headers.get("accept-encoding");return Boolean(t&&/\bgzip\b/i.test(t))}validateReservedOpenAPIPaths(){if(!this.openapiConfig.enabled)return;let e=new Set([this.openapiConfig.path]);if(this.openapiConfig.docs.enabled)e.add(this.openapiConfig.docs.path),e.add(z);let t=this.router.getRouteDefinitions().filter((r)=>e.has(r.path)).map((r)=>`${r.method} ${r.path}`),n=Object.entries(this.router.getRouteTable()).filter(([r,a])=>e.has(r)&&a instanceof Response).map(([r])=>`STATIC ${r}`),d=[...t,...n];if(d.length>0)throw new Error(`OpenAPI reserved path conflict: ${d.join(", ")}. Change your route path(s) or reconfigure openapi.path/docs.path.`)}tryHandleOpenAPIRequest(e){if(!this.openapiConfig.enabled||e.method!=="GET")return null;let t=new URL(e.url).pathname;if(t===this.openapiConfig.path)return Response.json(this.getOpenAPIDocument());if(this.openapiConfig.docs.enabled&&t===this.openapiConfig.docs.path){let{html:n,gzip:d,etag:r}=this.getOpenAPIDocsHtmlCacheEntry();if(e.headers.get("if-none-match")===r)return new Response(null,{status:304,headers:{etag:r,"cache-control":$,vary:"accept-encoding"}});if(this.requestAcceptsGzip(e))return new Response(d,{status:200,headers:{"content-type":"text/html; charset=utf-8","content-encoding":"gzip",etag:r,"cache-control":$,vary:"accept-encoding"}});return new Response(n,{status:200,headers:{"content-type":"text/html; charset=utf-8",etag:r,"cache-control":$,vary:"accept-encoding"}})}if(this.openapiConfig.docs.enabled&&t===z){if(!se){if(!this.openapiTailwindMissingLogged)this.openapiTailwindMissingLogged=!0,console.warn('[OpenAPI] Missing docs runtime asset "tailwindcdn.js". Serving inline fallback script instead.');return new Response(Te,{status:200,headers:{"content-type":"application/javascript; charset=utf-8","cache-control":ce}})}return new Response(se,{status:200,headers:{"content-type":"application/javascript; charset=utf-8","cache-control":ce}})}return null}normalizeCorsOptions(e){return{origin:e.origin||"*",credentials:e.credentials!==!1,allowHeaders:Array.isArray(e.allowHeaders)?e.allowHeaders.join(", "):e.allowHeaders||"Content-Type, Authorization",allowMethods:Array.isArray(e.allowMethods)?e.allowMethods.join(", "):e.allowMethods||"GET, POST, PUT, PATCH, DELETE, OPTIONS",exposeHeaders:Array.isArray(e.exposeHeaders)?e.exposeHeaders.join(", "):e.exposeHeaders||"Authorization",maxAge:e.maxAge||86400}}applyCors(e,t){if(this.corsHeadersEntries){for(let[n,d]of this.corsHeadersEntries)e.headers.set(n,d);return e}if(this.corsHandler&&t)return this.corsHandler.corsify(e,t);return e}async start(){let e=this.config.port??3000,t=this.config.hostname||"localhost";this.validateReservedOpenAPIPaths();let n=async(d)=>{try{if(this.corsHandler&&d.method==="OPTIONS")return this.corsHandler.preflight(d);let r=this.tryHandleOpenAPIRequest(d);if(r)return this.applyCors(r,d);return this.applyCors(C.NOT_FOUND.clone(),d)}catch(r){return console.error("Server error:",r),this.applyCors(new Response("Internal Server Error",{status:500}),d)}};try{if(this.server=Bun.serve({port:e,hostname:t,reusePort:this.config.reusePort!==!1,routes:this.router.getRouteTable(),fetch:n,idleTimeout:this.config.idleTimeout||60,error:(d,r)=>{return console.error("[ERROR] Server error:",d),this.applyCors(new Response("Internal Server Error",{status:500}),r)}}),!this.server||!this.server.port)throw new Error(`Failed to start server on ${t}:${e} - server object is invalid`);return this.server}catch(d){if(d.code==="EADDRINUSE"||d.message?.includes("address already in use"))d.message=`Port ${e} is already in use`,d.port=e;else if(d.code==="EACCES"||d.message?.includes("permission denied"))d.message=`Permission denied to bind to port ${e}`,d.port=e;else if(d.message?.includes("EADDRNOTAVAIL"))d.message=`Cannot bind to hostname ${t}`,d.hostname=t;throw d}}stop(){if(this.server)this.server.stop(),this.server=null,this.openapiDocCache=null,this.openapiDocsHtmlCache=null,this.openapiWarningsLogged=!1,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 e=this.getPort();return`http://${this.getHostname()}:${e}`}}class k{static instance;router;server=null;middlewareManager;authManager;cacheManager;config={};routeScanner=null;routeGenerator=null;_protectedHandler=null;_cacheHandler=null;constructor(){this.middlewareManager=new S,this.authManager=new _,this.cacheManager=new H,this.router=new L(this.middlewareManager,this.authManager,this.cacheManager)}static getInstance(){if(!k.instance)k.instance=new k;return k.instance}setProtectedHandler(e){this._protectedHandler=e,this.authManager.setProtectedHandler(e)}getProtectedHandler(){return this._protectedHandler}setCacheHandler(e){this._cacheHandler=e,this.cacheManager.setCacheHandler(e)}getCacheHandler(){return this._cacheHandler}addRoute(e,t){this.router.route(e,t)}async startServer(e){this.config={...this.config,...e};let t={...this.config.defaults?.route};if(this.router.setRouteBooleanDefaults(t),this.router.setDevelopmentMode(this.config.development),this.middlewareManager.clear(),this.config.autoDiscover!==!1)this.router.clearRoutes();if(e?.before)this.middlewareManager.addBefore(...e.before);if(e?.finally)this.middlewareManager.addFinally(...e.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 e=this.config.routesDir||"./routes",t=this.config.routeExcludePatterns;if(this.routeScanner=new N(e,t),!this.routeGenerator)this.routeGenerator=new T;try{let n=await this.routeScanner.scan();if(n.length>0){if(this.config.development)await this.routeGenerator.generate(n);for(let d of n)try{let a=await import(W(d.path)),o=d.name==="default"?a.default:a[d.name];if(o){if(this.isRouteDefinition(o))this.router.route(o.options,o.handler),this.logRouteLoaded(o.options);else if(this.isRouteEntry(o))this.router.addRoute(o),this.logRouteLoaded(o);else if(typeof o==="function")this.router.route(d.options,o),this.logRouteLoaded(d.options)}}catch(r){console.error(`Failed to load route ${d.name} from ${d.path}:`,r)}}}catch(n){if(n.code!=="ENOENT"&&n.code!=="ENOTDIR")console.error("Failed to discover routes:",n)}}async loadRoute(e){if(typeof e==="function"){let t=e();if(this.isRouteEntry(t))this.router.addRoute(t)}else if(e&&typeof e==="object"){for(let[,t]of Object.entries(e))if(typeof t==="function"){let n=t();if(this.isRouteEntry(n))this.router.addRoute(n)}}}isRouteEntry(e){if(!Array.isArray(e)||e.length<3)return!1;let[t,n,d,r]=e;return typeof t==="string"&&n instanceof RegExp&&Array.isArray(d)&&d.length>0&&d.every((a)=>typeof a==="function")&&(r===void 0||typeof r==="string")}isRouteDefinition(e){return e!==null&&typeof e==="object"&&"entry"in e&&"options"in e&&"handler"in e&&typeof e.handler==="function"}logRouteLoaded(e){}stop(){if(this.server)this.server.stop(),this.server=null}getServer(){return this.server}getRouter(){return this.router}getCacheManager(){return this.cacheManager}getAuthManager(){return this.authManager}static resetInstance(){k.instance=null}}var Fe=k.getInstance;function be(e,t){return{entry:{method:e.method.toUpperCase(),path:e.path},options:e,handler:t}}function Je(e){let t=e??null;try{return JSON.stringify(t)}catch(n){if(n instanceof TypeError&&/\bbigint\b/i.test(n.message))return JSON.stringify(t,(d,r)=>typeof r==="bigint"?r.toString():r);throw n}}function c(e,t,n){let d={error:!0,message:t,statusCode:e,timestamp:new Date().toISOString()};return v(e,d,n)}var x={badRequest:(e="Bad Request",t)=>c(g.BAD_REQUEST,e,t),unauthorized:(e="Unauthorized",t)=>c(g.UNAUTHORIZED,e,t),paymentRequired:(e="Payment Required",t)=>c(402,e,t),forbidden:(e="Forbidden",t)=>c(g.FORBIDDEN,e,t),notFound:(e="Not Found",t)=>c(g.NOT_FOUND,e,t),methodNotAllowed:(e="Method Not Allowed",t)=>c(405,e,t),notAcceptable:(e="Not Acceptable",t)=>c(406,e,t),requestTimeout:(e="Request Timeout",t)=>c(408,e,t),conflict:(e="Conflict",t)=>c(g.CONFLICT,e,t),gone:(e="Gone",t)=>c(410,e,t),lengthRequired:(e="Length Required",t)=>c(411,e,t),preconditionFailed:(e="Precondition Failed",t)=>c(412,e,t),payloadTooLarge:(e="Payload Too Large",t)=>c(413,e,t),uriTooLong:(e="URI Too Long",t)=>c(414,e,t),unsupportedMediaType:(e="Unsupported Media Type",t)=>c(415,e,t),rangeNotSatisfiable:(e="Range Not Satisfiable",t)=>c(416,e,t),expectationFailed:(e="Expectation Failed",t)=>c(417,e,t),imATeapot:(e="I'm a teapot",t)=>c(418,e,t),misdirectedRequest:(e="Misdirected Request",t)=>c(421,e,t),unprocessableEntity:(e="Unprocessable Entity",t)=>c(g.UNPROCESSABLE_ENTITY,e,t),locked:(e="Locked",t)=>c(423,e,t),failedDependency:(e="Failed Dependency",t)=>c(424,e,t),tooEarly:(e="Too Early",t)=>c(425,e,t),upgradeRequired:(e="Upgrade Required",t)=>c(426,e,t),preconditionRequired:(e="Precondition Required",t)=>c(428,e,t),tooManyRequests:(e="Too Many Requests",t)=>c(429,e,t),requestHeaderFieldsTooLarge:(e="Request Header Fields Too Large",t)=>c(431,e,t),unavailableForLegalReasons:(e="Unavailable For Legal Reasons",t)=>c(451,e,t),internalServerError:(e="Internal Server Error",t)=>c(g.INTERNAL_SERVER_ERROR,e,t),notImplemented:(e="Not Implemented",t)=>c(501,e,t),badGateway:(e="Bad Gateway",t)=>c(502,e,t),serviceUnavailable:(e="Service Unavailable",t)=>c(503,e,t),gatewayTimeout:(e="Gateway Timeout",t)=>c(504,e,t),httpVersionNotSupported:(e="HTTP Version Not Supported",t)=>c(505,e,t),variantAlsoNegotiates:(e="Variant Also Negotiates",t)=>c(506,e,t),insufficientStorage:(e="Insufficient Storage",t)=>c(507,e,t),loopDetected:(e="Loop Detected",t)=>c(508,e,t),notExtended:(e="Not Extended",t)=>c(510,e,t),networkAuthenticationRequired:(e="Network Authentication Required",t)=>c(511,e,t),invalidArgument:(e="Invalid Argument",t)=>c(g.UNPROCESSABLE_ENTITY,e,t),rateLimitExceeded:(e="Rate Limit Exceeded",t)=>c(429,e,t),maintenance:(e="Service Under Maintenance",t)=>c(503,e,t),custom:(e,t,n)=>c(e,t,n)};function v(e,t,n=P.JSON){let d=n===P.JSON?Je(t):t;return new Response(d,{status:e,headers:{"content-type":n}})}
|
|
1433
|
+
</html>`}function ve(e){let t=e?.["~standard"],n=t?.jsonSchema;return!!t&&typeof t==="object"&&t.version===1&&!!n&&typeof n.input==="function"&&typeof n.output==="function"}function ke(e){let t=0,n=[];return{openapiPath:e.split("/").map((r)=>{let a=/^:([A-Za-z0-9_]+)\+$/.exec(r);if(a?.[1])return n.push(a[1]),`{${a[1]}}`;let i=/^:([A-Za-z0-9_]+)$/.exec(r);if(i?.[1])return n.push(i[1]),`{${i[1]}}`;if(r==="*"){t+=1;let o=t===1?"wildcard":`wildcard${t}`;return n.push(o),`{${o}}`}return r}).join("/"),pathParamNames:n}}function Ze(e){return ke(e).openapiPath}function qe(e,t){return`${e.toLowerCase()}_${t}`.replace(/[:{}]/g,"").replace(/[^A-Za-z0-9_]+/g,"_").replace(/^_+|_+$/g,"")||`${e.toLowerCase()}_operation`}function et(e){let t=e.split("/").filter(Boolean);for(let n of t)if(!n.startsWith(":")&&n!=="*")return n.toLowerCase();return"default"}function tt(e){return ke(e).pathParamNames}function nt(e,t){let n=new Set((e.parameters||[]).filter((d)=>d.in==="path").map((d)=>String(d.name)));for(let d of tt(t)){if(n.has(d))continue;(e.parameters||=[]).push({name:d,in:"path",required:!0,schema:{type:"string"}})}}function dt(e){let t=Number(e);if(!Number.isInteger(t))return!1;return t>=100&&t<200||t===204||t===205||t===304}function rt(e){if(e==="204")return"No Content";if(e==="205")return"Reset Content";if(e==="304")return"Not Modified";let t=Number(e);if(Number.isInteger(t)&&t>=100&&t<200)return"Informational";return"OK"}function at(e,t,n,d){if(!ve(t))return null;try{return t["~standard"].jsonSchema.input({target:n})}catch(r){d.push(`[OpenAPI] Failed input schema conversion for ${e}: ${r instanceof Error?r.message:String(r)}. Falling back to a permissive JSON Schema.`);let a=we(t);return ot(a)?null:a}}function xe(e,t,n,d,r){if(!ve(n))return null;try{return n["~standard"].jsonSchema.output({target:d})}catch(a){return r.push(`[OpenAPI] Failed output schema conversion for ${e} (${t}): ${a instanceof Error?a.message:String(a)}. Falling back to a permissive JSON Schema.`),we(n)}}function g(e){return!!e&&typeof e==="object"&&!Array.isArray(e)}function ot(e){return g(e)&&Object.keys(e).length===0}function Z(e){if(!e||typeof e!=="object")return null;let t=e;if(g(t._def))return t._def;if(g(t._zod)&&g(t._zod.def))return t._zod.def;return null}function Ee(e){if(!e)return null;let t=e.typeName;if(typeof t==="string")return t;let n=e.type;if(typeof n==="string")return n;return null}function K(e){let t=["innerType","schema","type","out","in","left","right"];for(let n of t)if(n in e)return e[n];return}function it(e,t){for(let n of t){let d=e[n];if(d&&typeof d==="object"&&!Array.isArray(d))return d}return}function st(e){if(!e)return!1;let t=e.toLowerCase();return t.includes("optional")||t.includes("default")||t.includes("catch")}function lt(e){let t=e,n=!1,d=0;while(d<8){d+=1;let r=Z(t),a=Ee(r);if(!r||!st(a))break;n=!0;let i=K(r);if(!i)break;t=i}return{schema:t,optional:n}}function ct(e){let t=e.shape;if(typeof t==="function")try{let n=t();return g(n)?n:{}}catch{return{}}return g(t)?t:{}}function bt(e){let t=e.toLowerCase();if(t.includes("string"))return{type:"string"};if(t.includes("number"))return{type:"number"};if(t.includes("boolean"))return{type:"boolean"};if(t.includes("bigint"))return{type:"string"};if(t.includes("null"))return{type:"null"};if(t.includes("any")||t.includes("unknown")||t.includes("never"))return{};if(t.includes("date"))return{type:"string",format:"date-time"};if(t.includes("custom"))return{type:"object",additionalProperties:!0};return null}function x(e,t=new WeakSet){if(!e||typeof e!=="object")return{};if(t.has(e))return{};t.add(e);let n=Z(e),d=Ee(n);if(!n||!d)return{};let r=bt(d);if(r)return r;let a=d.toLowerCase();if(a.includes("object")){let o=ct(n),s={},c=[];for(let[u,m]of Object.entries(o)){let h=lt(m);if(s[u]=x(h.schema,t),!h.optional)c.push(u)}let l={type:"object",properties:s,additionalProperties:!0};if(c.length>0)l.required=c;return l}if(a.includes("array")){let o=it(n,["element","items","innerType","type"])??{};return{type:"array",items:x(o,t)}}if(a.includes("record")){let o=n.valueType??n.valueSchema;return{type:"object",additionalProperties:o?x(o,t):!0}}if(a.includes("tuple")){let s=(Array.isArray(n.items)?n.items:[]).map((c)=>x(c,t));return{type:"array",prefixItems:s,minItems:s.length,maxItems:s.length}}if(a.includes("union")){let o=n.options??n.schemas??[];if(!Array.isArray(o)||o.length===0)return{};return{anyOf:o.map((s)=>x(s,t))}}if(a.includes("intersection")){let{left:o,right:s}=n;if(!o||!s)return{};return{allOf:[x(o,t),x(s,t)]}}if(a.includes("enum")){let o=n.values;if(Array.isArray(o))return{enum:o};if(o&&typeof o==="object")return{enum:Object.values(o)};return{}}if(a.includes("literal")){let o=n.value;if(o===void 0)return{};let s=o===null?"null":typeof o;if(s==="string"||s==="number"||s==="boolean"||s==="null")return{type:s,const:o};return{const:o}}if(a.includes("nullable")){let o=K(n);if(!o)return{};return{anyOf:[x(o,t),{type:"null"}]}}if(a.includes("lazy")){let o=n.getter;if(typeof o!=="function")return{};try{return x(o(),t)}catch{return{}}}let i=K(n);if(i)return x(i,t);return{}}function we(e){if(!Z(e))return{};return x(e)}function ut(e,t){if(!g(t))return;if(t.type!=="object"||!g(t.properties)){e.requestBody={required:!0,content:{"application/json":{schema:t}}};return}let n=new Set(Array.isArray(t.required)?t.required:[]),d=t.properties,r=Array.isArray(e.parameters)?e.parameters:[],a=[{key:"params",in:"path"},{key:"query",in:"query"},{key:"headers",in:"header"},{key:"cookies",in:"cookie"}];for(let o of a){let s=d[o.key];if(!g(s))continue;if(s.type!=="object"||!g(s.properties))continue;let c=new Set(Array.isArray(s.required)?s.required:[]);for(let[l,u]of Object.entries(s.properties))r.push({name:l,in:o.in,required:o.in==="path"?!0:c.has(l),schema:g(u)?u:{}})}if(r.length>0){let o=new Map;for(let s of r)o.set(`${s.in}:${s.name}`,s);e.parameters=[...o.values()]}let i=d.body;if(i)e.requestBody={required:n.has("body"),content:{"application/json":{schema:g(i)?i:{}}}}}function mt(e,t,n,d,r){let a=n.output;if(!a){e.responses={200:{description:"OK"}};return}let i={};if(typeof a==="object"&&a!==null&&"~standard"in a){let o=xe(t,"200",a,d,r);if(o)i["200"]={description:"OK",content:{"application/json":{schema:o}}};else i["200"]={description:"OK"}}else for(let[o,s]of Object.entries(a)){let c=String(o),l=xe(t,c,s,d,r),u=rt(c);if(l&&!dt(c))i[c]={description:u,content:{"application/json":{schema:l}}};else i[c]={description:u}}if(Object.keys(i).length===0)i["200"]={description:"OK"};e.responses=i}function Be(e,t){let n=[],d={};for(let i of e){if(i.options.expose===!1)continue;if(!i.method||!i.path)continue;let o=i.method.toLowerCase();if(o==="options")continue;let s=Ze(i.path),c={operationId:qe(o,s),tags:[i.options.schema?.tag||et(i.path)]},l=at(i.path,i.options.schema?.input,t.target,n);if(l)ut(c,l);nt(c,i.path),mt(c,i.path,i.options.schema||{},t.target,n),d[s]||={},d[s][o]=c}return{document:{openapi:t.target==="openapi-3.0"?"3.0.3":"3.1.0",info:{title:t.info?.title||"Vector API",version:t.info?.version||"1.0.0",...t.info?.description?{description:t.info.description}:{}},paths:d},warnings:n}}var q="/_vector/openapi/tailwindcdn.js",ee="/_vector/openapi/logo_dark.svg",te="/_vector/openapi/logo_white.svg",De="/_vector/openapi/favicon/apple-touch-icon.png",Ne="/_vector/openapi/favicon/favicon-32x32.png",je="/_vector/openapi/favicon/favicon-16x16.png",ft="/_vector/openapi/favicon/favicon.ico",Me="/_vector/openapi/favicon/site.webmanifest",pt="/_vector/openapi/favicon/android-chrome-192x192.png",ht="/_vector/openapi/favicon/android-chrome-512x512.png",yt=["../openapi/assets/tailwindcdn.js","../src/openapi/assets/tailwindcdn.js","../../src/openapi/assets/tailwindcdn.js"],gt=["../openapi/assets/logo_dark.svg","../src/openapi/assets/logo_dark.svg","../../src/openapi/assets/logo_dark.svg"],xt=["../openapi/assets/logo_white.svg","../src/openapi/assets/logo_white.svg","../../src/openapi/assets/logo_white.svg"],vt=["src/openapi/assets/tailwindcdn.js","openapi/assets/tailwindcdn.js","dist/openapi/assets/tailwindcdn.js"],kt=["src/openapi/assets/logo_dark.svg","openapi/assets/logo_dark.svg","dist/openapi/assets/logo_dark.svg"],Et=["src/openapi/assets/logo_white.svg","openapi/assets/logo_white.svg","dist/openapi/assets/logo_white.svg"],L=["../openapi/assets/favicon","../src/openapi/assets/favicon","../../src/openapi/assets/favicon"],A=["src/openapi/assets/favicon","openapi/assets/favicon","dist/openapi/assets/favicon"],wt="/* OpenAPI docs runtime asset missing: tailwind disabled */";function y(e,t){return e.map((n)=>`${n}/${t}`)}function k(e,t){for(let d of e)try{let r=new URL(d,import.meta.url);if(re.existsSync(r))return Bun.file(r)}catch{}let n=process.cwd();for(let d of t){let r=j(n,d);if(re.existsSync(r))return Bun.file(r)}return null}var Ie=k(yt,vt),Le=k(gt,kt),Ae=k(xt,Et),Bt=k(y(L,"apple-touch-icon.png"),y(A,"apple-touch-icon.png")),It=k(y(L,"favicon-32x32.png"),y(A,"favicon-32x32.png")),Lt=k(y(L,"favicon-16x16.png"),y(A,"favicon-16x16.png")),At=k(y(L,"favicon.ico"),y(A,"favicon.ico")),Ct=k(y(L,"site.webmanifest"),y(A,"site.webmanifest")),Dt=k(y(L,"android-chrome-192x192.png"),y(A,"android-chrome-192x192.png")),Nt=k(y(L,"android-chrome-512x512.png"),y(A,"android-chrome-512x512.png")),Ce=[{path:De,file:Bt,contentType:"image/png",filename:"apple-touch-icon.png"},{path:Ne,file:It,contentType:"image/png",filename:"favicon-32x32.png"},{path:je,file:Lt,contentType:"image/png",filename:"favicon-16x16.png"},{path:ft,file:At,contentType:"image/x-icon",filename:"favicon.ico"},{path:Me,file:Ct,contentType:"application/manifest+json; charset=utf-8",filename:"site.webmanifest"},{path:pt,file:Dt,contentType:"image/png",filename:"android-chrome-192x192.png"},{path:ht,file:Nt,contentType:"image/png",filename:"android-chrome-512x512.png"}],ne="public, max-age=0, must-revalidate",H="public, max-age=31536000, immutable",de="no-store";function jt(e){return e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function Mt(e){let t="^";for(let n of e){if(n==="*"){t+=".*";continue}t+=jt(n)}return t+="$",new RegExp(t)}function Ot(e,t){if(!t.includes("*"))return e===t;return Mt(t).test(e)}class ae{server=null;router;config;openapiConfig;openapiDocCache=null;openapiDocsHtmlCache=null;openapiWarningsLogged=!1;openapiTailwindMissingLogged=!1;openapiLogoDarkMissingLogged=!1;openapiLogoWhiteMissingLogged=!1;corsHandler=null;corsHeadersEntries=null;constructor(e,t){if(this.router=e,this.config=t,this.openapiConfig=this.normalizeOpenAPIConfig(t.openapi,t.development),t.cors){let n=this.normalizeCorsOptions(t.cors),{preflight:d,corsify:r}=ye(n);if(this.corsHandler={preflight:d,corsify:r},typeof n.origin==="string"&&(n.origin!=="*"||!n.credentials)){let i={"access-control-allow-origin":n.origin,"access-control-allow-methods":n.allowMethods,"access-control-allow-headers":n.allowHeaders,"access-control-expose-headers":n.exposeHeaders,"access-control-max-age":String(n.maxAge)};if(n.credentials)i["access-control-allow-credentials"]="true";this.corsHeadersEntries=Object.entries(i)}this.router.setCorsHeaders(this.corsHeadersEntries),this.router.setCorsHandler(this.corsHeadersEntries?null:this.corsHandler.corsify)}}normalizeOpenAPIConfig(e,t){let d=t!==!1&&!0;if(e===!1)return{enabled:!1,path:"/openapi.json",target:"openapi-3.0",docs:{enabled:!1,path:"/docs"}};if(e===!0)return{enabled:!0,path:"/openapi.json",target:"openapi-3.0",docs:{enabled:!1,path:"/docs"}};let r=e||{},a=r.docs,i=typeof a==="boolean"?{enabled:a,path:"/docs",exposePaths:void 0}:{enabled:a?.enabled===!0,path:a?.path||"/docs",exposePaths:Array.isArray(a?.exposePaths)?a.exposePaths.map((o)=>typeof o==="string"?o.trim():"").filter((o)=>o.length>0):void 0};return{enabled:r.enabled??d,path:r.path||"/openapi.json",target:r.target||"openapi-3.0",docs:i,info:r.info}}isDocsReservedPath(e){return e===this.openapiConfig.path||this.openapiConfig.docs.enabled&&e===this.openapiConfig.docs.path}getOpenAPIDocument(){if(this.openapiDocCache)return this.openapiDocCache;let e=this.router.getRouteDefinitions().filter((n)=>!this.isDocsReservedPath(n.path)),t=Be(e,{target:this.openapiConfig.target,info:this.openapiConfig.info});if(!this.openapiWarningsLogged&&t.warnings.length>0){for(let n of t.warnings)console.warn(n);this.openapiWarningsLogged=!0}return this.openapiDocCache=t.document,this.openapiDocCache}getOpenAPIDocumentForDocs(){let e=this.openapiConfig.docs.exposePaths,t=this.getOpenAPIDocument();if(!Array.isArray(e)||e.length===0)return t;let n=t.paths&&typeof t.paths==="object"&&!Array.isArray(t.paths)?t.paths:{},d={};for(let[r,a]of Object.entries(n))if(e.some((i)=>Ot(r,i)))d[r]=a;return{...t,paths:d}}getOpenAPIDocsHtmlCacheEntry(){if(this.openapiDocsHtmlCache)return this.openapiDocsHtmlCache;let e=ge(this.getOpenAPIDocumentForDocs(),this.openapiConfig.path,q,ee,te,De,Ne,je,Me),t=Bun.gzipSync(e),n=`"${Bun.hash(e).toString(16)}"`;return this.openapiDocsHtmlCache={html:e,gzip:t,etag:n},this.openapiDocsHtmlCache}requestAcceptsGzip(e){let t=e.headers.get("accept-encoding");return Boolean(t&&/\bgzip\b/i.test(t))}validateReservedOpenAPIPaths(){if(!this.openapiConfig.enabled)return;let e=new Set([this.openapiConfig.path]);if(this.openapiConfig.docs.enabled){e.add(this.openapiConfig.docs.path),e.add(q),e.add(ee),e.add(te);for(let r of Ce)e.add(r.path)}let t=this.router.getRouteDefinitions().filter((r)=>e.has(r.path)).map((r)=>`${r.method} ${r.path}`),n=Object.entries(this.router.getRouteTable()).filter(([r,a])=>e.has(r)&&a instanceof Response).map(([r])=>`STATIC ${r}`),d=[...t,...n];if(d.length>0)throw new Error(`OpenAPI reserved path conflict: ${d.join(", ")}. Change your route path(s) or reconfigure openapi.path/docs.path.`)}tryHandleOpenAPIRequest(e){if(!this.openapiConfig.enabled||e.method!=="GET")return null;let t=new URL(e.url).pathname;if(t===this.openapiConfig.path)return Response.json(this.getOpenAPIDocument());if(this.openapiConfig.docs.enabled&&t===this.openapiConfig.docs.path){let{html:n,gzip:d,etag:r}=this.getOpenAPIDocsHtmlCacheEntry();if(e.headers.get("if-none-match")===r)return new Response(null,{status:304,headers:{etag:r,"cache-control":ne,vary:"accept-encoding"}});if(this.requestAcceptsGzip(e))return new Response(d,{status:200,headers:{"content-type":"text/html; charset=utf-8","content-encoding":"gzip",etag:r,"cache-control":ne,vary:"accept-encoding"}});return new Response(n,{status:200,headers:{"content-type":"text/html; charset=utf-8",etag:r,"cache-control":ne,vary:"accept-encoding"}})}if(this.openapiConfig.docs.enabled&&t===q){if(!Ie){if(!this.openapiTailwindMissingLogged)this.openapiTailwindMissingLogged=!0,console.warn('[OpenAPI] Missing docs runtime asset "tailwindcdn.js". Serving inline fallback script instead.');return new Response(wt,{status:200,headers:{"content-type":"application/javascript; charset=utf-8","cache-control":H}})}return new Response(Ie,{status:200,headers:{"content-type":"application/javascript; charset=utf-8","cache-control":H}})}if(this.openapiConfig.docs.enabled&&t===ee){if(!Le){if(!this.openapiLogoDarkMissingLogged)this.openapiLogoDarkMissingLogged=!0,console.warn('[OpenAPI] Missing docs runtime asset "logo_dark.svg".');return new Response("OpenAPI docs runtime asset missing: logo_dark.svg",{status:404,headers:{"content-type":"text/plain; charset=utf-8","cache-control":de}})}return new Response(Le,{status:200,headers:{"content-type":"image/svg+xml; charset=utf-8","cache-control":H}})}if(this.openapiConfig.docs.enabled&&t===te){if(!Ae){if(!this.openapiLogoWhiteMissingLogged)this.openapiLogoWhiteMissingLogged=!0,console.warn('[OpenAPI] Missing docs runtime asset "logo_white.svg".');return new Response("OpenAPI docs runtime asset missing: logo_white.svg",{status:404,headers:{"content-type":"text/plain; charset=utf-8","cache-control":de}})}return new Response(Ae,{status:200,headers:{"content-type":"image/svg+xml; charset=utf-8","cache-control":H}})}if(this.openapiConfig.docs.enabled){let n=Ce.find((d)=>d.path===t);if(n){if(!n.file)return new Response(`OpenAPI docs runtime asset missing: ${n.filename}`,{status:404,headers:{"content-type":"text/plain; charset=utf-8","cache-control":de}});return new Response(n.file,{status:200,headers:{"content-type":n.contentType,"cache-control":H}})}}return null}normalizeCorsOptions(e){return{origin:e.origin||"*",credentials:e.credentials!==!1,allowHeaders:Array.isArray(e.allowHeaders)?e.allowHeaders.join(", "):e.allowHeaders||"Content-Type, Authorization",allowMethods:Array.isArray(e.allowMethods)?e.allowMethods.join(", "):e.allowMethods||"GET, POST, PUT, PATCH, DELETE, OPTIONS",exposeHeaders:Array.isArray(e.exposeHeaders)?e.exposeHeaders.join(", "):e.exposeHeaders||"Authorization",maxAge:e.maxAge||86400}}applyCors(e,t){if(this.corsHeadersEntries){for(let[n,d]of this.corsHeadersEntries)e.headers.set(n,d);return e}if(this.corsHandler&&t)return this.corsHandler.corsify(e,t);return e}async start(){let e=this.config.port??3000,t=this.config.hostname||"localhost";this.validateReservedOpenAPIPaths();let n=async(d)=>{try{if(this.corsHandler&&d.method==="OPTIONS")return this.corsHandler.preflight(d);let r=this.tryHandleOpenAPIRequest(d);if(r)return this.applyCors(r,d);return this.applyCors(T.NOT_FOUND.clone(),d)}catch(r){return console.error("Server error:",r),this.applyCors(new Response("Internal Server Error",{status:500}),d)}};try{if(this.server=Bun.serve({port:e,hostname:t,reusePort:this.config.reusePort!==!1,routes:this.router.getRouteTable(),fetch:n,idleTimeout:this.config.idleTimeout??60,error:(d,r)=>{return console.error("[ERROR] Server error:",d),this.applyCors(new Response("Internal Server Error",{status:500}),r)}}),!this.server||!this.server.port)throw new Error(`Failed to start server on ${t}:${e} - server object is invalid`);return this.server}catch(d){if(d.code==="EADDRINUSE"||d.message?.includes("address already in use"))d.message=`Port ${e} is already in use`,d.port=e;else if(d.code==="EACCES"||d.message?.includes("permission denied"))d.message=`Permission denied to bind to port ${e}`,d.port=e;else if(d.message?.includes("EADDRNOTAVAIL"))d.message=`Cannot bind to hostname ${t}`,d.hostname=t;throw d}}stop(){if(this.server)this.server.stop(),this.server=null,this.openapiDocCache=null,this.openapiDocsHtmlCache=null,this.openapiWarningsLogged=!1,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 e=this.getPort();return`http://${this.getHostname()}:${e}`}}class C{static instance;router;server=null;middlewareManager;authManager;cacheManager;config={};routeScanner=null;routeGenerator=null;_protectedHandler=null;_cacheHandler=null;shutdownPromise=null;constructor(){this.middlewareManager=new U,this.authManager=new V,this.cacheManager=new F,this.router=new O(this.middlewareManager,this.authManager,this.cacheManager)}static getInstance(){if(!C.instance)C.instance=new C;return C.instance}setProtectedHandler(e){if(this._protectedHandler=e,e){this.authManager.setProtectedHandler(e);return}this.authManager.clearProtectedHandler()}getProtectedHandler(){return this._protectedHandler}setCacheHandler(e){if(this._cacheHandler=e,e){this.cacheManager.setCacheHandler(e);return}this.cacheManager.clearCacheHandler()}getCacheHandler(){return this._cacheHandler}addRoute(e,t){this.router.route(e,t)}async startServer(e){this.config={...this.config,...e};let t={...this.config.defaults?.route};if(this.router.setRouteBooleanDefaults(t),this.router.setDevelopmentMode(this.config.development),this.middlewareManager.clear(),this.config.autoDiscover!==!1)this.router.clearRoutes();if(e?.before)this.middlewareManager.addBefore(...e.before);if(e?.finally)this.middlewareManager.addFinally(...e.finally);if(typeof this.config.startup==="function")await this.config.startup();if(this.config.autoDiscover!==!1)await this.discoverRoutes();return this.server=new ae(this.router,this.config),await this.server.start()}async discoverRoutes(){let e=this.config.routesDir||"./routes",t=this.config.routeExcludePatterns;if(this.routeScanner=new R(e,t),!this.routeGenerator)this.routeGenerator=new Q;try{let n=await this.routeScanner.scan();if(n.length>0){if(this.config.development)await this.routeGenerator.generate(n);for(let d of n)try{let a=await import(_(d.path)),i=d.name==="default"?a.default:a[d.name];if(i){if(this.isRouteDefinition(i))this.router.route(i.options,i.handler),this.logRouteLoaded(i.options);else if(this.isRouteEntry(i))this.router.addRoute(i),this.logRouteLoaded(i);else if(typeof i==="function")this.router.route(d.options,i),this.logRouteLoaded(d.options)}}catch(r){console.error(`Failed to load route ${d.name} from ${d.path}:`,r)}}}catch(n){if(n.code!=="ENOENT"&&n.code!=="ENOTDIR")console.error("Failed to discover routes:",n)}}async loadRoute(e){if(typeof e==="function"){let t=e();if(this.isRouteEntry(t))this.router.addRoute(t)}else if(e&&typeof e==="object"){for(let[,t]of Object.entries(e))if(typeof t==="function"){let n=t();if(this.isRouteEntry(n))this.router.addRoute(n)}}}isRouteEntry(e){if(!Array.isArray(e)||e.length<3)return!1;let[t,n,d,r]=e;return typeof t==="string"&&n instanceof RegExp&&Array.isArray(d)&&d.length>0&&d.every((a)=>typeof a==="function")&&(r===void 0||typeof r==="string")}isRouteDefinition(e){return e!==null&&typeof e==="object"&&"entry"in e&&"options"in e&&"handler"in e&&typeof e.handler==="function"}logRouteLoaded(e){}stop(){if(this.server)this.server.stop(),this.server=null}async shutdown(){if(this.shutdownPromise)return this.shutdownPromise;this.shutdownPromise=(async()=>{if(this.stop(),typeof this.config.shutdown==="function")await this.config.shutdown()})();try{await this.shutdownPromise}finally{this.shutdownPromise=null}}getServer(){return this.server}getRouter(){return this.router}getCacheManager(){return this.cacheManager}getAuthManager(){return this.authManager}static resetInstance(){C.instance=null}}var oe=C.getInstance;function Oe(e,t){return{entry:{method:e.method.toUpperCase(),path:e.path},options:e,handler:t}}function Ht(e){let t=e??null;try{return JSON.stringify(t)}catch(n){if(n instanceof TypeError&&/\bbigint\b/i.test(n.message))return JSON.stringify(t,(d,r)=>typeof r==="bigint"?r.toString():r);throw n}}function b(e,t,n){let d={error:!0,message:t,statusCode:e,timestamp:new Date().toISOString()};return I(e,d,n)}var w={badRequest:(e="Bad Request",t)=>b(E.BAD_REQUEST,e,t),unauthorized:(e="Unauthorized",t)=>b(E.UNAUTHORIZED,e,t),paymentRequired:(e="Payment Required",t)=>b(402,e,t),forbidden:(e="Forbidden",t)=>b(E.FORBIDDEN,e,t),notFound:(e="Not Found",t)=>b(E.NOT_FOUND,e,t),methodNotAllowed:(e="Method Not Allowed",t)=>b(405,e,t),notAcceptable:(e="Not Acceptable",t)=>b(406,e,t),requestTimeout:(e="Request Timeout",t)=>b(408,e,t),conflict:(e="Conflict",t)=>b(E.CONFLICT,e,t),gone:(e="Gone",t)=>b(410,e,t),lengthRequired:(e="Length Required",t)=>b(411,e,t),preconditionFailed:(e="Precondition Failed",t)=>b(412,e,t),payloadTooLarge:(e="Payload Too Large",t)=>b(413,e,t),uriTooLong:(e="URI Too Long",t)=>b(414,e,t),unsupportedMediaType:(e="Unsupported Media Type",t)=>b(415,e,t),rangeNotSatisfiable:(e="Range Not Satisfiable",t)=>b(416,e,t),expectationFailed:(e="Expectation Failed",t)=>b(417,e,t),imATeapot:(e="I'm a teapot",t)=>b(418,e,t),misdirectedRequest:(e="Misdirected Request",t)=>b(421,e,t),unprocessableEntity:(e="Unprocessable Entity",t)=>b(E.UNPROCESSABLE_ENTITY,e,t),locked:(e="Locked",t)=>b(423,e,t),failedDependency:(e="Failed Dependency",t)=>b(424,e,t),tooEarly:(e="Too Early",t)=>b(425,e,t),upgradeRequired:(e="Upgrade Required",t)=>b(426,e,t),preconditionRequired:(e="Precondition Required",t)=>b(428,e,t),tooManyRequests:(e="Too Many Requests",t)=>b(429,e,t),requestHeaderFieldsTooLarge:(e="Request Header Fields Too Large",t)=>b(431,e,t),unavailableForLegalReasons:(e="Unavailable For Legal Reasons",t)=>b(451,e,t),internalServerError:(e="Internal Server Error",t)=>b(E.INTERNAL_SERVER_ERROR,e,t),notImplemented:(e="Not Implemented",t)=>b(501,e,t),badGateway:(e="Bad Gateway",t)=>b(502,e,t),serviceUnavailable:(e="Service Unavailable",t)=>b(503,e,t),gatewayTimeout:(e="Gateway Timeout",t)=>b(504,e,t),httpVersionNotSupported:(e="HTTP Version Not Supported",t)=>b(505,e,t),variantAlsoNegotiates:(e="Variant Also Negotiates",t)=>b(506,e,t),insufficientStorage:(e="Insufficient Storage",t)=>b(507,e,t),loopDetected:(e="Loop Detected",t)=>b(508,e,t),notExtended:(e="Not Extended",t)=>b(510,e,t),networkAuthenticationRequired:(e="Network Authentication Required",t)=>b(511,e,t),invalidArgument:(e="Invalid Argument",t)=>b(E.UNPROCESSABLE_ENTITY,e,t),rateLimitExceeded:(e="Rate Limit Exceeded",t)=>b(429,e,t),maintenance:(e="Service Under Maintenance",t)=>b(503,e,t),custom:(e,t,n)=>b(e,t,n)};function I(e,t,n=J.JSON){let d=n===J.JSON?Ht(t):t;return new Response(d,{status:e,headers:{"content-type":n}})}var He=(()=>({}));class ie{configPath;config=null;configSource="default";constructor(e){let t=e||"vector.config.ts";this.configPath=z(t)?t:B(process.cwd(),t)}async load(){if(He.existsSync(this.configPath))try{let t=await import(_(this.configPath));this.config=t.default||t,this.configSource="user"}catch(e){let t=e instanceof Error?e.message:String(e);console.error(`[vector] Failed to load config from ${this.configPath}: ${t}`),console.error("[vector] Server is using default configuration. Fix your config file and restart."),this.config={}}else this.config={};return await this.buildLegacyConfig()}getConfigSource(){return this.configSource}async buildLegacyConfig(){let e={};if(this.config)e.port=this.config.port,e.hostname=this.config.hostname,e.reusePort=this.config.reusePort,e.development=this.config.development,e.routesDir=this.config.routesDir||"./routes",e.routeExcludePatterns=this.config.routeExcludePatterns,e.idleTimeout=this.config.idleTimeout,e.defaults=this.config.defaults,e.openapi=this.config.openapi,e.startup=this.config.startup,e.shutdown=this.config.shutdown;if(e.autoDiscover=!0,this.config?.cors)if(typeof this.config.cors==="boolean")e.cors=this.config.cors?{origin:"*",credentials:!0,allowHeaders:"Content-Type, Authorization",allowMethods:"GET, POST, PUT, PATCH, DELETE, OPTIONS",exposeHeaders:"Authorization",maxAge:86400}:void 0;else e.cors=this.config.cors;if(this.config?.before)e.before=this.config.before;if(this.config?.after)e.finally=this.config.after;return e}async loadAuthHandler(){return this.config?.auth||null}async loadCacheHandler(){return this.config?.cache||null}getConfig(){return this.config}}async function Te(e={}){let t=new ie(e.configPath),n=await t.load(),d=t.getConfigSource(),r={...n};if(e.mutateConfig)r=await e.mutateConfig(r,{configSource:d});if(e.config)r={...r,...e.config};if(e.autoDiscover!==void 0)r.autoDiscover=e.autoDiscover;let a=oe(),i=e.protectedHandler!==void 0?e.protectedHandler:await t.loadAuthHandler(),o=e.cacheHandler!==void 0?e.cacheHandler:await t.loadCacheHandler();a.setProtectedHandler(i??null),a.setCacheHandler(o??null);let s=await a.startServer(r),c={...r,port:s.port??r.port??D.PORT,hostname:s.hostname||r.hostname||D.HOSTNAME,reusePort:r.reusePort!==!1,idleTimeout:r.idleTimeout??60};return{server:s,config:c,stop:()=>a.stop(),shutdown:()=>a.shutdown()}}
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,8DAA8D;AAC9D,OAAO,EAAE,KAAK,EAAE,MAAM,QAAQ,CAAC;AAC/B,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAE7C,4CAA4C;AAC5C,OAAO,EAAE,KAAK,EAAE,CAAC;AACjB,OAAO,EAAE,WAAW,EAAE,CAAC;AAEvB,sCAAsC;AACtC,OAAO,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,QAAQ,CAAC;AAElD,oCAAoC;AACpC,cAAc,SAAS,CAAC;AAExB,gFAAgF"}
|