vector-framework 1.2.2 → 1.2.3

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.
Files changed (189) hide show
  1. package/README.md +18 -6
  2. package/dist/auth/protected.d.ts +4 -4
  3. package/dist/auth/protected.d.ts.map +1 -1
  4. package/dist/auth/protected.js +10 -7
  5. package/dist/auth/protected.js.map +1 -1
  6. package/dist/cache/manager.d.ts +2 -0
  7. package/dist/cache/manager.d.ts.map +1 -1
  8. package/dist/cache/manager.js +21 -4
  9. package/dist/cache/manager.js.map +1 -1
  10. package/dist/checkpoint/artifacts/compressor.d.ts +5 -0
  11. package/dist/checkpoint/artifacts/compressor.d.ts.map +1 -0
  12. package/dist/checkpoint/artifacts/compressor.js +24 -0
  13. package/dist/checkpoint/artifacts/compressor.js.map +1 -0
  14. package/dist/checkpoint/artifacts/decompress-worker.d.ts +2 -0
  15. package/dist/checkpoint/artifacts/decompress-worker.d.ts.map +1 -0
  16. package/dist/checkpoint/artifacts/decompress-worker.js +31 -0
  17. package/dist/checkpoint/artifacts/decompress-worker.js.map +1 -0
  18. package/dist/checkpoint/artifacts/hasher.d.ts +2 -0
  19. package/dist/checkpoint/artifacts/hasher.d.ts.map +1 -0
  20. package/dist/checkpoint/artifacts/hasher.js +7 -0
  21. package/dist/checkpoint/artifacts/hasher.js.map +1 -0
  22. package/dist/checkpoint/artifacts/manifest.d.ts +6 -0
  23. package/dist/checkpoint/artifacts/manifest.d.ts.map +1 -0
  24. package/dist/checkpoint/artifacts/manifest.js +55 -0
  25. package/dist/checkpoint/artifacts/manifest.js.map +1 -0
  26. package/dist/checkpoint/artifacts/materializer.d.ts +16 -0
  27. package/dist/checkpoint/artifacts/materializer.d.ts.map +1 -0
  28. package/dist/checkpoint/artifacts/materializer.js +168 -0
  29. package/dist/checkpoint/artifacts/materializer.js.map +1 -0
  30. package/dist/checkpoint/artifacts/packager.d.ts +12 -0
  31. package/dist/checkpoint/artifacts/packager.d.ts.map +1 -0
  32. package/dist/checkpoint/artifacts/packager.js +82 -0
  33. package/dist/checkpoint/artifacts/packager.js.map +1 -0
  34. package/dist/checkpoint/artifacts/repository.d.ts +11 -0
  35. package/dist/checkpoint/artifacts/repository.d.ts.map +1 -0
  36. package/dist/checkpoint/artifacts/repository.js +29 -0
  37. package/dist/checkpoint/artifacts/repository.js.map +1 -0
  38. package/dist/checkpoint/artifacts/store.d.ts +13 -0
  39. package/dist/checkpoint/artifacts/store.d.ts.map +1 -0
  40. package/dist/checkpoint/artifacts/store.js +85 -0
  41. package/dist/checkpoint/artifacts/store.js.map +1 -0
  42. package/dist/checkpoint/artifacts/types.d.ts +21 -0
  43. package/dist/checkpoint/artifacts/types.d.ts.map +1 -0
  44. package/dist/checkpoint/artifacts/types.js +2 -0
  45. package/dist/checkpoint/artifacts/types.js.map +1 -0
  46. package/dist/checkpoint/artifacts/worker-decompressor.d.ts +17 -0
  47. package/dist/checkpoint/artifacts/worker-decompressor.d.ts.map +1 -0
  48. package/dist/checkpoint/artifacts/worker-decompressor.js +148 -0
  49. package/dist/checkpoint/artifacts/worker-decompressor.js.map +1 -0
  50. package/dist/checkpoint/asset-store.d.ts +10 -0
  51. package/dist/checkpoint/asset-store.d.ts.map +1 -0
  52. package/dist/checkpoint/asset-store.js +46 -0
  53. package/dist/checkpoint/asset-store.js.map +1 -0
  54. package/dist/checkpoint/bundler.d.ts +15 -0
  55. package/dist/checkpoint/bundler.d.ts.map +1 -0
  56. package/dist/checkpoint/bundler.js +45 -0
  57. package/dist/checkpoint/bundler.js.map +1 -0
  58. package/dist/checkpoint/cli.d.ts +2 -0
  59. package/dist/checkpoint/cli.d.ts.map +1 -0
  60. package/dist/checkpoint/cli.js +157 -0
  61. package/dist/checkpoint/cli.js.map +1 -0
  62. package/dist/checkpoint/entrypoint-generator.d.ts +17 -0
  63. package/dist/checkpoint/entrypoint-generator.d.ts.map +1 -0
  64. package/dist/checkpoint/entrypoint-generator.js +251 -0
  65. package/dist/checkpoint/entrypoint-generator.js.map +1 -0
  66. package/dist/checkpoint/forwarder.d.ts +6 -0
  67. package/dist/checkpoint/forwarder.d.ts.map +1 -0
  68. package/dist/checkpoint/forwarder.js +74 -0
  69. package/dist/checkpoint/forwarder.js.map +1 -0
  70. package/dist/checkpoint/gateway.d.ts +11 -0
  71. package/dist/checkpoint/gateway.d.ts.map +1 -0
  72. package/dist/checkpoint/gateway.js +30 -0
  73. package/dist/checkpoint/gateway.js.map +1 -0
  74. package/dist/checkpoint/ipc.d.ts +12 -0
  75. package/dist/checkpoint/ipc.d.ts.map +1 -0
  76. package/dist/checkpoint/ipc.js +96 -0
  77. package/dist/checkpoint/ipc.js.map +1 -0
  78. package/dist/checkpoint/manager.d.ts +20 -0
  79. package/dist/checkpoint/manager.d.ts.map +1 -0
  80. package/dist/checkpoint/manager.js +214 -0
  81. package/dist/checkpoint/manager.js.map +1 -0
  82. package/dist/checkpoint/process-manager.d.ts +35 -0
  83. package/dist/checkpoint/process-manager.d.ts.map +1 -0
  84. package/dist/checkpoint/process-manager.js +203 -0
  85. package/dist/checkpoint/process-manager.js.map +1 -0
  86. package/dist/checkpoint/resolver.d.ts +25 -0
  87. package/dist/checkpoint/resolver.d.ts.map +1 -0
  88. package/dist/checkpoint/resolver.js +95 -0
  89. package/dist/checkpoint/resolver.js.map +1 -0
  90. package/dist/checkpoint/socket-path.d.ts +2 -0
  91. package/dist/checkpoint/socket-path.d.ts.map +1 -0
  92. package/dist/checkpoint/socket-path.js +51 -0
  93. package/dist/checkpoint/socket-path.js.map +1 -0
  94. package/dist/checkpoint/types.d.ts +54 -0
  95. package/dist/checkpoint/types.d.ts.map +1 -0
  96. package/dist/checkpoint/types.js +2 -0
  97. package/dist/checkpoint/types.js.map +1 -0
  98. package/dist/cli/index.js +10 -2
  99. package/dist/cli/index.js.map +1 -1
  100. package/dist/cli/option-resolution.d.ts +1 -1
  101. package/dist/cli/option-resolution.d.ts.map +1 -1
  102. package/dist/cli/option-resolution.js.map +1 -1
  103. package/dist/cli.js +3709 -328
  104. package/dist/core/config-loader.d.ts +1 -0
  105. package/dist/core/config-loader.d.ts.map +1 -1
  106. package/dist/core/config-loader.js +10 -2
  107. package/dist/core/config-loader.js.map +1 -1
  108. package/dist/core/router.d.ts +24 -3
  109. package/dist/core/router.d.ts.map +1 -1
  110. package/dist/core/router.js +398 -249
  111. package/dist/core/router.js.map +1 -1
  112. package/dist/core/server.d.ts +2 -0
  113. package/dist/core/server.d.ts.map +1 -1
  114. package/dist/core/server.js +22 -8
  115. package/dist/core/server.js.map +1 -1
  116. package/dist/core/vector.d.ts +3 -0
  117. package/dist/core/vector.d.ts.map +1 -1
  118. package/dist/core/vector.js +51 -1
  119. package/dist/core/vector.js.map +1 -1
  120. package/dist/dev/route-scanner.d.ts.map +1 -1
  121. package/dist/dev/route-scanner.js +2 -1
  122. package/dist/dev/route-scanner.js.map +1 -1
  123. package/dist/http.d.ts +32 -7
  124. package/dist/http.d.ts.map +1 -1
  125. package/dist/http.js +144 -13
  126. package/dist/http.js.map +1 -1
  127. package/dist/index.cjs +1297 -74
  128. package/dist/index.d.ts +3 -2
  129. package/dist/index.d.ts.map +1 -1
  130. package/dist/index.js +2 -2
  131. package/dist/index.js.map +1 -1
  132. package/dist/index.mjs +1296 -73
  133. package/dist/middleware/manager.d.ts +3 -3
  134. package/dist/middleware/manager.d.ts.map +1 -1
  135. package/dist/middleware/manager.js +9 -8
  136. package/dist/middleware/manager.js.map +1 -1
  137. package/dist/openapi/docs-ui.d.ts.map +1 -1
  138. package/dist/openapi/docs-ui.js +1097 -61
  139. package/dist/openapi/docs-ui.js.map +1 -1
  140. package/dist/openapi/generator.d.ts +2 -1
  141. package/dist/openapi/generator.d.ts.map +1 -1
  142. package/dist/openapi/generator.js +240 -7
  143. package/dist/openapi/generator.js.map +1 -1
  144. package/dist/types/index.d.ts +71 -28
  145. package/dist/types/index.d.ts.map +1 -1
  146. package/dist/types/index.js +24 -1
  147. package/dist/types/index.js.map +1 -1
  148. package/dist/utils/validation.d.ts.map +1 -1
  149. package/dist/utils/validation.js +3 -2
  150. package/dist/utils/validation.js.map +1 -1
  151. package/package.json +2 -1
  152. package/src/auth/protected.ts +11 -8
  153. package/src/cache/manager.ts +23 -4
  154. package/src/checkpoint/artifacts/compressor.ts +30 -0
  155. package/src/checkpoint/artifacts/decompress-worker.ts +49 -0
  156. package/src/checkpoint/artifacts/hasher.ts +6 -0
  157. package/src/checkpoint/artifacts/manifest.ts +72 -0
  158. package/src/checkpoint/artifacts/materializer.ts +211 -0
  159. package/src/checkpoint/artifacts/packager.ts +100 -0
  160. package/src/checkpoint/artifacts/repository.ts +36 -0
  161. package/src/checkpoint/artifacts/store.ts +102 -0
  162. package/src/checkpoint/artifacts/types.ts +24 -0
  163. package/src/checkpoint/artifacts/worker-decompressor.ts +192 -0
  164. package/src/checkpoint/asset-store.ts +61 -0
  165. package/src/checkpoint/bundler.ts +64 -0
  166. package/src/checkpoint/cli.ts +177 -0
  167. package/src/checkpoint/entrypoint-generator.ts +275 -0
  168. package/src/checkpoint/forwarder.ts +84 -0
  169. package/src/checkpoint/gateway.ts +40 -0
  170. package/src/checkpoint/ipc.ts +107 -0
  171. package/src/checkpoint/manager.ts +254 -0
  172. package/src/checkpoint/process-manager.ts +250 -0
  173. package/src/checkpoint/resolver.ts +124 -0
  174. package/src/checkpoint/socket-path.ts +61 -0
  175. package/src/checkpoint/types.ts +63 -0
  176. package/src/cli/index.ts +11 -2
  177. package/src/cli/option-resolution.ts +5 -1
  178. package/src/core/config-loader.ts +11 -2
  179. package/src/core/router.ts +505 -264
  180. package/src/core/server.ts +36 -9
  181. package/src/core/vector.ts +60 -1
  182. package/src/dev/route-scanner.ts +2 -1
  183. package/src/http.ts +219 -19
  184. package/src/index.ts +3 -2
  185. package/src/middleware/manager.ts +10 -10
  186. package/src/openapi/docs-ui.ts +1097 -61
  187. package/src/openapi/generator.ts +265 -6
  188. package/src/types/index.ts +83 -30
  189. package/src/utils/validation.ts +5 -3
package/dist/index.mjs CHANGED
@@ -1,8 +1,195 @@
1
1
  // @bun
2
- 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},L={PORT:3000,HOSTNAME:"localhost",ROUTES_DIR:"./routes",CACHE_TTL:0,CORS_MAX_AGE:86400},T={JSON:"application/json",TEXT:"text/plain",HTML:"text/html",FORM_URLENCODED:"application/x-www-form-urlencoded",MULTIPART:"multipart/form-data"};var j={NOT_FOUND:new Response(JSON.stringify({error:!0,message:"Not Found",statusCode:404}),{status:404,headers:{"content-type":"application/json"}})};class R{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 U{cacheHandler=null;memoryCache=new Map;cleanupInterval=null;inflight=new Map;setCacheHandler(e){this.cacheHandler=e}clearCacheHandler(){this.cacheHandler=null}async get(e,t,d=L.CACHE_TTL){if(d<=0)return t();if(this.cacheHandler)return this.cacheHandler(e,t,d);return this.getFromMemoryCache(e,t,d)}async getFromMemoryCache(e,t,d){let n=Date.now(),r=this.memoryCache.get(e);if(this.isCacheValid(r,n))return r.value;if(this.inflight.has(e))return await this.inflight.get(e);let o=(async()=>{let i=await t();return this.setInMemoryCache(e,i,d),i})();this.inflight.set(e,o);try{return await o}finally{this.inflight.delete(e)}}isCacheValid(e,t){return e!==void 0&&e.expires>t}setInMemoryCache(e,t,d){let n=Date.now()+d*1000;this.memoryCache.set(e,{value:t,expires:n}),this.scheduleCleanup()}scheduleCleanup(){if(this.cleanupInterval)return;this.cleanupInterval=setInterval(()=>{this.cleanupExpired()},60000)}cleanupExpired(){let e=Date.now();for(let[t,d]of this.memoryCache.entries())if(d.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,d=L.CACHE_TTL){if(d<=0)return;if(this.cacheHandler){await this.cacheHandler(e,async()=>t,d);return}this.setInMemoryCache(e,t,d)}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 d=e._parsedUrl??new URL(e.url),n=t?.authUser?.id!=null?String(t.authUser.id):"anonymous";return`${e.method}:${d.pathname}:${d.search}:${n}`}}import{promises as ee}from"fs";import{dirname as te,relative as je}from"path";class ${outputPath;constructor(e="./.vector/routes.generated.ts"){this.outputPath=e}async generate(e){let t=te(this.outputPath);await ee.mkdir(t,{recursive:!0});let d=[],n=new Map;for(let a of e){if(!n.has(a.path))n.set(a.path,[]);n.get(a.path).push(a)}let r=0,o=[];for(let[a,s]of n){let c=je(te(this.outputPath),a).replace(/\\/g,"/").replace(/\.(ts|js)$/,""),m=`route_${r++}`,b=s.filter((p)=>p.name!=="default").map((p)=>p.name);if(s.some((p)=>p.name==="default"))if(b.length>0)d.push(`import ${m}, { ${b.join(", ")} } from '${c}';`);else d.push(`import ${m} from '${c}';`);else if(b.length>0)d.push(`import { ${b.join(", ")} } from '${c}';`);for(let p of s){let x=p.name==="default"?m:p.name;o.push(` ${x},`)}}let i=`// This file is auto-generated. Do not edit manually.
2
+ var ir=Object.defineProperty;var P=(e,t)=>{for(var r in t)ir(e,r,{get:t[r],enumerable:!0,configurable:!0,set:(a)=>t[r]=()=>a})};var E=(e,t)=>()=>(e&&(t=e(e=0)),t);var ge=1;function ft(e,t="gzip"){let r=new Uint8Array(e);switch(t){case"none":return r;case"gzip":return Bun.gzipSync(r);default:throw new Error(`Unsupported compression codec: ${t}`)}}var ht="gzip";function T(e){let t=e instanceof Uint8Array?e:new Uint8Array(e),r=Bun.SHA256.hash(t),a=new Uint8Array(r.buffer,r.byteOffset,r.byteLength);return Buffer.from(a).toString("hex")}import{basename as oa,isAbsolute as da,relative as ia}from"path";function Y(e){let t=U(e).trim(),n=(ye(t)?la(t):t).split("/").filter((i)=>i.length>0&&i!=="."&&i!=="..").join("/").replace(gt,"_").replace(/^\/+/,"");if(n.length>0)return n;let o=oa(t).replace(gt,"_");return o.length>0?`external/${o}`:"external/asset.bin"}function xt(e){return U(e).replace(/^\/+/,"")}function ye(e){let t=U(e).trim();return da(t)||yt.test(t)||wt.test(e)}function vt(e){let t=e.map((r)=>({type:r.type,logicalPath:r.logicalPath,contentHash:r.contentHash??r.hash,blobHash:r.blobHash??"",blobPath:r.blobPath??r.storedPath,codec:r.codec??"none",size:r.contentSize??r.size})).sort((r,a)=>`${r.type}:${r.logicalPath}:${r.contentHash}:${r.blobHash}`.localeCompare(`${a.type}:${a.logicalPath}:${a.contentHash}:${a.blobHash}`));return JSON.stringify(t)}function U(e){return e.replace(/\\/g,"/")}function la(e){let t=U(e);if(yt.test(t))return t.replace(/^[a-zA-Z]:/,"").replace(/^\/+/,"");if(wt.test(e))return U(e).replace(/^\\\\[^\\]+\\[^\\]+/,"").replace(/^\/+/,"");return U(ia(process.cwd(),t))}var gt,yt,wt;var we=E(()=>{gt=/[^a-zA-Z0-9._/-]/g,yt=/^[a-zA-Z]:[\\/]/,wt=/^\\\\[^\\]+\\[^\\]+/});import{existsSync as sa,promises as O}from"fs";import{join as xe}from"path";class ve{storageDir;codec;constructor(e,t={}){this.storageDir=e,this.codec=t.assetCodec??ht}async addEmbedded(e,t){return this.addAsset("embedded",e,t)}async addSidecar(e,t){return this.addAsset("sidecar",e,t)}async collect(e,t){let r=[];for(let a of e)r.push(await this.addEmbedded(a,a));for(let a of t)r.push(await this.addSidecar(a,a));return r}async addAsset(e,t,r){let a=await O.readFile(r),n=new Uint8Array(a.buffer,a.byteOffset,a.byteLength),o=T(n),i=ft(n,this.codec),d=T(i),l=xt(xe(Et,`${d}${this.codec==="gzip"?".gz":""}`)),c=xe(this.storageDir,l);if(await O.mkdir(xe(this.storageDir,Et),{recursive:!0}),!sa(c))await this.writeAtomically(c,i);else{let m=await O.readFile(c),s=new Uint8Array(m.buffer,m.byteOffset,m.byteLength);if(T(s)!==d)await this.writeAtomically(c,i)}return{type:e,logicalPath:Y(t),storedPath:c,hash:o,size:a.byteLength,contentHash:o,contentSize:a.byteLength,blobHash:d,blobSize:i.byteLength,blobPath:l,codec:this.codec}}async writeAtomically(e,t){let r=`${e}.tmp.${process.pid}.${Date.now()}`;await O.writeFile(r,t);try{await O.rename(r,e)}catch(a){if(!ca(a))throw a;await O.rm(e,{force:!0}),await O.rename(r,e)}}}function ca(e){if(typeof e!=="object"||e===null||!("code"in e))return!1;let t=e.code;return t==="EEXIST"||t==="EPERM"}var Et="_assets/blobs";var kt=E(()=>{we()});import{promises as pa}from"fs";class Ee{artifactStore;constructor(e){this.artifactStore=new ve(e)}async addEmbedded(e,t){let r=await pa.readFile(t);if(r.byteLength>Bt)throw new Error(`Embedded asset "${e}" is ${q(r.byteLength)} \u2014 exceeds ${q(Bt)} per-file budget. Use sidecar instead.`);return await this.artifactStore.addEmbedded(e,t)}async addSidecar(e,t){return await this.artifactStore.addSidecar(e,t)}async collect(e,t){let r=[];for(let a of e)r.push(await this.addEmbedded(a,a));for(let a of t)r.push(await this.addSidecar(a,a));return r}validateBudgets(e){let t=e.filter((r)=>r.type==="embedded").reduce((r,a)=>r+(a.contentSize??a.size),0);if(t>It)throw new Error(`Total embedded asset size ${q(t)} exceeds ${q(It)} budget.`)}}function q(e){if(e<1024)return`${e} B`;if(e<1048576)return`${(e/1024).toFixed(1)} KB`;return`${(e/1048576).toFixed(1)} MB`}var Bt=65536,It=524288;var Tt=E(()=>{kt()});import{existsSync as Ct}from"fs";import{join as ma}from"path";class ke{async bundle(e){let t=e.outputFile??"checkpoint.js",r=await Bun.build({entrypoints:[e.entrypointPath],outdir:e.outputDir,target:"bun",format:"esm",minify:!0,naming:{entry:t}});if(!r.success){let n=r.logs.map((o)=>o.message??String(o)).join(`
3
+ `);throw new Error(`Checkpoint bundle failed:
4
+ ${n}`)}let a=ma(e.outputDir,t);if(!Ct(a)){let n=r.outputs.find((o)=>o.kind==="entry-point");if(n){let o=n.path;if(Ct(o))return this.hashFile(o)}throw new Error(`Bundle output not found at expected path: ${a}`)}return this.hashFile(a)}async hashFile(e){let r=await Bun.file(e).arrayBuffer(),a=Bun.SHA256.hash(new Uint8Array(r)),n=new Uint8Array(a.buffer,a.byteOffset,a.byteLength),o=Buffer.from(n).toString("hex");return{outputPath:e,hash:o,size:r.byteLength}}}var Lt=()=>{};import{existsSync as ba,promises as Be}from"fs";import{join as Nt,relative as At,sep as St}from"path";class Ie{discoveredRoutes=[];async generate(e){let t=await this.scanRouteFiles(e.routesDir),r=this.buildSource(t,e),a=Nt(e.outputDir,"entrypoint.ts");return await Be.writeFile(a,r,"utf-8"),a}getDiscoveredRoutes(){return this.discoveredRoutes}async scanRouteFiles(e){if(!ba(e))return[];let t=[];return await this.walkDir(e,t),t}async walkDir(e,t){let r=await Be.readdir(e);for(let a of r){let n=Nt(e,a);if((await Be.stat(n)).isDirectory())await this.walkDir(n,t);else if((a.endsWith(".ts")||a.endsWith(".js"))&&!a.endsWith(".test.ts")&&!a.endsWith(".test.js")&&!a.endsWith(".spec.ts")&&!a.endsWith(".spec.js")&&!a.endsWith(".d.ts"))t.push(n)}}buildSource(e,t){this.discoveredRoutes=[];let r=[],a=[];for(let[n,o]of e.entries()){let i=`routeModule_${n}`,d=this.toImportSpecifier(o,t.outputDir);r.push(`import * as ${i} from ${JSON.stringify(d)};`),a.push(` registerModule(${i});`);let l=At(t.routesDir,o).replace(/\.(ts|js)$/,"").split(St).join("/");this.discoveredRoutes.push({method:"*",path:`/${l}`})}return`// Checkpoint entrypoint \u2014 auto-generated for version ${t.version}
5
+ // DO NOT EDIT: This file is generated by Vector checkpoint publish.
6
+
7
+ ${r.join(`
8
+ `)}
9
+
10
+ const socketPath = process.env.VECTOR_CHECKPOINT_SOCKET ?? '${t.socketPath}';
11
+ const checkpointContextHeader = 'x-vector-checkpoint-context';
12
+
13
+ // Route registration helper
14
+ type RouteDefinition = {
15
+ entry: { method: string; path: string };
16
+ options: { method: string; path: string; [key: string]: any };
17
+ handler: (ctx: any) => any;
18
+ };
19
+
20
+ function isRouteDefinition(value: unknown): value is RouteDefinition {
21
+ return (
22
+ value !== null &&
23
+ typeof value === 'object' &&
24
+ 'entry' in value &&
25
+ 'options' in value &&
26
+ 'handler' in value &&
27
+ typeof (value as any).handler === 'function'
28
+ );
29
+ }
30
+
31
+ const routeTable: Record<string, Record<string, (req: Request) => Response | Promise<Response>>> = {};
32
+
33
+ function parseCheckpointContext(req: Request): Record<string, unknown> {
34
+ const encoded = req.headers.get(checkpointContextHeader);
35
+ if (!encoded) {
36
+ return {};
37
+ }
38
+
39
+ try {
40
+ const json = Buffer.from(encoded, 'base64url').toString('utf-8');
41
+ const parsed = JSON.parse(json);
42
+ if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) {
43
+ return {};
44
+ }
45
+ return parsed as Record<string, unknown>;
46
+ } catch {
47
+ return {};
48
+ }
49
+ }
50
+
51
+ function parseQuery(url: URL): Record<string, string | string[]> {
52
+ const query: Record<string, string | string[]> = {};
53
+ for (const [key, value] of url.searchParams) {
54
+ if (key in query) {
55
+ const existing = query[key];
56
+ if (Array.isArray(existing)) {
57
+ existing.push(value);
58
+ } else {
59
+ query[key] = [existing as string, value];
60
+ }
61
+ } else {
62
+ query[key] = value;
63
+ }
64
+ }
65
+ return query;
66
+ }
67
+
68
+ function parseCookies(cookieHeader: string | null): Record<string, string> {
69
+ const cookies: Record<string, string> = {};
70
+ if (!cookieHeader) {
71
+ return cookies;
72
+ }
73
+ for (const pair of cookieHeader.split(';')) {
74
+ const idx = pair.indexOf('=');
75
+ if (idx > 0) {
76
+ cookies[pair.slice(0, idx).trim()] = pair.slice(idx + 1).trim();
77
+ }
78
+ }
79
+ return cookies;
80
+ }
81
+
82
+ function extractRouteParams(req: Request): Record<string, string> {
83
+ const nativeParams = (req as Request & { params?: Record<string, string> }).params;
84
+ if (nativeParams && typeof nativeParams === 'object' && !Array.isArray(nativeParams)) {
85
+ return nativeParams;
86
+ }
87
+ return {};
88
+ }
89
+
90
+ function createContext(req: Request): Record<string, unknown> {
91
+ const ctx: Record<string, unknown> = Object.create(null);
92
+ setContextField(ctx, 'request', req);
93
+
94
+ // Initialize always-present VectorContext fields with defaults derived from the request
95
+ setContextField(ctx, 'params', extractRouteParams(req));
96
+
97
+ try {
98
+ setContextField(ctx, 'query', parseQuery(new URL(req.url)));
99
+ } catch {
100
+ setContextField(ctx, 'query', {});
101
+ }
102
+
103
+ setContextField(ctx, 'cookies', parseCookies(req.headers.get('cookie')));
104
+ setContextField(ctx, 'metadata', {});
105
+
106
+ const checkpointContext = parseCheckpointContext(req);
107
+ const allowedCheckpointKeys = ['metadata', 'content', 'validatedInput', 'authUser'] as const;
108
+ for (const key of allowedCheckpointKeys) {
109
+ if (!Object.prototype.hasOwnProperty.call(checkpointContext, key)) {
110
+ continue;
111
+ }
112
+ const value = checkpointContext[key];
113
+ setContextField(ctx, key, value);
114
+ }
115
+
116
+ return ctx;
117
+ }
118
+
119
+ function setContextField(target: Record<string, unknown>, key: string, value: unknown) {
120
+ const ownDescriptor = Object.getOwnPropertyDescriptor(target as object, key);
121
+ if (ownDescriptor && ownDescriptor.writable === false && typeof ownDescriptor.set !== 'function') {
122
+ return;
123
+ }
124
+
125
+ try {
126
+ target[key] = value;
127
+ return;
128
+ } catch {
129
+ // Fall back to own-property define when inherited Request field is readonly.
130
+ }
131
+
132
+ try {
133
+ Object.defineProperty(target, key, {
134
+ value,
135
+ writable: true,
136
+ configurable: true,
137
+ enumerable: true,
138
+ });
139
+ } catch {
140
+ // Ignore non-extensible context edge cases.
141
+ }
142
+ }
143
+
144
+ function addToRouteTable(method: string, path: string, handler: (ctx: any) => any) {
145
+ if (!routeTable[path]) {
146
+ routeTable[path] = Object.create(null);
147
+ }
148
+ routeTable[path][method.toUpperCase()] = async (req: Request) => {
149
+ const ctx = createContext(req);
150
+ const result = await handler(ctx);
151
+ if (result instanceof Response) return result;
152
+ return Response.json(result);
153
+ };
154
+ }
155
+
156
+ function registerModule(mod: Record<string, unknown>) {
157
+ for (const [name, value] of Object.entries(mod)) {
158
+ if (isRouteDefinition(value)) {
159
+ addToRouteTable(value.options.method, value.options.path, value.handler);
160
+ } else if (name === 'default' && typeof value === 'function') {
161
+ // Default export functions need path context \u2014 skip for now
162
+ }
163
+ }
164
+ }
165
+
166
+ ${a.join(`
167
+ `)}
168
+
169
+ // Health check endpoint for parent process
170
+ routeTable['/_vector/health'] = {
171
+ GET: () => Response.json({ status: 'ok', version: '${t.version}' }),
172
+ };
173
+
174
+ const server = Bun.serve({
175
+ unix: socketPath,
176
+ routes: routeTable,
177
+ fetch(req: Request) {
178
+ return Response.json(
179
+ { error: true, message: 'Not Found', statusCode: 404 },
180
+ { status: 404 }
181
+ );
182
+ },
183
+ });
184
+
185
+ // Signal readiness to parent process
186
+ process.stdout.write('READY\\n');
187
+ `}toImportSpecifier(e,t){let r=At(t,e).split(St).join("/");if(r.startsWith(".")||r.startsWith("/"))return r;return`./${r}`}}var Rt=()=>{};import{promises as Te}from"fs";import{join as Q,relative as Ce}from"path";class Le{storageDir;codec;constructor(e,t="gzip"){this.storageDir=e,this.codec=t}async packageVersion(e){let t=Q(this.storageDir,e),r=Q(Ht,`${e}${this.archiveSuffix()}`).replace(/\\/g,"/"),a=Q(this.storageDir,r);await Te.mkdir(Q(this.storageDir,Ht),{recursive:!0});let n=await ua(t),o=await this.buildArchiveBytes(t,a,n);return{archivePath:r,archiveHash:T(o),archiveSize:o.byteLength,codec:this.codec}}async buildArchiveBytes(e,t,r){let a=Bun.Archive;if(typeof a==="function"){let o=Object.fromEntries(r.map((c)=>{return[Ce(e,c).replace(/\\/g,"/"),Bun.file(c)]})),i=new a(o),d=new Uint8Array(await i.bytes()),l=this.codec==="gzip"?Bun.gzipSync(d):d;return await Bun.write(t,l),l}await this.buildArchiveWithTar(e,t,r);let n=await Te.readFile(t);return new Uint8Array(n.buffer,n.byteOffset,n.byteLength)}async buildArchiveWithTar(e,t,r){let a=r.map((l)=>Ce(e,l));if(a.length===0)throw new Error(`Cannot package checkpoint: no files found in "${e}"`);let n=this.codec==="gzip"?["-czf",t]:["-cf",t],o=Bun.spawn(["tar",...n,"-C",e,...a],{stdout:"pipe",stderr:"pipe"}),i=await o.exited;if(i===0)return;let d=await new Response(o.stderr).text();throw new Error(`Failed to package checkpoint archive with tar (exit ${i}): ${d.trim()}`)}archiveSuffix(){return this.codec==="gzip"?".tar.gz":".tar"}}async function ua(e){let t=[];return await Ot(e,t),t.filter((r)=>Ce(e,r).replace(/\\/g,"/")!=="manifest.json")}async function Ot(e,t){let r=await Te.readdir(e,{withFileTypes:!0});for(let a of r){let n=Q(e,a.name);if(a.isDirectory()){await Ot(n,t);continue}if(a.isFile())t.push(n)}}var Ht="_archives";var Dt=()=>{};import{createHash as ha}from"crypto";import{tmpdir as fa}from"os";import{isAbsolute as ga,join as Ne,resolve as ya}from"path";function jt(e){return ga(e)?e:ya(e)}function $t(e){return Buffer.byteLength(e,"utf8")<=xa}function va(e,t){let r=t.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/(^-+|-+$)/g,"").slice(0,12),a=ha("sha256").update(e).update("\x00").update(t).digest("hex").slice(0,16);return`vector-${r.length>0?`${r}-`:""}${a}.sock`}function Ea(){let e=new Set,t=process.env.VECTOR_CHECKPOINT_SOCKET_DIR?.trim();if(t)e.add(jt(t));if(process.platform!=="win32")e.add("/tmp"),e.add("/private/tmp");return e.add(jt(fa())),[...e]}function K(e,t){let r=Ne(e,t,wa);if(process.platform==="win32"||$t(r))return r;let a=va(e,t);for(let n of Ea()){let o=Ne(n,a);if($t(o))return o}return Ne("/tmp",a)}var wa="run.sock",xa=103;var Ae=()=>{};var Pt={};P(Pt,{CheckpointManager:()=>Mt});import{existsSync as M,promises as B}from"fs";import{join as D,resolve as _t}from"path";function Ba(e){if(e.codec)return e.codec;return(e.blobPath??e.storedPath??"").trim().toLowerCase().endsWith(".gz")?"gzip":"none"}class Mt{storageDir;maxCheckpoints;constructor(e={}){this.storageDir=_t(process.cwd(),e.storageDir??ka),this.maxCheckpoints=e.maxCheckpoints??10}getStorageDir(){return this.storageDir}versionDir(e){return D(this.storageDir,e)}socketPath(e){return K(this.storageDir,e)}async ensureStorageDir(){await B.mkdir(this.storageDir,{recursive:!0})}async publish(e){await this.ensureStorageDir();let t=this.versionDir(e.version);await B.mkdir(t,{recursive:!0});let r=new Ie,a=await r.generate({version:e.version,outputDir:t,routesDir:_t(process.cwd(),e.routesDir),socketPath:this.socketPath(e.version)}),o=await new ke().bundle({entrypointPath:a,outputDir:t}),i=new Ee(this.storageDir),d=await i.collect(e.embeddedAssetPaths??[],e.sidecarAssetPaths??[]);i.validateBudgets(d);let l={formatVersion:ge,version:e.version,createdAt:new Date().toISOString(),entrypoint:"checkpoint.js",routes:r.getDiscoveredRoutes(),assets:d,bundleHash:o.hash,bundleSize:o.size,checkpointArchivePath:void 0,checkpointArchiveHash:void 0,checkpointArchiveSize:void 0,checkpointArchiveCodec:void 0};await this.writeManifest(e.version,l);try{await B.unlink(a)}catch{}let m=await new Le(this.storageDir).packageVersion(e.version);return l.checkpointArchivePath=m.archivePath,l.checkpointArchiveHash=m.archiveHash,l.checkpointArchiveSize=m.archiveSize,l.checkpointArchiveCodec=m.codec,await this.writeManifest(e.version,l),await this.pruneOld(),l}async readManifest(e){let t=D(this.versionDir(e),"manifest.json"),r=await B.readFile(t,"utf-8");return this.normalizeManifest(JSON.parse(r))}async writeManifest(e,t){let r=D(this.versionDir(e),"manifest.json");await B.writeFile(r,JSON.stringify(t,null,2),"utf-8")}async listVersions(){if(!M(this.storageDir))return[];let e=await B.readdir(this.storageDir),t=[];for(let r of e){let a=D(this.storageDir,r,"manifest.json");if(M(a))try{let n=await B.readFile(a,"utf-8");t.push(this.normalizeManifest(JSON.parse(n)))}catch{}}return t.sort((r,a)=>new Date(a.createdAt).getTime()-new Date(r.createdAt).getTime()),t}async getActive(){let e=D(this.storageDir,Ut);if(!M(e))return null;try{let t=await B.readFile(e,"utf-8");return JSON.parse(t)}catch{return null}}async setActive(e){let t=this.versionDir(e);if(!M(t))throw new Error(`Checkpoint version ${e} does not exist`);let r=D(t,"manifest.json");if(!M(r))throw new Error(`Checkpoint version ${e} has no manifest`);await this.ensureStorageDir();let a={version:e,activatedAt:new Date().toISOString()},n=D(this.storageDir,Ut);await B.writeFile(n,JSON.stringify(a,null,2),"utf-8")}async remove(e){if((await this.getActive())?.version===e)throw new Error(`Cannot remove active checkpoint version ${e}. Rollback to a different version first.`);let r=this.versionDir(e);if(!M(r))throw new Error(`Checkpoint version ${e} does not exist`);await B.rm(r,{recursive:!0,force:!0})}async pruneOld(){if(this.maxCheckpoints<=0)return;let e=await this.listVersions();if(e.length<=this.maxCheckpoints)return;let t=await this.getActive(),r=e.slice(this.maxCheckpoints);for(let a of r){if(t?.version===a.version)continue;try{let n=this.versionDir(a.version);await B.rm(n,{recursive:!0,force:!0})}catch{}}}normalizeManifest(e){let t=(e.assets??[]).map((r)=>({...r,contentHash:r.contentHash??r.hash,contentSize:r.contentSize??r.size,blobPath:r.blobPath??r.storedPath,blobHash:r.blobHash,blobSize:r.blobSize,codec:Ba(r)}));return{formatVersion:e.formatVersion??ge,version:e.version??"unknown",createdAt:e.createdAt??new Date(0).toISOString(),entrypoint:e.entrypoint??"checkpoint.js",routes:e.routes??[],assets:t,bundleHash:e.bundleHash??"",bundleSize:e.bundleSize??0,checkpointArchivePath:e.checkpointArchivePath,checkpointArchiveHash:e.checkpointArchiveHash,checkpointArchiveSize:e.checkpointArchiveSize,checkpointArchiveCodec:e.checkpointArchiveCodec}}}var ka=".vector/checkpoints",Ut="active.json";var zt=E(()=>{Tt();Lt();Rt();Dt();Ae()});function Ia(e){let t=e.trim();if(!t)return null;if(t==="READY")return{type:"ready"};try{return JSON.parse(t)}catch{return null}}async function Jt(e,t=1e4){return new Promise((r,a)=>{let n=!1,o=e.getReader(),i=new TextDecoder,d="";function l(p){if(n)return;n=!0,clearTimeout(c);try{o.releaseLock()}catch{}p()}let c=setTimeout(()=>{l(()=>a(new Error(`Checkpoint process did not become ready within ${t}ms`)))},t),m=(p)=>{let h=Ia(p);if(h?.type==="ready")return l(()=>r()),"ready";if(h?.type==="error")return l(()=>a(new Error(`Checkpoint process error: ${h.message}`))),"error";return"continue"},s=()=>{let p=d.indexOf(`
188
+ `);while(p!==-1){let h=d.slice(0,p);d=d.slice(p+1);let u=m(h);if(u!=="continue")return u;p=d.indexOf(`
189
+ `)}return"continue"};(async()=>{try{while(!0){let{done:p,value:h}=await o.read();if(p){d+=i.decode();let f=d.trim();if(f.length>0){if(m(f)!=="continue")return}l(()=>a(new Error("Checkpoint process stdout closed before READY signal")));return}if(d+=i.decode(h,{stream:!0}),d.length>1048576){l(()=>a(new Error("Checkpoint process stdout exceeded 1048576 chars before READY")));return}if(s()!=="continue")return}}catch(p){l(()=>a(p))}})()})}import{availableParallelism as Ta,cpus as Ca}from"os";class Se{workers=[];idleWorkers=[];queue=[];activeJobsByWorker=new Map;nextJobId=1;disposed=!1;constructor(e=Na()){let t=Sa(e),r=Ra();for(let a=0;a<t;a++){let n=new Worker(r.href);n.onmessage=(o)=>this.handleWorkerMessage(n,o),n.onerror=(o)=>this.handleWorkerError(n,o),this.workers.push(n),this.idleWorkers.push(n)}}async decompress(e,t){if(t==="none")return new Uint8Array(e);if(this.disposed)throw new Error("Checkpoint worker decompressor is disposed");let r=new Uint8Array(e);return await new Promise((a,n)=>{let o=this.nextJobId++;this.queue.push({id:o,request:{id:o,codec:t,input:r.buffer},resolve:a,reject:n}),this.pump()})}async dispose(){if(this.disposed)return;this.disposed=!0;let e=new Error("Checkpoint worker decompressor disposed");this.failAll(e);for(let t of this.workers)try{t.terminate()}catch{}this.workers=[],this.idleWorkers=[],this.activeJobsByWorker.clear()}pump(){while(this.idleWorkers.length>0&&this.queue.length>0){let e=this.idleWorkers.pop(),t=this.queue.shift();this.activeJobsByWorker.set(e,t),e.postMessage(t.request,[t.request.input])}}handleWorkerMessage(e,t){let r=this.activeJobsByWorker.get(e);if(this.activeJobsByWorker.delete(e),!this.disposed)this.idleWorkers.push(e);if(!r){this.pump();return}let a=t.data;if(a.error)r.reject(new Error(a.error));else if(a.output instanceof ArrayBuffer)r.resolve(new Uint8Array(a.output));else r.reject(new Error("Worker returned no output"));this.pump()}handleWorkerError(e,t){let r=this.activeJobsByWorker.get(e);this.activeJobsByWorker.delete(e),this.idleWorkers=this.idleWorkers.filter((o)=>o!==e);let a=t.message?.trim()||"Checkpoint decompression worker crashed",n=new Error(a);if(r)r.reject(n);this.failAll(n),this.dispose().catch(()=>{})}failAll(e){let t=this.queue.splice(0,this.queue.length);for(let r of t)r.reject(e);for(let r of this.activeJobsByWorker.values())r.reject(e);this.activeJobsByWorker.clear()}}function Na(){let e=Aa(),t=Math.max(1,e-1);return Math.max(1,Math.min(La,t))}function Aa(){try{let t=Ta();if(Number.isFinite(t)&&t>0)return t}catch{}let e=Ca().length;return Number.isFinite(e)&&e>0?e:1}function Sa(e){if(!Number.isFinite(e)||e<=0)return 1;return Math.max(1,Math.floor(e))}function Ra(){if(import.meta.url.endsWith(".ts"))return new URL("./decompress-worker.ts",import.meta.url);return new URL("./decompress-worker.js",import.meta.url)}var La=4;var Ft=()=>{};import{existsSync as ee,promises as g}from"fs";import{dirname as Gt,extname as Ha,join as C,relative as Oa}from"path";class Re{verifyChecksums;materializedDirName;lockTimeoutMs;constructor(e={}){this.verifyChecksums=e.verifyChecksums??!0,this.materializedDirName=e.materializedDirName??Da,this.lockTimeoutMs=e.lockTimeoutMs??ja}async materialize(e,t){let r=C(t,e.version),a=C(r,".assets.ready.json"),n=C(r,".assets.lock"),o=vt(e.assets);if(await this.isReady(a,o,e.assets,C(r,this.materializedDirName)))return;await this.acquireLock(n);try{if(await this.isReady(a,o,e.assets,C(r,this.materializedDirName)))return;let i=C(r,this.materializedDirName);await g.rm(i,{recursive:!0,force:!0}),await g.mkdir(i,{recursive:!0});let d=new Se;try{for(let c of e.assets){let m=await this.materializeAsset(c,t,r,i,d);c.materializedPath=m}}finally{await d.dispose()}let l={fingerprint:o,createdAt:new Date().toISOString()};await g.writeFile(a,JSON.stringify(l,null,2),"utf-8")}finally{await g.rm(n,{recursive:!0,force:!0})}}async materializeAsset(e,t,r,a,n){let o=this.resolveSourcePath(e,t);if(!ee(o))throw new Error(`Checkpoint asset blob not found: ${o}`);let i=await g.readFile(o),d=new Uint8Array(i.buffer,i.byteOffset,i.byteLength),l=e.blobHash;if(this.verifyChecksums&&l&&T(d)!==l)throw new Error(`Checkpoint asset blob checksum mismatch for ${e.logicalPath}`);let c=e.codec??(e.blobHash?"gzip":"none"),m=await n.decompress(d,c),s=e.contentHash??e.hash;if(this.verifyChecksums&&s&&T(m)!==s)throw new Error(`Checkpoint asset content checksum mismatch for ${e.logicalPath}`);let p=await this.writeDecompressedCache(e,t,m),h=Y(e.logicalPath),u=C(a,h);return await g.mkdir(Gt(u),{recursive:!0}),await g.rm(u,{force:!0}),await this.linkWithFallback(p,u),_a(Oa(r,u))}async writeDecompressedCache(e,t,r){let a=e.contentHash??e.hash,n=Ha(e.logicalPath)||".bin",o=C(t,"_assets/cache",`${a}${n}`);if(await g.mkdir(Gt(o),{recursive:!0}),ee(o)){if(!this.verifyChecksums)return o;let i=await g.readFile(o),d=new Uint8Array(i.buffer,i.byteOffset,i.byteLength);if(T(d)===a)return o}return await g.writeFile(o,r),o}resolveSourcePath(e,t){let r=e.blobPath??e.storedPath;if(ye(r))return r;return C(t,r)}async linkWithFallback(e,t){try{await g.link(e,t);return}catch{}try{await g.symlink(e,t);return}catch{}await g.copyFile(e,t)}async acquireLock(e){let t=Date.now()+this.lockTimeoutMs;while(Date.now()<t){try{await g.mkdir(e);return}catch(r){if(!Ua(r))throw r}await Ma($a)}throw new Error(`Timed out waiting for checkpoint asset lock: ${e}`)}async isReady(e,t,r,a){if(!ee(e))return!1;try{if(JSON.parse(await g.readFile(e,"utf-8")).fingerprint!==t)return!1;for(let o of r){let i=C(a,Y(o.logicalPath));if(!ee(i))return!1}return!0}catch{return!1}}}function _a(e){return e.replace(/\\/g,"/")}function Ua(e){return typeof e==="object"&&e!==null&&"code"in e&&e.code==="EEXIST"}function Ma(e){return new Promise((t)=>setTimeout(t,e))}var Da="_materialized",ja=15000,$a=50;var Yt=E(()=>{we();Ft()});var qt={};P(qt,{CheckpointProcessManager:()=>Zt});import{existsSync as Qt,promises as Pa,unlinkSync as za}from"fs";import{dirname as Ja,join as Vt}from"path";class Zt{running=new Map;pending=new Map;readyTimeoutMs;idleTimeoutMs;idleTimers=new Map;lastUsedAt=new Map;materializer;constructor(e=Wt){if(typeof e==="number")this.readyTimeoutMs=e,this.idleTimeoutMs=Xt;else this.readyTimeoutMs=e.readyTimeoutMs??Wt,this.idleTimeoutMs=e.idleTimeoutMs??Xt;this.materializer=new Re}async spawn(e,t){if(this.running.has(e.version))return this.running.get(e.version);if(this.pending.has(e.version))return this.pending.get(e.version);let r=this.doSpawn(e,t);this.pending.set(e.version,r);try{return await r}finally{this.pending.delete(e.version)}}async doSpawn(e,t){let r=Vt(t,e.version),a=Vt(r,e.entrypoint),n=K(t,e.version);if(!Qt(a))throw new Error(`Checkpoint bundle not found: ${a}`);await this.materializer.materialize(e,t),await Pa.mkdir(Ja(n),{recursive:!0}),this.tryUnlinkSocket(n);let o=Bun.spawn(["bun","run",a],{env:{...process.env,VECTOR_CHECKPOINT_SOCKET:n,VECTOR_CHECKPOINT_VERSION:e.version},stdout:"pipe",stderr:"inherit"});if(!o.stdout)throw o.kill("SIGTERM"),new Error(`Checkpoint process for ${e.version} did not provide stdout`);try{await Jt(o.stdout,this.readyTimeoutMs)}catch(d){throw o.kill("SIGTERM"),d}let i={version:e.version,socketPath:n,process:o,pid:o.pid};return this.running.set(e.version,i),this.lastUsedAt.set(e.version,Date.now()),this.scheduleIdleCheck(e.version),i}markUsed(e){if(!this.running.has(e))return;this.lastUsedAt.set(e,Date.now())}async stop(e){let t=this.running.get(e);if(!t)return;if(this.running.delete(e),this.clearIdleTimer(e),this.lastUsedAt.delete(e),t.process.kill("SIGTERM"),!await Promise.race([t.process.exited.then(()=>!0),new Promise((a)=>setTimeout(()=>a(!1),Fa))]))try{t.process.kill("SIGKILL"),await t.process.exited}catch{}this.tryUnlinkSocket(t.socketPath)}async stopAll(){let e=[...this.running.keys()];for(let t of e)await this.stop(t)}isRunning(e){return this.running.has(e)}getRunning(e){return this.running.get(e)}async health(e){let t=this.running.get(e);if(!t)return!1;try{return(await fetch("http://localhost/_vector/health",{unix:t.socketPath,signal:AbortSignal.timeout(2000)})).ok}catch{return!1}}getRunningVersions(){return[...this.running.keys()]}scheduleIdleCheck(e,t=this.idleTimeoutMs){if(this.clearIdleTimer(e),this.idleTimeoutMs<=0)return;let r=setTimeout(()=>{this.handleIdleCheck(e)},Math.max(1,t));if(typeof r.unref==="function")r.unref();this.idleTimers.set(e,r)}async handleIdleCheck(e){if(!this.running.has(e))return;let t=this.lastUsedAt.get(e)??0,r=Date.now()-t,a=this.idleTimeoutMs-r;if(a>0){this.scheduleIdleCheck(e,a);return}try{await this.stop(e)}catch(n){console.error(`[CheckpointProcessManager] Failed to stop idle checkpoint ${e}:`,n)}}clearIdleTimer(e){let t=this.idleTimers.get(e);if(!t)return;clearTimeout(t),this.idleTimers.delete(e)}tryUnlinkSocket(e){try{if(Qt(e))za(e)}catch{}}}var Wt=1e4,Xt=600000,Fa=5000;var Kt=E(()=>{Yt();Ae()});var tr={};P(tr,{CheckpointResolver:()=>er});class er{manager;processManager;versionHeader;cacheKeyOverride;allowFallbackVersionHeader;pendingVersionResolves=new Map;constructor(e,t,r={}){this.manager=e,this.processManager=t,this.versionHeader=Ga(r.versionHeader??"x-vector-checkpoint-version"),this.cacheKeyOverride=r.cacheKeyOverride===!0,this.allowFallbackVersionHeader=r.versionHeader===void 0}async resolve(e){let t=this.getRequestedVersion(e);if(!t)return null;return await this.resolveVersion(t)}getRequestedVersion(e){return this.getRequestedHeader(e)?.value??null}getCacheKeyOverrideValue(e){if(!this.cacheKeyOverride)return null;let t=this.getRequestedHeader(e);if(!t)return null;return`${t.name}:${t.value}`}getRequestedHeader(e){let t=e.headers.get(this.versionHeader);if(t&&t.trim().length>0)return{name:this.versionHeader,value:t.trim()};if(this.allowFallbackVersionHeader&&this.versionHeader!=="x-vector-checkpoint"){let r=e.headers.get("x-vector-checkpoint");if(r&&r.trim().length>0)return{name:"x-vector-checkpoint",value:r.trim()}}return null}async resolveVersion(e){let t=this.processManager.getRunning(e);if(!t){let r=this.pendingVersionResolves.get(e);if(r){let o=await r;if(!o)return null;return this.processManager.markUsed(e),o}let a=(async()=>{try{let o=await this.manager.readManifest(e);return(await this.processManager.spawn(o,this.manager.getStorageDir())).socketPath}catch{return null}})();this.pendingVersionResolves.set(e,a);let n=await a;if(this.pendingVersionResolves.delete(e),!n)return null;return this.processManager.markUsed(e),n}return this.processManager.markUsed(e),t.socketPath}invalidateCache(){}}function Ga(e){let t=e.trim().toLowerCase();return t.length>0?t:"x-vector-checkpoint-version"}var ar={};P(ar,{CheckpointForwarder:()=>rr,CHECKPOINT_CONTEXT_HEADER:()=>Ya});class rr{async forward(e,t,r){try{let a=Wa(r),n=Qa(e.headers,a),o=await fetch(e.url,{method:e.method,headers:n,body:e.body,unix:t,duplex:e.body?"half":void 0});return new Response(o.body,{status:o.status,statusText:o.statusText,headers:new Headers(o.headers)})}catch(a){return console.error("[CheckpointForwarder] Forward failed:",a),new Response(JSON.stringify({error:!0,message:"Checkpoint unavailable",statusCode:503}),{status:503,headers:{"content-type":"application/json"}})}}}function Qa(e,t){let r=new Headers(e);if(Va(r),t)r.set("x-vector-checkpoint-context",t);return r}function Va(e){let t=e.get("connection");if(t)for(let r of t.split(",")){let a=r.trim().toLowerCase();if(a)e.delete(a)}e.delete("connection"),e.delete("keep-alive"),e.delete("proxy-authenticate"),e.delete("proxy-authorization"),e.delete("te"),e.delete("trailer"),e.delete("transfer-encoding"),e.delete("upgrade")}function Wa(e){if(!e)return null;if(Object.keys(e).length===0)return null;try{return Buffer.from(JSON.stringify(e),"utf-8").toString("base64url")}catch{return null}}var Ya="x-vector-checkpoint-context";var or={};P(or,{CheckpointGateway:()=>nr});class nr{resolver;forwarder;constructor(e,t){this.resolver=e,this.forwarder=t}getRequestedVersion(e){return this.resolver.getRequestedVersion(e)}getCacheKeyOverrideValue(e){return this.resolver.getCacheKeyOverrideValue(e)}async handle(e,t){let r=this.getRequestedVersion(e),a=await this.resolver.resolve(e);if(!a){if(r)return new Response(JSON.stringify({error:!0,message:`Requested checkpoint version "${r}" is unavailable`,statusCode:503}),{status:503,headers:{"content-type":"application/json"}});return null}return await this.forwarder.forward(e,a,t)}}var A={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},$={PORT:3000,HOSTNAME:"localhost",ROUTES_DIR:"./routes",CACHE_TTL:0,CORS_MAX_AGE:86400},z={JSON:"application/json",TEXT:"text/plain",HTML:"text/html",FORM_URLENCODED:"application/x-www-form-urlencoded",MULTIPART:"multipart/form-data"};var je={NOT_FOUND:new Response(JSON.stringify({error:!0,message:"Not Found",statusCode:404}),{status:404,headers:{"content-type":"application/json"}})};class te{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.");if(!e||typeof e!=="object"||!e.request)throw new Error("Authentication context is invalid: missing request");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 re{cacheHandler=null;memoryCache=new Map;cleanupInterval=null;inflight=new Map;setCacheHandler(e){this.cacheHandler=e}clearCacheHandler(){this.cacheHandler=null}async get(e,t,r=$.CACHE_TTL){if(r<=0)return t();if(this.cacheHandler)return this.cacheHandler(e,t,r);return this.getFromMemoryCache(e,t,r)}async getFromMemoryCache(e,t,r){let a=Date.now(),n=this.memoryCache.get(e);if(this.isCacheValid(n,a))return this.cloneCachedValue(n.value);if(this.inflight.has(e)){let i=await this.inflight.get(e);return this.cloneCachedValue(i)}let o=(async()=>{let i=await t();return this.setInMemoryCache(e,i,r),i})();this.inflight.set(e,o);try{return await o}finally{this.inflight.delete(e)}}isCacheValid(e,t){return e!==void 0&&e.expires>t}setInMemoryCache(e,t,r){let a=Date.now()+r*1000;this.memoryCache.set(e,{value:this.cloneForStore(t),expires:a}),this.scheduleCleanup()}cloneForStore(e){if(e instanceof Response)return e.clone();return e}cloneCachedValue(e){if(e instanceof Response)return e.clone();return e}scheduleCleanup(){if(this.cleanupInterval)return;let e=setInterval(()=>{this.cleanupExpired()},60000);if(typeof e.unref==="function")e.unref();this.cleanupInterval=e}cleanupExpired(){let e=Date.now();for(let[t,r]of this.memoryCache.entries())if(r.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,r=$.CACHE_TTL){if(r<=0)return;if(this.cacheHandler){await this.cacheHandler(e,async()=>t,r);return}this.setInMemoryCache(e,t,r)}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 r=e._parsedUrl??new URL(e.url),a=t?.authUser?.id!=null?String(t.authUser.id):"anonymous";return`${e.method}:${r.pathname}:${r.search}:${a}`}}import{promises as $e}from"fs";import{dirname as _e,relative as lr}from"path";class ae{outputPath;constructor(e="./.vector/routes.generated.ts"){this.outputPath=e}async generate(e){let t=_e(this.outputPath);await $e.mkdir(t,{recursive:!0});let r=[],a=new Map;for(let d of e){if(!a.has(d.path))a.set(d.path,[]);a.get(d.path).push(d)}let n=0,o=[];for(let[d,l]of a){let c=lr(_e(this.outputPath),d).replace(/\\/g,"/").replace(/\.(ts|js)$/,""),m=`route_${n++}`,s=l.filter((p)=>p.name!=="default").map((p)=>p.name);if(l.some((p)=>p.name==="default"))if(s.length>0)r.push(`import ${m}, { ${s.join(", ")} } from '${c}';`);else r.push(`import ${m} from '${c}';`);else if(s.length>0)r.push(`import { ${s.join(", ")} } from '${c}';`);for(let p of l){let h=p.name==="default"?m:p.name;o.push(` ${h},`)}}let i=`// This file is auto-generated. Do not edit manually.
3
190
  // Generated at: ${new Date().toISOString()}
4
191
 
5
- ${d.join(`
192
+ ${r.join(`
6
193
  `)}
7
194
 
8
195
  export const routes = [
@@ -11,15 +198,15 @@ ${o.join(`
11
198
  ];
12
199
 
13
200
  export default routes;
14
- `;await ee.writeFile(this.outputPath,i,"utf-8")}async generateDynamic(e){let t=[];for(let d of e){let n=JSON.stringify({method:d.method,path:d.options.path,options:d.options});t.push(` await import('${d.path}').then(m => ({
15
- ...${n},
16
- handler: m.${d.name==="default"?"default":d.name}
201
+ `;await $e.writeFile(this.outputPath,i,"utf-8")}async generateDynamic(e){let t=[];for(let r of e){let a=JSON.stringify({method:r.method,path:r.options.path,options:r.options});t.push(` await import('${r.path}').then(m => ({
202
+ ...${a},
203
+ handler: m.${r.name==="default"?"default":r.name}
17
204
  }))`)}return`export const loadRoutes = async () => {
18
205
  return Promise.all([
19
206
  ${t.join(`,
20
207
  `)}
21
208
  ]);
22
- };`}}import{existsSync as Me,promises as de}from"fs";import{join as Ce,relative as ne,resolve as He,sep as re}from"path";class M{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=He(process.cwd(),e),this.excludePatterns=t||M.DEFAULT_EXCLUDE_PATTERNS}async scan(){let e=[];if(!Me(this.routesDir))return[];try{await this.scanDirectory(this.routesDir,e)}catch(t){if(t.code==="ENOENT")return console.warn(` \u2717 Routes directory not accessible: ${this.routesDir}`),[];throw t}return e}isExcluded(e){let t=ne(this.routesDir,e);for(let d of this.excludePatterns){let n=d.replace(/\./g,"\\.").replace(/\*\*/g,"__GLOBSTAR__").replace(/\*/g,"[^/]*").replace(/__GLOBSTAR__/g,".*").replace(/\?/g,"."),r=new RegExp(`^${n}$`),o=t.split(re).pop()||"";if(r.test(t)||r.test(o))return!0}return!1}async scanDirectory(e,t,d=""){let n=await de.readdir(e);for(let r of n){let o=Ce(e,r);if((await de.stat(o)).isDirectory()){let a=d?`${d}/${r}`:r;await this.scanDirectory(o,t,a)}else if(r.endsWith(".ts")||r.endsWith(".js")){if(this.isExcluded(o))continue;let a=ne(this.routesDir,o).replace(/\.(ts|js)$/,"").split(re).join("/");try{let c=await import(process.platform==="win32"?`file:///${o.replace(/\\/g,"/")}`:o);if(c.default&&typeof c.default==="function")t.push({name:"default",path:o,method:"GET",options:{method:"GET",path:`/${a}`,expose:!0}});for(let[m,b]of Object.entries(c)){if(m==="default")continue;if(b&&typeof b==="object"&&"entry"in b&&"options"in b&&"handler"in b){let p=b;t.push({name:m,path:o,method:p.options.method,options:p.options})}else if(Array.isArray(b)&&b.length>=4){let[p,,,x]=b;t.push({name:m,path:o,method:p,options:{method:p,path:x,expose:!0}})}}}catch(s){console.error(`Failed to load route from ${o}:`,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 C{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 d of this.beforeHandlers){let n=await d(t);if(n instanceof Response)return n;t=n}return t}async executeFinally(e,t){if(this.finallyHandlers.length===0)return e;let d=e;for(let n of this.finallyHandlers)try{d=await n(d,t)}catch(r){console.error("After middleware error:",r)}return d}clone(){let e=new C;return e.beforeHandlers=[...this.beforeHandlers],e.finallyHandlers=[...this.finallyHandlers],e}clear(){this.beforeHandlers=[],this.finallyHandlers=[]}}function H(e){return process.platform==="win32"?`file:///${e.replace(/\\/g,"/")}`:e}function P(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 oe(e){let t=e?.["~standard"];return!!t&&typeof t==="object"&&typeof t.validate==="function"&&t.version===1}async function ae(e,t){let d=await e["~standard"].validate(t),n=d?.issues;if(Array.isArray(n)&&n.length>0)return{success:!1,issues:n};return{success:!0,value:d?.value}}function ie(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 Oe(e){if(!Array.isArray(e))return[];let t=[];for(let d=0;d<e.length;d++){let n=e[d],r=n;if(n&&typeof n==="object"&&"key"in n)r=n.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 _(e,t){let d=[];for(let n=0;n<e.length;n++){let r=e[n],o=r,i={message:typeof o?.message==="string"&&o.message.length>0?o.message:"Invalid value",path:Oe(o?.path)};if(typeof o?.code==="string")i.code=o.code;if(t)i.raw=r;d.push(i)}return d}function J(e,t){return{error:!0,message:"Validation failed",statusCode:422,source:"validation",target:e,issues:t,timestamp:new Date().toISOString()}}class N{middlewareManager;authManager;cacheManager;routeBooleanDefaults={};developmentMode=void 0;routeDefinitions=[];routeTable=Object.create(null);routeMatchers=[];corsHeadersEntries=null;corsHandler=null;constructor(e,t,d){this.middlewareManager=e,this.authManager=t,this.cacheManager=d}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},d=this.routeBooleanDefaults,n=["auth","expose","rawRequest","validate","rawResponse"];for(let r of n)if(t[r]===void 0&&d[r]!==void 0)t[r]=d[r];return t}route(e,t){let d=this.applyRouteBooleanDefaults(e),n=d.method.toUpperCase(),r=d.path,o=this.wrapHandler(d,t),i=this.getOrCreateMethodMap(r);i[n]=o,this.routeDefinitions.push({method:n,path:r,options:d})}addRoute(e){let[t,,d,n]=e;if(!n)return;let r=this.getOrCreateMethodMap(n);r[t.toUpperCase()]=d[0];let o=t.toUpperCase();this.routeDefinitions.push({method:o,path:n,options:{method:o,path:n,expose:!0}})}bulkAddRoutes(e){for(let t of e)this.addRoute(t)}addStaticRoute(e,t){let d=this.routeTable[e];if(d&&!(d 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 d=this.routeTable[t.path];if(!d||d instanceof Response)continue;for(let[n,r]of Object.entries(d))e.push([n,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 v.badRequest("Malformed request URL")}e._parsedUrl=t;let d=t.pathname;for(let n of this.routeMatchers){let r=n.path,o=this.routeTable[r];if(!o)continue;if(o instanceof Response)continue;let i=o;if(e.method==="OPTIONS"||e.method in i){let a=d.match(n.regex);if(a){try{e.params=a.groups??{}}catch{}let s=i[e.method]??i.GET;if(s){let c=await s(e);if(c)return c}}}}return j.NOT_FOUND.clone()}prepareRequest(e,t){if(!e.context)e.context={};let d=!!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||d))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 n=this._parsedUrl??new URL(this.url),r=N.parseQuery(n);return Object.defineProperty(this,"query",{value:r,writable:!0,configurable:!0,enumerable:!0}),r},set(n){Object.defineProperty(this,"query",{value:n,writable:!0,configurable:!0,enumerable:!0})},configurable:!0,enumerable:!0})}catch{let n=e._parsedUrl??new URL(e.url);try{e.query=N.parseQuery(n)}catch{}}if(!Object.getOwnPropertyDescriptor(e,"cookies"))Object.defineProperty(e,"cookies",{get(){let n=this.headers.get("cookie")??"",r={};if(n)for(let o of n.split(";")){let i=o.indexOf("=");if(i>0)r[o.slice(0,i).trim()]=o.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 d=e.params;if(d&&typeof d==="object"&&!Array.isArray(d)&&Object.keys(d).length>0)return;let n;try{n=(e._parsedUrl??new URL(e.url)).pathname}catch{return}let r=n.match(t);if(!r?.groups)return;return r.groups}wrapHandler(e,t){let d=e.path,n=d.includes(":")?P(d):null;return async(r)=>{let o=r,i=this.resolveFallbackParams(r,n);this.prepareRequest(o,{params:i,route:d,metadata:e.metadata});try{if(e.expose===!1)return v.forbidden("Forbidden");let a=await this.middlewareManager.executeBefore(o);if(a instanceof Response)return a;let s=a;if(e.auth)try{await this.authManager.authenticate(s)}catch(u){return v.unauthorized(u instanceof Error?u.message:"Authentication failed",e.responseContentType)}if(!e.rawRequest&&s.method!=="GET"&&s.method!=="HEAD"){let u=null;try{let f=s.headers.get("content-type");if(f?.startsWith("application/json"))u=await s.json();else if(f?.startsWith("application/x-www-form-urlencoded"))u=Object.fromEntries(await s.formData());else if(f?.startsWith("multipart/form-data"))u=await s.formData();else u=await s.text()}catch{u=null}this.setContentAndBodyAlias(s,u)}let c=await this.validateInputSchema(s,e);if(c)return c;let m,b=e.cache;if(b&&typeof b==="number"&&b>0){let u=this.cacheManager.generateKey(s,{authUser:s.authUser});m=await this.cacheManager.get(u,async()=>{let f=await t(s);if(f instanceof Response)return{_isResponse:!0,body:await f.text(),status:f.status,headers:Object.fromEntries(f.headers.entries())};return f},b)}else if(b&&typeof b==="object"&&b.ttl){let u=b.key||this.cacheManager.generateKey(s,{authUser:s.authUser});m=await this.cacheManager.get(u,async()=>{let f=await t(s);if(f instanceof Response)return{_isResponse:!0,body:await f.text(),status:f.status,headers:Object.fromEntries(f.headers.entries())};return f},b.ttl)}else m=await t(s);if(m&&typeof m==="object"&&m._isResponse===!0)m=new Response(m.body,{status:m.status,headers:m.headers});let p;if(e.rawResponse||m instanceof Response)p=m instanceof Response?m:new Response(m);else p=D(200,m,e.responseContentType);p=await this.middlewareManager.executeFinally(p,s);let x=this.corsHeadersEntries;if(x)for(let[u,f]of x)p.headers.set(u,f);else{let u=this.corsHandler;if(u)p=u(p,s)}return p}catch(a){if(a instanceof Response)return a;return console.error("Route handler error:",a),v.internalServerError(a instanceof Error?a.message:String(a),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 d=e.content;if(t.rawRequest&&e.method!=="GET"&&e.method!=="HEAD")try{d=await e.clone().text()}catch{d=null}return{params:e.params??{},query:e.query??{},headers:Object.fromEntries(e.headers.entries()),cookies:e.cookies??{},body:d}}applyValidatedInput(e,t){if(e.validatedInput=t,!t||typeof t!=="object")return;let d=t;if("params"in d)try{e.params=d.params}catch{}if("query"in d)try{e.query=d.query}catch{}if("cookies"in d)try{e.cookies=d.cookies}catch{}if("body"in d)this.setContentAndBodyAlias(e,d.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 d=t.schema?.input;if(!d)return null;if(t.validate===!1)return null;if(!oe(d))return v.internalServerError("Invalid route schema configuration",t.responseContentType);let n=this.isDevelopmentMode(),r=await this.buildInputValidationPayload(e,t);try{let o=await ae(d,r);if(o.success===!1){let i=_(o.issues,n);return D(422,J("input",i),t.responseContentType)}return this.applyValidatedInput(e,o.value),null}catch(o){let i=ie(o);if(i){let a=_(i,n);return D(422,J("input",a),t.responseContentType)}return v.internalServerError(o instanceof Error?o.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 d=Object.create(null);return this.routeTable[e]=d,this.addRouteMatcher(e),d}addRouteMatcher(e){if(this.routeMatchers.some((t)=>t.path===e))return;this.routeMatchers.push({path:e,regex:P(e),specificity:this.routeSpecificityScore(e)}),this.routeMatchers.sort((t,d)=>{if(t.specificity!==d.specificity)return d.specificity-t.specificity;return t.path.localeCompare(d.path)})}removeRouteMatcher(e){this.routeMatchers=this.routeMatchers.filter((t)=>t.path!==e)}static parseQuery(e){let t={};for(let[d,n]of e.searchParams)if(d in t){let r=t[d];if(Array.isArray(r))r.push(n);else t[d]=[r,n]}else t[d]=n;return t}routeSpecificityScore(e){let o=e.split("/").filter(Boolean),i=0;for(let a of o)if(a.includes("*"))i+=1;else if(a.startsWith(":"))i+=10;else i+=1000;if(i+=e.length,!e.includes(":")&&!e.includes("*"))i+=1e4;return i}}import{existsSync as ge}from"fs";import{join as Ke}from"path";function se(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 le(e){return typeof e.origin==="string"&&e.origin==="*"&&e.credentials||Array.isArray(e.origin)||typeof e.origin==="function"}function ce(e,t,d){let n={};if(e){if(n["access-control-allow-origin"]=e,n["access-control-allow-methods"]=t.allowMethods,n["access-control-allow-headers"]=t.allowHeaders,n["access-control-expose-headers"]=t.exposeHeaders,n["access-control-max-age"]=String(t.maxAge),t.credentials)n["access-control-allow-credentials"]="true";if(d)n.vary="Origin"}return n}function Te(e,t){if(!e)return t;let d=e.split(",").map((r)=>r.trim()).filter(Boolean);if(!d.map((r)=>r.toLowerCase()).includes(t.toLowerCase()))d.push(t);return d.join(", ")}function be(e){return{preflight(t){let d=t.headers.get("origin")??void 0,n=se(d,e),r=Boolean(d&&n&&le(e));return new Response(null,{status:204,headers:ce(n,e,r)})},corsify(t,d){let n=d.headers.get("origin")??void 0,r=se(n,e);if(!r)return t;let o=Boolean(n&&le(e)),i=ce(r,e,o);for(let[a,s]of Object.entries(i)){if(a==="vary"){t.headers.set("vary",Te(t.headers.get("vary"),s));continue}t.headers.set(a,s)}return t}}}function me(e,t,d,n,r,o,i,a,s){let c=JSON.stringify(e).replace(/<\/script/gi,"<\\/script"),m=JSON.stringify(t),b=JSON.stringify(d),p=JSON.stringify(n),x=JSON.stringify(r),u=JSON.stringify(o),f=JSON.stringify(i),Ne=JSON.stringify(a),Ae=JSON.stringify(s);return`<!DOCTYPE html>
209
+ };`}}import{existsSync as sr,promises as Ue}from"fs";import{join as cr,relative as Me,resolve as pr,sep as Pe}from"path";class V{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=pr(process.cwd(),e),this.excludePatterns=t||V.DEFAULT_EXCLUDE_PATTERNS}async scan(){let e=[];if(!sr(this.routesDir))return[];try{await this.scanDirectory(this.routesDir,e)}catch(t){if(t.code==="ENOENT")return console.warn(` \u2717 Routes directory not accessible: ${this.routesDir}`),[];throw t}return e}isExcluded(e){let t=Me(this.routesDir,e);for(let r of this.excludePatterns){let a=r.replace(/\./g,"\\.").replace(/\*\*/g,"__GLOBSTAR__").replace(/\*/g,"[^/]*").replace(/__GLOBSTAR__/g,".*").replace(/\?/g,"."),n=new RegExp(`^${a}$`),o=t.split(Pe).pop()||"";if(n.test(t)||n.test(o))return!0}return!1}async scanDirectory(e,t,r=""){let a=await Ue.readdir(e);for(let n of a){let o=cr(e,n);if((await Ue.stat(o)).isDirectory()){let d=r?`${r}/${n}`:n;await this.scanDirectory(o,t,d)}else if(n.endsWith(".ts")||n.endsWith(".js")){if(this.isExcluded(o))continue;let d=Me(this.routesDir,o).replace(/\.(ts|js)$/,"").split(Pe).join("/");try{let c=await import(`${process.platform==="win32"?`file:///${o.replace(/\\/g,"/")}`:o}?t=${Date.now()}`);if(c.default&&typeof c.default==="function")t.push({name:"default",path:o,method:"GET",options:{method:"GET",path:`/${d}`,expose:!0}});for(let[m,s]of Object.entries(c)){if(m==="default")continue;if(s&&typeof s==="object"&&"entry"in s&&"options"in s&&"handler"in s){let p=s;t.push({name:m,path:o,method:p.options.method,options:p.options})}else if(Array.isArray(s)&&s.length>=4){let[p,,,h]=s;t.push({name:m,path:o,method:p,options:{method:p,path:h,expose:!0}})}}}catch(l){console.error(`Failed to load route from ${o}:`,l)}}}}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 W{beforeHandlers=[];finallyHandlers=[];addBefore(...e){this.beforeHandlers.push(...e)}addFinally(...e){this.finallyHandlers.push(...e)}async executeBefore(e){if(this.beforeHandlers.length===0)return null;for(let t of this.beforeHandlers){let r=await t(e);if(r instanceof Response)return r;if(r!==void 0)throw new TypeError("Before middleware must return void or Response")}return null}async executeFinally(e,t){if(this.finallyHandlers.length===0)return e;let r=e;for(let a of this.finallyHandlers)try{r=await a(r,t)}catch(n){console.error("After middleware error:",n)}return r}clone(){let e=new W;return e.beforeHandlers=[...this.beforeHandlers],e.finallyHandlers=[...this.finallyHandlers],e}clear(){this.beforeHandlers=[],this.finallyHandlers=[]}}function X(e){return process.platform==="win32"?`file:///${e.replace(/\\/g,"/")}`:e}function ne(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.*)?")}/*$`)}var ze;((o)=>{o.ApiKey="apiKey";o.Http="http";o.MutualTls="mutualTLS";o.OAuth2="oauth2";o.OpenIdConnect="openIdConnect"})(ze||={});var Je;((a)=>{a.Basic="basic";a.Bearer="bearer";a.Digest="digest"})(Je||={});var J;((d)=>{d.ApiKey="ApiKey";d.HttpBasic="HttpBasic";d.HttpBearer="HttpBearer";d.HttpDigest="HttpDigest";d.OAuth2="OAuth2";d.OpenIdConnect="OpenIdConnect";d.MutualTls="MutualTls"})(J||={});function Fe(e){let t=e?.["~standard"];return!!t&&typeof t==="object"&&typeof t.validate==="function"&&t.version===1}async function Ge(e,t){let r=await e["~standard"].validate(t),a=r?.issues;if(Array.isArray(a)&&a.length>0)return{success:!1,issues:a};return{success:!0,value:r?.value}}function Ye(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 mr(e){if(!Array.isArray(e))return[];let t=[];for(let r=0;r<e.length;r++){let a=e[r],n=a;if(a&&typeof a==="object"&&"key"in a)n=a.key;if(typeof n==="string"||typeof n==="number")t.push(n);else if(typeof n==="symbol")t.push(String(n));else if(n!==void 0&&n!==null)t.push(String(n))}return t}function oe(e,t){let r=[];for(let a=0;a<e.length;a++){let n=e[a],o=n,i={message:typeof o?.message==="string"&&o.message.length>0?o.message:"Invalid value",path:mr(o?.path)};if(typeof o?.code==="string")i.code=o.code;if(t)i.raw=n;r.push(i)}return r}function de(e,t){return{error:!0,message:"Validation failed",statusCode:422,source:"validation",target:e,issues:t,timestamp:new Date().toISOString()}}var br=new Set(Object.values(J));function ur(e){return typeof e==="string"&&br.has(e)}class F{middlewareManager;authManager;cacheManager;routeBooleanDefaults={};developmentMode=void 0;routeDefinitions=[];routeTable=Object.create(null);routeMatchers=[];corsHeadersEntries=null;corsHandler=null;checkpointGateway=null;constructor(e,t,r){this.middlewareManager=e,this.authManager=t,this.cacheManager=r}setCorsHeaders(e){this.corsHeadersEntries=e}setCorsHandler(e){this.corsHandler=e}setCheckpointGateway(e){this.checkpointGateway=e}setRouteBooleanDefaults(e){this.routeBooleanDefaults={...e}}setDevelopmentMode(e){this.developmentMode=e}applyRouteBooleanDefaults(e){let t={...e},r=this.routeBooleanDefaults,a=["auth","expose","rawRequest","validate","rawResponse"];for(let n of a)if(t[n]===void 0&&r[n]!==void 0)t[n]=r[n];if(t.auth===!0&&ur(r.auth))t.auth=r.auth;return t}route(e,t){let r=this.applyRouteBooleanDefaults(e),a=r.method.toUpperCase(),n=r.path,o=this.wrapHandler(r,t),i=this.getOrCreateMethodMap(n);i[a]=o,this.routeDefinitions.push({method:a,path:n,options:r})}addRoute(e){let[t,,r,a]=e;if(!a)return;let n=this.getOrCreateMethodMap(a);n[t.toUpperCase()]=r[0];let o=t.toUpperCase();this.routeDefinitions.push({method:o,path:a,options:{method:o,path:a,expose:!0}})}bulkAddRoutes(e){for(let t of e)this.addRoute(t)}addStaticRoute(e,t){let r=this.routeTable[e];if(r&&!(r 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 r=this.routeTable[t.path];if(!r||r instanceof Response)continue;for(let[a,n]of Object.entries(r))e.push([a,t.regex,[n],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 S.badRequest("Malformed request URL")}let r=t.pathname,a=this.routeTable[r];if(a){if(a instanceof Response)return this.applyCorsResponse(a.clone(),e);let n=a,o=n[e.method]??(e.method==="HEAD"?n.GET:void 0);if(o){let i=await o(e);if(i)return i}}for(let n of this.routeMatchers){let o=n.path,i=this.routeTable[o];if(!i)continue;if(i instanceof Response){if(r===o)return this.applyCorsResponse(i.clone(),e);continue}let d=i,l=d[e.method]??(e.method==="HEAD"?d.GET:void 0);if(!l)continue;if(!r.match(n.regex))continue;let m=await l(e);if(m)return m}return this.applyCorsResponse(je.NOT_FOUND.clone(),e)}cloneMetadata(e){if(Array.isArray(e))return[...e];if(e&&typeof e==="object")return{...e};return e}createContext(e,t){let r={request:e};return this.setContextField(r,"metadata",t?.metadata!==void 0?this.cloneMetadata(t.metadata):{}),this.setContextField(r,"params",t?.params??{}),this.setContextField(r,"query",t?.query??{}),this.setContextField(r,"cookies",t?.cookies??{}),r}setContextField(e,t,r){e[t]=r}hasOwnContextField(e,t){return Object.prototype.hasOwnProperty.call(e,t)}buildCheckpointContextPayload(e){let t={},r=["metadata","content","validatedInput","authUser"];for(let a of r){if(!this.hasOwnContextField(e,a))continue;let n=e[a];if(typeof n==="function"||typeof n==="symbol"||n===void 0)continue;t[a]=n}return t}resolveFallbackParams(e,t){if(!t)return;let r=e.match(t);if(!r?.groups)return;return r.groups}getRequestedCheckpointVersion(e){if(!this.checkpointGateway)return null;let t=this.checkpointGateway;if(t?.getRequestedVersion)return t.getRequestedVersion(e);let r=e.headers.get("x-vector-checkpoint-version");if(r&&r.trim().length>0)return r.trim();let a=e.headers.get("x-vector-checkpoint");if(a&&a.trim().length>0)return a.trim();return null}getCheckpointCacheKeyOverrideValue(e){if(!this.checkpointGateway)return null;let t=this.checkpointGateway;if(t?.getCacheKeyOverrideValue)return t.getCacheKeyOverrideValue(e);let r=e.headers.get("x-vector-checkpoint-version");if(r&&r.trim().length>0)return`x-vector-checkpoint-version:${r.trim()}`;let a=e.headers.get("x-vector-checkpoint");if(a&&a.trim().length>0)return`x-vector-checkpoint:${a.trim()}`;return null}applyCheckpointCacheNamespace(e,t){let r=this.getRequestedCheckpointVersion(t);if(!r)return e;return`${e}:checkpoint=${r}`}applyCheckpointRouteKeyOverride(e,t){let r=this.getCheckpointCacheKeyOverrideValue(t);if(!r)return e;return r}async parseRequestBodyForContext(e,t,r){let a=null;try{let n=r?t.clone():t,o=n.headers.get("content-type");if(o?.startsWith("application/json"))a=await n.json();else if(o?.startsWith("application/x-www-form-urlencoded"))a=Object.fromEntries(await n.formData());else if(o?.startsWith("multipart/form-data"))a=await n.formData();else a=await n.text()}catch{a=null}this.setContextField(e,"content",a)}isLikelyStreamingBodyRequest(e){if(e.method==="GET"||e.method==="HEAD")return!1;if(!e.body)return!1;if(e.duplex==="half")return!0;let t=e.headers.get("transfer-encoding");if(t){if(t.split(",").some((a)=>a.trim().toLowerCase()==="chunked"))return!0}return!1}wrapHandler(e,t){let r=e.path,a=r.includes(":")?ne(r):null;return async(n)=>{let o=n,i="";try{i=new URL(n.url).pathname}catch{}let d=this.resolveFallbackParams(i,a),l=this.createContext(o,{metadata:e.metadata,params:this.getRequestParams(n,d),query:this.getRequestQuery(n),cookies:this.getRequestCookies(n)});try{if(e.expose===!1)return S.forbidden("Forbidden");let c=await this.middlewareManager.executeBefore(l);if(c instanceof Response)return c;if(e.auth)try{await this.authManager.authenticate(l)}catch(u){return S.unauthorized(u instanceof Error?u.message:"Authentication failed",e.responseContentType)}let m=async()=>{let u=l.request,f=u,L=this.getRequestedCheckpointVersion(f)!==null,x=this.isLikelyStreamingBodyRequest(f)&&e.schema?.input!==void 0&&e.validate!==!1;if(!e.rawRequest&&u.method!=="GET"&&u.method!=="HEAD"&&!x)await this.parseRequestBodyForContext(l,f,L);if(x){let N=await this.validateInputSchema(l,e,d,{includeBody:!1,allowBodyDeferral:!0});if(N.response)return N.response;if(N.requiresBody){if(!e.rawRequest&&u.method!=="GET"&&u.method!=="HEAD")await this.parseRequestBodyForContext(l,f,L);let De=await this.validateInputSchema(l,e,d);if(De.response)return De.response}}else{let N=await this.validateInputSchema(l,e,d);if(N.response)return N.response}if(this.checkpointGateway){let N=await this.checkpointGateway.handle(u,this.buildCheckpointContextPayload(l));if(N)return N}return await t(l)},s,p=e.cache;if(p&&typeof p==="number"&&p>0){let u=this.applyCheckpointCacheNamespace(this.cacheManager.generateKey(l.request,{authUser:l.authUser}),l.request);s=await this.cacheManager.get(u,async()=>await m(),p)}else if(p&&typeof p==="object"&&p.ttl){let u=typeof p.key==="string"&&p.key.length>0,f;if(u)f=this.applyCheckpointRouteKeyOverride(p.key,l.request);else{let L=this.cacheManager.generateKey(l.request,{authUser:l.authUser});f=this.applyCheckpointCacheNamespace(L,l.request)}s=await this.cacheManager.get(f,async()=>await m(),p.ttl)}else s=await m();if(s instanceof Response&&!!p)s=s.clone();let h;if(e.rawResponse||s instanceof Response)h=s instanceof Response?s:new Response(s);else h=_(200,s,e.responseContentType);return h=await this.middlewareManager.executeFinally(h,l),this.applyCorsResponse(h,l.request)}catch(c){if(c instanceof Response)return c;return console.error("Route handler error:",c),S.internalServerError(c instanceof Error?c.message:String(c),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,r,a){let n=e.request,o=a?.includeBody!==!1,i=o&&this.hasOwnContextField(e,"content")?e.content:void 0;if(o&&t.rawRequest&&n.method!=="GET"&&n.method!=="HEAD")try{i=await n.clone().text()}catch{i=null}return{params:this.getRequestParams(n,r),query:this.getRequestQuery(n),headers:Object.fromEntries(n.headers.entries()),cookies:this.getRequestCookies(n),body:i}}getRequestParams(e,t){let r=this.readRequestObjectField(e,"params");if(r&&Object.keys(r).length>0)return r;return t??{}}getRequestQuery(e){let t=this.readRequestObjectField(e,"query");if(t)return t;try{return F.parseQuery(new URL(e.url))}catch{return{}}}getRequestCookies(e){let t=this.readRequestObjectField(e,"cookies");if(t)return t;return F.parseCookies(e.headers.get("cookie"))}readRequestObjectField(e,t){let r=e[t];if(!r||typeof r!=="object"||Array.isArray(r))return;return r}applyValidatedInput(e,t){this.setContextField(e,"validatedInput",t)}issueHasBodyPath(e){if(!e||typeof e!=="object"||!("path"in e))return!1;let t=e.path;if(!Array.isArray(t)||t.length===0)return!1;let r=t[0];if(r&&typeof r==="object"&&"key"in r)return r.key==="body";return r==="body"}issueHasExplicitNonBodyPath(e){if(!e||typeof e!=="object"||!("path"in e))return!1;let t=e.path;if(!Array.isArray(t)||t.length===0)return!1;let r=t[0];if(r&&typeof r==="object"&&"key"in r)return r.key!=="body";return r!=="body"}issueHasUnknownPath(e){if(!e||typeof e!=="object"||!("path"in e))return!0;let t=e.path;if(!Array.isArray(t))return!0;return t.length===0}shouldDeferBodyValidation(e,t,r){if(!(r?.allowBodyDeferral===!0&&r?.includeBody===!1))return!1;let a=t.request;if(!(a.method!=="GET"&&a.method!=="HEAD"&&a.body!==null)||e.length===0)return!1;if(e.some((d)=>this.issueHasBodyPath(d)))return!0;let o=e.some((d)=>this.issueHasExplicitNonBodyPath(d)),i=e.some((d)=>this.issueHasUnknownPath(d));return!o&&i}async validateInputSchema(e,t,r,a){let n=t.schema?.input;if(!n)return{response:null,requiresBody:!1};if(t.validate===!1)return{response:null,requiresBody:!1};if(!Fe(n))return{response:S.internalServerError("Invalid route schema configuration",t.responseContentType),requiresBody:!1};let o=this.isDevelopmentMode(),i=await this.buildInputValidationPayload(e,t,r,{includeBody:a?.includeBody});try{let d=await Ge(n,i);if(d.success===!1){if(this.shouldDeferBodyValidation(d.issues,e,a))return{response:null,requiresBody:!0};let l=oe(d.issues,o);return{response:_(422,de("input",l),t.responseContentType),requiresBody:!1}}return this.applyValidatedInput(e,d.value),{response:null,requiresBody:!1}}catch(d){let l=Ye(d);if(l){if(this.shouldDeferBodyValidation(l,e,a))return{response:null,requiresBody:!0};let c=oe(l,o);return{response:_(422,de("input",c),t.responseContentType),requiresBody:!1}}return{response:S.internalServerError(d instanceof Error?d.message:"Validation failed",t.responseContentType),requiresBody:!1}}}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 r=Object.create(null);return this.routeTable[e]=r,this.addRouteMatcher(e),r}addRouteMatcher(e){if(this.routeMatchers.some((t)=>t.path===e))return;this.routeMatchers.push({path:e,regex:ne(e),specificity:this.routeSpecificityScore(e)}),this.routeMatchers.sort((t,r)=>{if(t.specificity!==r.specificity)return r.specificity-t.specificity;return t.path.localeCompare(r.path)})}removeRouteMatcher(e){this.routeMatchers=this.routeMatchers.filter((t)=>t.path!==e)}static parseQuery(e){let t={};for(let[r,a]of e.searchParams)if(r in t){let n=t[r];if(Array.isArray(n))n.push(a);else t[r]=[n,a]}else t[r]=a;return t}static parseCookies(e){let t={};if(!e)return t;for(let r of e.split(";")){let a=r.indexOf("=");if(a>0)t[r.slice(0,a).trim()]=r.slice(a+1).trim()}return t}routeSpecificityScore(e){let o=e.split("/").filter(Boolean),i=0;for(let d of o)if(d.includes("*"))i+=1;else if(d.startsWith(":"))i+=10;else i+=1000;if(i+=e.length,!e.includes(":")&&!e.includes("*"))i+=1e4;return i}applyCorsResponse(e,t){let r=this.corsHeadersEntries;if(r){for(let[n,o]of r)e.headers.set(n,o);return e}let a=this.corsHandler;if(a)return a(e,t);return e}}import{existsSync as ot}from"fs";import{join as $r}from"path";function Qe(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 Ve(e){return typeof e.origin==="string"&&e.origin==="*"&&e.credentials||Array.isArray(e.origin)||typeof e.origin==="function"}function We(e,t,r){let a={};if(e){if(a["access-control-allow-origin"]=e,a["access-control-allow-methods"]=t.allowMethods,a["access-control-allow-headers"]=t.allowHeaders,a["access-control-expose-headers"]=t.exposeHeaders,a["access-control-max-age"]=String(t.maxAge),t.credentials)a["access-control-allow-credentials"]="true";if(r)a.vary="Origin"}return a}function hr(e,t){if(!e)return t;let r=e.split(",").map((n)=>n.trim()).filter(Boolean);if(!r.map((n)=>n.toLowerCase()).includes(t.toLowerCase()))r.push(t);return r.join(", ")}function Xe(e){return{preflight(t){let r=t.headers.get("origin")??void 0,a=Qe(r,e),n=Boolean(r&&a&&Ve(e));return new Response(null,{status:204,headers:We(a,e,n)})},corsify(t,r){let a=r.headers.get("origin")??void 0,n=Qe(a,e);if(!n)return t;let o=Boolean(a&&Ve(e)),i=We(n,e,o);for(let[d,l]of Object.entries(i)){if(d==="vary"){t.headers.set("vary",hr(t.headers.get("vary"),l));continue}t.headers.set(d,l)}return t}}}function Ze(e,t,r,a,n,o,i,d,l){let c=JSON.stringify(e).replace(/<\/script/gi,"<\\/script"),m=JSON.stringify(t),s=JSON.stringify(r),p=JSON.stringify(a),h=JSON.stringify(n),u=JSON.stringify(o),f=JSON.stringify(i),L=JSON.stringify(d),x=JSON.stringify(l);return`<!DOCTYPE html>
23
210
  <html lang="en">
24
211
  <head>
25
212
  <meta charset="UTF-8">
@@ -27,8 +214,8 @@ ${t.join(`,
27
214
  <title>Vector API Documentation</title>
28
215
  <link rel="apple-touch-icon" sizes="180x180" href=${u}>
29
216
  <link rel="icon" type="image/png" sizes="32x32" href=${f}>
30
- <link rel="icon" type="image/png" sizes="16x16" href=${Ne}>
31
- <link rel="manifest" href=${Ae}>
217
+ <link rel="icon" type="image/png" sizes="16x16" href=${L}>
218
+ <link rel="manifest" href=${x}>
32
219
  <script>
33
220
  if (localStorage.getItem('theme') === 'dark' || (!('theme' in localStorage) && window.matchMedia('(prefers-color-scheme: dark)').matches)) {
34
221
  document.documentElement.classList.add('dark');
@@ -36,7 +223,7 @@ ${t.join(`,
36
223
  document.documentElement.classList.remove('dark');
37
224
  }
38
225
  </script>
39
- <script src=${b}></script>
226
+ <script src=${s}></script>
40
227
  <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500&display=swap" rel="stylesheet">
41
228
  <script>
42
229
  tailwind.config = {
@@ -144,6 +331,124 @@ ${t.join(`,
144
331
  .dark .json-number { color: #7dc9ff; }
145
332
  .dark .json-boolean { color: #93a4bf; }
146
333
  .dark .json-null { color: #7c8ba3; }
334
+ .param-row {
335
+ --param-row-bg-rgb: 255 255 255;
336
+ }
337
+ .dark .param-row {
338
+ --param-row-bg-rgb: 10 10 10;
339
+ }
340
+ .param-row-head {
341
+ display: grid;
342
+ grid-template-columns: minmax(0, 1fr) auto;
343
+ align-items: center;
344
+ gap: 0.5rem;
345
+ min-width: 0;
346
+ width: 100%;
347
+ }
348
+ .param-row-main {
349
+ min-width: 0;
350
+ display: flex;
351
+ align-items: center;
352
+ gap: 0.4rem;
353
+ overflow: hidden;
354
+ }
355
+ .param-tooltip-trigger {
356
+ border: 0;
357
+ margin: 0;
358
+ padding: 0;
359
+ background: transparent;
360
+ color: inherit;
361
+ cursor: pointer;
362
+ font: inherit;
363
+ text-align: left;
364
+ min-width: 0;
365
+ }
366
+ .param-tooltip-trigger:focus-visible {
367
+ outline: 2px solid rgba(0, 161, 255, 0.65);
368
+ outline-offset: 2px;
369
+ border-radius: 0.375rem;
370
+ }
371
+ .param-name-trigger {
372
+ min-width: 0;
373
+ flex: 1 1 auto;
374
+ overflow: hidden;
375
+ }
376
+ .param-name-text {
377
+ display: block;
378
+ max-width: 100%;
379
+ overflow: hidden;
380
+ text-overflow: ellipsis;
381
+ white-space: nowrap;
382
+ mask-image: linear-gradient(to right, #000 0%, #000 calc(100% - 18px), transparent 100%);
383
+ -webkit-mask-image: linear-gradient(to right, #000 0%, #000 calc(100% - 18px), transparent 100%);
384
+ }
385
+ .param-type-fade {
386
+ position: relative;
387
+ z-index: 1;
388
+ display: block;
389
+ max-width: none;
390
+ overflow: visible;
391
+ text-overflow: clip;
392
+ padding-left: 1.25rem;
393
+ white-space: nowrap;
394
+ text-align: left;
395
+ justify-self: end;
396
+ background: linear-gradient(
397
+ 90deg,
398
+ rgba(var(--param-row-bg-rgb), 0) 0%,
399
+ rgba(var(--param-row-bg-rgb), 0.76) 36%,
400
+ rgba(var(--param-row-bg-rgb), 0.94) 68%,
401
+ rgba(var(--param-row-bg-rgb), 1) 100%
402
+ );
403
+ }
404
+ #param-value-tooltip {
405
+ position: fixed;
406
+ top: 0;
407
+ left: 0;
408
+ z-index: 70;
409
+ width: min(42rem, calc(100vw - 0.75rem));
410
+ border-radius: 0.5rem;
411
+ border: 1px solid rgba(15, 23, 42, 0.12);
412
+ background: rgba(255, 255, 255, 0.92);
413
+ color: #111111;
414
+ box-shadow: 0 10px 20px rgba(15, 23, 42, 0.14);
415
+ backdrop-filter: blur(12px) saturate(145%);
416
+ -webkit-backdrop-filter: blur(12px) saturate(145%);
417
+ padding: 0.4rem 0.6rem;
418
+ opacity: 0;
419
+ pointer-events: none;
420
+ transform: translateY(6px) scale(0.98);
421
+ transition:
422
+ opacity var(--motion-fast) var(--motion-ease),
423
+ transform var(--motion-fast) var(--motion-ease);
424
+ }
425
+ #param-value-tooltip.is-visible {
426
+ opacity: 1;
427
+ pointer-events: auto;
428
+ transform: translateY(0) scale(1);
429
+ }
430
+ .dark #param-value-tooltip {
431
+ border-color: rgba(148, 163, 184, 0.24);
432
+ background: rgba(17, 17, 17, 0.9);
433
+ color: #ededed;
434
+ box-shadow: 0 14px 30px rgba(0, 0, 0, 0.45);
435
+ }
436
+ #param-tooltip-line {
437
+ margin: 0;
438
+ font-size: 11px;
439
+ line-height: 1.3;
440
+ font-family: "JetBrains Mono", monospace;
441
+ white-space: normal;
442
+ word-break: break-word;
443
+ }
444
+ #param-tooltip-description {
445
+ margin: 0.2rem 0 0;
446
+ font-size: 11px;
447
+ line-height: 1.3;
448
+ opacity: 0.8;
449
+ white-space: normal;
450
+ word-break: break-word;
451
+ }
147
452
  </style>
148
453
  </head>
149
454
  <body class="bg-light-bg text-light-text dark:bg-dark-bg dark:text-dark-text font-sans antialiased flex h-screen overflow-hidden">
@@ -152,7 +457,7 @@ ${t.join(`,
152
457
  <div class="h-14 flex items-center px-5 border-b border-light-border dark:border-dark-border">
153
458
  <div class="flex items-center">
154
459
  <img src=${p} alt="Vector" class="h-6 w-auto block dark:hidden" />
155
- <img src=${x} alt="Vector" class="h-6 w-auto hidden dark:block" />
460
+ <img src=${h} alt="Vector" class="h-6 w-auto hidden dark:block" />
156
461
  </div>
157
462
  <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">
158
463
  <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
@@ -173,6 +478,16 @@ ${t.join(`,
173
478
  />
174
479
  </div>
175
480
  </div>
481
+ <div id="auth-panel" class="border-b border-light-border dark:border-dark-border">
482
+ <button id="auth-toggle" class="w-full flex items-center justify-between px-4 py-2.5 text-xs font-semibold uppercase tracking-wider opacity-60 hover:opacity-100 transition-opacity">
483
+ <span class="flex items-center gap-1.5">
484
+ <svg class="w-3.5 h-3.5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 15v2m-6 4h12a2 2 0 002-2v-6a2 2 0 00-2-2H6a2 2 0 00-2 2v6a2 2 0 002 2zm10-10V7a4 4 0 00-8 0v4h8z"></path></svg>
485
+ Auth
486
+ </span>
487
+ <svg id="auth-chevron" class="w-3.5 h-3.5 transition-transform duration-200" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7"></path></svg>
488
+ </button>
489
+ <div id="auth-fields" class="px-4 pb-3 space-y-2"></div>
490
+ </div>
176
491
  <nav class="flex-1 overflow-y-auto px-3 py-2 space-y-6 text-sm" id="sidebar-nav"></nav>
177
492
  </aside>
178
493
 
@@ -185,7 +500,7 @@ ${t.join(`,
185
500
  </svg>
186
501
  </button>
187
502
  <img src=${p} alt="Vector" class="h-5 w-auto block dark:hidden" />
188
- <img src=${x} alt="Vector" class="h-5 w-auto hidden dark:block" />
503
+ <img src=${h} alt="Vector" class="h-5 w-auto hidden dark:block" />
189
504
  </div>
190
505
  <div class="flex-1"></div>
191
506
  <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">
@@ -206,6 +521,9 @@ ${t.join(`,
206
521
  <span id="endpoint-method" class="px-2.5 py-0.5 rounded-full text-xs font-mono font-medium"></span>
207
522
  <h2 class="text-xl font-semibold tracking-tight" id="endpoint-title">Operation</h2>
208
523
  </div>
524
+ <div id="deprecated-banner" class="hidden mb-4 px-3 py-2 rounded border border-amber-300 dark:border-amber-700 bg-amber-50 dark:bg-amber-900/20 text-amber-700 dark:text-amber-400 text-xs font-medium">
525
+ ! This operation is deprecated
526
+ </div>
209
527
  <p class="text-sm opacity-80 mb-8 font-mono" id="endpoint-path">/</p>
210
528
  <div class="grid grid-cols-1 lg:grid-cols-12 gap-10">
211
529
  <div class="lg:col-span-5 space-y-8" id="params-column"></div>
@@ -301,6 +619,10 @@ ${t.join(`,
301
619
  <pre id="expand-viewer" class="hidden w-full h-[70vh] text-sm p-3 rounded border border-light-border dark:border-dark-border bg-light-bg dark:bg-dark-bg overflow-auto font-mono"></pre>
302
620
  </div>
303
621
  </div>
622
+ <div id="param-value-tooltip" aria-hidden="true" role="tooltip">
623
+ <p id="param-tooltip-line"></p>
624
+ <p id="param-tooltip-description" class="hidden"></p>
625
+ </div>
304
626
 
305
627
  <script>
306
628
  const spec = ${c};
@@ -371,14 +693,71 @@ ${t.join(`,
371
693
  return ops;
372
694
  }
373
695
 
696
+ const AUTH_STATE_KEY = "vector-docs-auth-v1";
697
+ const AUTH_SELECTION_KEY = "vector-docs-auth-selection-v1";
698
+ const HEADERS_STATE_KEY = "vector-docs-headers-v1";
699
+
700
+ function loadSavedHeaders() {
701
+ try {
702
+ const raw = localStorage.getItem(HEADERS_STATE_KEY);
703
+ if (raw) {
704
+ const parsed = JSON.parse(raw);
705
+ if (Array.isArray(parsed) && parsed.length > 0) return parsed;
706
+ }
707
+ } catch {}
708
+ return [{ key: "", value: "" }];
709
+ }
710
+
711
+ function saveHeaders() {
712
+ try { localStorage.setItem(HEADERS_STATE_KEY, JSON.stringify(requestHeaders)); } catch {}
713
+ }
714
+
715
+ function loadAuthState() {
716
+ try {
717
+ const raw = localStorage.getItem(AUTH_STATE_KEY);
718
+ if (raw) return JSON.parse(raw);
719
+ } catch {}
720
+ return {};
721
+ }
722
+
723
+ function saveAuthState() {
724
+ try { localStorage.setItem(AUTH_STATE_KEY, JSON.stringify(authState)); } catch {}
725
+ }
726
+
727
+ function loadAuthSelectionState() {
728
+ try {
729
+ const raw = localStorage.getItem(AUTH_SELECTION_KEY);
730
+ if (raw) {
731
+ const parsed = JSON.parse(raw);
732
+ if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
733
+ return parsed;
734
+ }
735
+ }
736
+ } catch {}
737
+ return {};
738
+ }
739
+
740
+ function saveAuthSelectionState() {
741
+ try { localStorage.setItem(AUTH_SELECTION_KEY, JSON.stringify(authSelectionState)); } catch {}
742
+ }
743
+
744
+ const authSchemes = (spec.components && spec.components.securitySchemes) || {};
745
+ let authState = loadAuthState();
746
+ let authSelectionState = loadAuthSelectionState();
747
+
374
748
  const operations = getOperations();
375
749
  let selected = operations[0] || null;
376
750
  const operationParamValues = new Map();
377
751
  const operationBodyDrafts = new Map();
378
- const requestHeaders = [{ key: "Authorization", value: "" }];
752
+ const requestHeaders = loadSavedHeaders();
379
753
  let expandModalMode = null;
380
754
  let isMobileSidebarOpen = false;
381
755
  let sidebarSearchQuery = "";
756
+ const paramTooltipRoot = document.getElementById("param-value-tooltip");
757
+ const paramTooltipLine = document.getElementById("param-tooltip-line");
758
+ const paramTooltipDescription = document.getElementById("param-tooltip-description");
759
+ let activeParamTooltipTrigger = null;
760
+ let paramTooltipHideTimer = null;
382
761
 
383
762
  function setMobileSidebarOpen(open) {
384
763
  const sidebar = document.getElementById("docs-sidebar");
@@ -398,6 +777,29 @@ ${t.join(`,
398
777
  return op.method + " " + op.path;
399
778
  }
400
779
 
780
+ function getOpHash(op) {
781
+ var tag = op.tag || "default";
782
+ var id = (op.operation && op.operation.operationId)
783
+ ? op.operation.operationId
784
+ : op.method.toLowerCase() + "_" + op.path.split("/").filter(Boolean).join("_").replace(/[{}]/g, "");
785
+ return "#/" + encodeURIComponent(tag) + "/" + encodeURIComponent(id);
786
+ }
787
+
788
+ function findOpByHash(hash) {
789
+ if (!hash || hash.length <= 1) return null;
790
+ var parts = hash.slice(1).split("/").filter(Boolean);
791
+ if (parts.length < 2) return null;
792
+ var hashTag = decodeURIComponent(parts[0]);
793
+ var hashId = decodeURIComponent(parts[1]);
794
+ return operations.find(function(op) {
795
+ if (op.tag !== hashTag) return false;
796
+ var id = (op.operation && op.operation.operationId)
797
+ ? op.operation.operationId
798
+ : op.method.toLowerCase() + "_" + op.path.split("/").filter(Boolean).join("_").replace(/[{}]/g, "");
799
+ return id === hashId;
800
+ }) || null;
801
+ }
802
+
401
803
  function getOperationParameterGroups(op) {
402
804
  const params =
403
805
  op &&
@@ -447,7 +849,7 @@ ${t.join(`,
447
849
  return resolved;
448
850
  }
449
851
 
450
- function buildRequestPath(op, pathParams, queryParams, values) {
852
+ function buildRequestPath(op, pathParams, queryParams, values, extraQuery) {
451
853
  const resolvedPath = resolvePath(op.path, pathParams, values);
452
854
  const query = new URLSearchParams();
453
855
 
@@ -459,6 +861,13 @@ ${t.join(`,
459
861
  query.append(param.name, String(rawValue));
460
862
  }
461
863
 
864
+ if (extraQuery) {
865
+ for (const key of Object.keys(extraQuery)) {
866
+ const val = extraQuery[key];
867
+ if (val) query.set(key, String(val));
868
+ }
869
+ }
870
+
462
871
  const queryString = query.toString();
463
872
  return queryString ? resolvedPath + "?" + queryString : resolvedPath;
464
873
  }
@@ -598,14 +1007,25 @@ ${t.join(`,
598
1007
 
599
1008
  const name = document.createElement("span");
600
1009
  name.textContent = op.name;
1010
+ if (op.operation && op.operation.deprecated) {
1011
+ name.style.textDecoration = "line-through";
1012
+ name.style.opacity = "0.5";
1013
+ }
601
1014
 
602
1015
  row.appendChild(method);
603
1016
  row.appendChild(name);
1017
+ if (op.operation && op.operation.deprecated) {
1018
+ const badge = document.createElement("span");
1019
+ badge.className = "text-[9px] px-1 py-0.5 rounded bg-amber-100 dark:bg-amber-900/30 text-amber-700 dark:text-amber-500 font-semibold shrink-0";
1020
+ badge.textContent = "deprecated";
1021
+ row.appendChild(badge);
1022
+ }
604
1023
  a.appendChild(row);
605
1024
 
606
1025
  a.onclick = (e) => {
607
1026
  e.preventDefault();
608
1027
  selected = op;
1028
+ history.pushState(null, "", getOpHash(op));
609
1029
  renderSidebar();
610
1030
  renderEndpoint();
611
1031
  if (window.innerWidth < 768) {
@@ -619,51 +1039,257 @@ ${t.join(`,
619
1039
  }
620
1040
  }
621
1041
 
1042
+ function hideParamTooltip() {
1043
+ if (!paramTooltipRoot) return;
1044
+ if (paramTooltipHideTimer) {
1045
+ window.clearTimeout(paramTooltipHideTimer);
1046
+ paramTooltipHideTimer = null;
1047
+ }
1048
+ paramTooltipRoot.classList.remove("is-visible");
1049
+ paramTooltipRoot.setAttribute("aria-hidden", "true");
1050
+ if (activeParamTooltipTrigger) {
1051
+ activeParamTooltipTrigger.setAttribute("aria-expanded", "false");
1052
+ }
1053
+ activeParamTooltipTrigger = null;
1054
+ }
1055
+
1056
+ function scheduleParamTooltipHide() {
1057
+ if (paramTooltipHideTimer) {
1058
+ window.clearTimeout(paramTooltipHideTimer);
1059
+ }
1060
+ paramTooltipHideTimer = window.setTimeout(() => {
1061
+ hideParamTooltip();
1062
+ }, 95);
1063
+ }
1064
+
1065
+ function positionParamTooltip(trigger) {
1066
+ if (!paramTooltipRoot || !trigger) return;
1067
+ const viewportPadding = 8;
1068
+ const spacing = 10;
1069
+ const triggerRect = trigger.getBoundingClientRect();
1070
+ const tooltipRect = paramTooltipRoot.getBoundingClientRect();
1071
+ let left = triggerRect.left + (triggerRect.width / 2) - (tooltipRect.width / 2);
1072
+ left = Math.max(viewportPadding, Math.min(left, window.innerWidth - tooltipRect.width - viewportPadding));
1073
+ let top = triggerRect.top - tooltipRect.height - spacing;
1074
+ if (top < viewportPadding) {
1075
+ top = triggerRect.bottom + spacing;
1076
+ }
1077
+ if (top + tooltipRect.height > window.innerHeight - viewportPadding) {
1078
+ top = window.innerHeight - tooltipRect.height - viewportPadding;
1079
+ }
1080
+ paramTooltipRoot.style.left = Math.round(left) + "px";
1081
+ paramTooltipRoot.style.top = Math.round(top) + "px";
1082
+ }
1083
+
1084
+ function showParamTooltip(trigger) {
1085
+ if (
1086
+ !paramTooltipRoot ||
1087
+ !paramTooltipLine ||
1088
+ !paramTooltipDescription ||
1089
+ !trigger
1090
+ ) {
1091
+ return;
1092
+ }
1093
+ if (paramTooltipHideTimer) {
1094
+ window.clearTimeout(paramTooltipHideTimer);
1095
+ paramTooltipHideTimer = null;
1096
+ }
1097
+ const label = trigger.getAttribute("data-param-tooltip-label") || "Value";
1098
+ const value = trigger.getAttribute("data-param-tooltip-value") || "";
1099
+ const related = trigger.getAttribute("data-param-tooltip-related") || "";
1100
+ const description = trigger.getAttribute("data-param-tooltip-description") || "";
1101
+ if (activeParamTooltipTrigger && activeParamTooltipTrigger !== trigger) {
1102
+ activeParamTooltipTrigger.setAttribute("aria-expanded", "false");
1103
+ }
1104
+ activeParamTooltipTrigger = trigger;
1105
+ activeParamTooltipTrigger.setAttribute("aria-expanded", "true");
1106
+ const pathLabel = related ? " | path: " + related : "";
1107
+ paramTooltipLine.textContent = label + ": " + value + pathLabel;
1108
+ if (description.trim()) {
1109
+ paramTooltipDescription.textContent = description;
1110
+ paramTooltipDescription.classList.remove("hidden");
1111
+ } else {
1112
+ paramTooltipDescription.textContent = "";
1113
+ paramTooltipDescription.classList.add("hidden");
1114
+ }
1115
+ paramTooltipRoot.classList.add("is-visible");
1116
+ paramTooltipRoot.setAttribute("aria-hidden", "false");
1117
+ positionParamTooltip(trigger);
1118
+ }
1119
+
1120
+ function registerParamTooltipTargets(scope) {
1121
+ if (!scope) return;
1122
+ const targets = scope.querySelectorAll("[data-param-tooltip-value]");
1123
+ for (const target of targets) {
1124
+ target.addEventListener("click", (event) => {
1125
+ event.preventDefault();
1126
+ if (
1127
+ activeParamTooltipTrigger === target &&
1128
+ paramTooltipRoot &&
1129
+ paramTooltipRoot.classList.contains("is-visible")
1130
+ ) {
1131
+ hideParamTooltip();
1132
+ return;
1133
+ }
1134
+ showParamTooltip(target);
1135
+ });
1136
+ target.addEventListener("mouseenter", () => {
1137
+ showParamTooltip(target);
1138
+ });
1139
+ target.addEventListener("mouseleave", (event) => {
1140
+ const related = event.relatedTarget;
1141
+ if (paramTooltipRoot && related && paramTooltipRoot.contains(related)) return;
1142
+ scheduleParamTooltipHide();
1143
+ });
1144
+ target.addEventListener("focus", () => {
1145
+ showParamTooltip(target);
1146
+ });
1147
+ target.addEventListener("blur", (event) => {
1148
+ const related = event.relatedTarget;
1149
+ if (paramTooltipRoot && related && paramTooltipRoot.contains(related)) return;
1150
+ scheduleParamTooltipHide();
1151
+ });
1152
+ }
1153
+ }
1154
+
622
1155
  function renderParamSection(title, params) {
623
1156
  if (!params.length) return "";
624
1157
  let rows = "";
625
1158
  for (const p of params) {
626
- const type = escapeHtml((p.schema && p.schema.type) || "unknown");
627
- const name = escapeHtml(p.name || "");
628
- rows += '<div class="py-2 flex justify-between border-b border-light-border/50 dark:border-dark-border/50"><div><code class="text-sm font-mono">' + name + '</code><span class="text-xs text-brand ml-2">' + (p.required ? "required" : "optional") + '</span></div><span class="text-xs font-mono opacity-60">' + type + '</span></div>';
1159
+ const schema = resolveSchemaRef(p.schema || {});
1160
+ const typeRaw = getSchemaTypeLabel(schema);
1161
+ const type = escapeHtml(typeRaw);
1162
+ const nameRaw = p.name || "";
1163
+ const name = escapeHtml(nameRaw);
1164
+ const tooltipName = escapeHtmlAttribute(nameRaw);
1165
+ const tooltipType = escapeHtmlAttribute(typeRaw);
1166
+ const tooltipDescription = (typeof p.description === "string" && p.description.trim())
1167
+ ? escapeHtmlAttribute(p.description.trim())
1168
+ : (typeof schema.description === "string" && schema.description.trim())
1169
+ ? escapeHtmlAttribute(schema.description.trim())
1170
+ : "";
1171
+ const desc = (typeof p.description === "string" && p.description.trim())
1172
+ ? '<p class="text-xs opacity-60 mt-0.5 leading-snug">' + renderMarkdown(p.description.trim()) + '</p>'
1173
+ : "";
1174
+ const extra = buildSchemaExtra(schema);
1175
+ rows +=
1176
+ '<div class="param-row py-2 border-b border-light-border/50 dark:border-dark-border/50">' +
1177
+ '<div class="param-row-head">' +
1178
+ '<div class="param-row-main">' +
1179
+ '<button type="button" class="param-tooltip-trigger param-name-trigger" data-param-tooltip-label="Parameter" data-param-tooltip-value="' +
1180
+ tooltipName +
1181
+ '" data-param-tooltip-description="' +
1182
+ tooltipDescription +
1183
+ '" aria-expanded="false">' +
1184
+ '<code class="text-sm font-mono param-name-text">' +
1185
+ name +
1186
+ "</code></button>" +
1187
+ '<span class="text-xs text-brand shrink-0">' +
1188
+ (p.required ? "required" : "optional") +
1189
+ "</span></div>" +
1190
+ '<button type="button" class="param-tooltip-trigger param-type-fade text-xs font-mono opacity-60" data-param-tooltip-label="Type" data-param-tooltip-value="' +
1191
+ tooltipType +
1192
+ '" data-param-tooltip-description="' +
1193
+ tooltipDescription +
1194
+ '" aria-expanded="false">' +
1195
+ type +
1196
+ "</button></div>" +
1197
+ desc +
1198
+ extra +
1199
+ "</div>";
629
1200
  }
630
1201
  return '<div><h3 class="text-sm font-semibold mb-3 flex items-center border-b border-light-border dark:border-dark-border pb-2">' + escapeHtml(title) + "</h3>" + rows + "</div>";
631
1202
  }
632
1203
 
633
1204
  function getSchemaTypeLabel(schema) {
634
- if (!schema || typeof schema !== "object") return "unknown";
635
- if (Array.isArray(schema.type)) return schema.type.join(" | ");
636
- if (schema.type) return String(schema.type);
637
- if (schema.properties) return "object";
638
- if (schema.items) return "array";
639
- if (Array.isArray(schema.oneOf)) return "oneOf";
640
- if (Array.isArray(schema.anyOf)) return "anyOf";
641
- if (Array.isArray(schema.allOf)) return "allOf";
1205
+ const resolved = resolveSchemaRef(schema);
1206
+ if (!resolved || typeof resolved !== "object") return "unknown";
1207
+ if (Array.isArray(resolved.type)) return resolved.type.join(" | ");
1208
+ if (resolved.type) return String(resolved.type);
1209
+ if (resolved.properties) return "object";
1210
+ if (resolved.items) return "array";
1211
+ if (Array.isArray(resolved.oneOf)) return "oneOf";
1212
+ if (Array.isArray(resolved.anyOf)) return "anyOf";
1213
+ if (Array.isArray(resolved.allOf)) return "allOf";
642
1214
  return "unknown";
643
1215
  }
644
1216
 
1217
+ function buildSchemaExtra(schema) {
1218
+ const resolved = resolveSchemaRef(schema);
1219
+ if (!resolved || typeof resolved !== "object") return "";
1220
+ const chips = [];
1221
+ if (resolved.format) chips.push(escapeHtml(String(resolved.format)));
1222
+ if (Array.isArray(resolved.enum) && resolved.enum.length > 0) {
1223
+ const shown = resolved.enum.slice(0, 5).map(function(v) { return escapeHtml(JSON.stringify(v)); });
1224
+ chips.push(shown.join(" | ") + (resolved.enum.length > 5 ? " \u2026" : ""));
1225
+ }
1226
+ if (resolved.minimum !== undefined) chips.push("min: " + resolved.minimum);
1227
+ if (resolved.maximum !== undefined) chips.push("max: " + resolved.maximum);
1228
+ if (typeof resolved.exclusiveMinimum === "number") chips.push("&gt;" + resolved.exclusiveMinimum);
1229
+ if (typeof resolved.exclusiveMaximum === "number") chips.push("&lt;" + resolved.exclusiveMaximum);
1230
+ if (resolved.minLength !== undefined) chips.push("minLen: " + resolved.minLength);
1231
+ if (resolved.maxLength !== undefined) chips.push("maxLen: " + resolved.maxLength);
1232
+ if (resolved.minItems !== undefined) chips.push("minItems: " + resolved.minItems);
1233
+ if (resolved.maxItems !== undefined) chips.push("maxItems: " + resolved.maxItems);
1234
+ if (resolved.uniqueItems) chips.push("unique");
1235
+ if (resolved.pattern) chips.push("/" + escapeHtml(String(resolved.pattern)) + "/");
1236
+ if (!chips.length) return "";
1237
+ return '<div class="flex flex-wrap gap-1 mt-1.5">' +
1238
+ chips.map(function(c) {
1239
+ return '<span class="text-[10px] px-1.5 py-0.5 rounded bg-black/5 dark:bg-white/5 font-mono opacity-80">' + c + '</span>';
1240
+ }).join("") +
1241
+ '</div>';
1242
+ }
1243
+
1244
+ function resolveSchemaRef(schema, visitedRefs) {
1245
+ if (!schema || typeof schema !== "object") return schema;
1246
+ const ref = typeof schema.$ref === "string" ? schema.$ref : "";
1247
+ if (!ref || !ref.startsWith("#/components/schemas/")) {
1248
+ return schema;
1249
+ }
1250
+
1251
+ const seen = visitedRefs || new Set();
1252
+ if (seen.has(ref)) return schema;
1253
+ seen.add(ref);
1254
+
1255
+ const parts = ref.split("/");
1256
+ const schemaName = parts[parts.length - 1];
1257
+ const referenced = spec && spec.components && spec.components.schemas && spec.components.schemas[schemaName];
1258
+ if (!referenced || typeof referenced !== "object") return schema;
1259
+
1260
+ const merged = Object.assign({}, referenced, schema);
1261
+ delete merged.$ref;
1262
+ return resolveSchemaRef(merged, seen);
1263
+ }
1264
+
645
1265
  function buildSchemaChildren(schema) {
646
- if (!schema || typeof schema !== "object") return [];
1266
+ const resolved = resolveSchemaRef(schema);
1267
+ if (!resolved || typeof resolved !== "object") return [];
647
1268
 
648
1269
  const children = [];
649
1270
 
650
- if (schema.properties && typeof schema.properties === "object") {
1271
+ if (resolved.properties && typeof resolved.properties === "object") {
651
1272
  const requiredSet = new Set(
652
- Array.isArray(schema.required) ? schema.required : [],
1273
+ Array.isArray(resolved.required) ? resolved.required : [],
653
1274
  );
654
- for (const [name, childSchema] of Object.entries(schema.properties)) {
1275
+ for (const [name, childSchema] of Object.entries(resolved.properties)) {
1276
+ const childDef = childSchema || {};
1277
+ const isArrayType = Array.isArray(childDef.type)
1278
+ ? childDef.type.includes("array")
1279
+ : childDef.type === "array";
1280
+ const isArrayLike = isArrayType || childDef.items !== undefined;
655
1281
  children.push({
656
- name,
657
- schema: childSchema || {},
1282
+ name: isArrayLike ? (name + "[]") : name,
1283
+ schema: childDef,
658
1284
  required: requiredSet.has(name),
659
1285
  });
660
1286
  }
661
1287
  }
662
1288
 
663
- if (schema.items) {
1289
+ if (resolved.items) {
664
1290
  children.push({
665
- name: "items[]",
666
- schema: schema.items,
1291
+ name: getArrayItemNodeName(resolved.items),
1292
+ schema: resolved.items,
667
1293
  required: true,
668
1294
  });
669
1295
  }
@@ -671,45 +1297,100 @@ ${t.join(`,
671
1297
  return children;
672
1298
  }
673
1299
 
674
- function renderSchemaFieldNode(field, depth) {
675
- const schema = field.schema || {};
676
- const name = escapeHtml(field.name || "field");
1300
+ function getArrayItemNodeName(itemSchema) {
1301
+ if (!itemSchema || typeof itemSchema !== "object") return "item";
1302
+ const title =
1303
+ typeof itemSchema.title === "string" && itemSchema.title.trim()
1304
+ ? itemSchema.title.trim()
1305
+ : "";
1306
+ if (title) return title;
1307
+
1308
+ const ref =
1309
+ typeof itemSchema.$ref === "string" && itemSchema.$ref.trim()
1310
+ ? itemSchema.$ref.trim()
1311
+ : "";
1312
+ if (ref) {
1313
+ const parts = ref.split("/").filter(Boolean);
1314
+ const last = parts[parts.length - 1];
1315
+ if (last) return last;
1316
+ }
1317
+
1318
+ const typeLabel = getSchemaTypeLabel(itemSchema);
1319
+ if (typeLabel && typeLabel !== "unknown") return typeLabel;
1320
+ return "type";
1321
+ }
1322
+
1323
+ function renderSchemaFieldNode(field, depth, parentPath) {
1324
+ const schema = resolveSchemaRef(field.schema || {});
1325
+ const nameRaw = field.name || "field";
1326
+ const name = escapeHtml(nameRaw);
677
1327
  const requiredLabel = field.required ? "required" : "optional";
678
- const type = escapeHtml(getSchemaTypeLabel(schema));
1328
+ const typeRaw = getSchemaTypeLabel(schema);
1329
+ const type = escapeHtml(typeRaw);
1330
+ const tooltipName = escapeHtmlAttribute(nameRaw);
1331
+ const tooltipType = escapeHtmlAttribute(typeRaw);
1332
+ const fieldPath = parentPath ? (parentPath + "." + nameRaw) : nameRaw;
1333
+ const tooltipPath = escapeHtmlAttribute(fieldPath);
1334
+ const tooltipDescription = (typeof schema.description === "string" && schema.description.trim())
1335
+ ? escapeHtmlAttribute(schema.description.trim())
1336
+ : "";
679
1337
  const children = buildSchemaChildren(schema);
680
1338
  const padding = depth * 14;
1339
+ const extra = buildSchemaExtra(schema);
681
1340
 
682
1341
  if (!children.length) {
683
1342
  return (
684
- '<div class="py-2 border-b border-light-border/50 dark:border-dark-border/50" style="padding-left:' +
1343
+ '<div class="param-row py-2 border-b border-light-border/50 dark:border-dark-border/50" style="padding-left:' +
685
1344
  padding +
686
- 'px"><div class="flex justify-between"><div><code class="text-sm font-mono">' +
1345
+ 'px"><div class="param-row-head"><div class="param-row-main">' +
1346
+ '<button type="button" class="param-tooltip-trigger param-name-trigger" data-param-tooltip-label="Field" data-param-tooltip-value="' +
1347
+ tooltipName +
1348
+ '" data-param-tooltip-related="' +
1349
+ tooltipPath +
1350
+ '" data-param-tooltip-description="' +
1351
+ tooltipDescription +
1352
+ '" aria-expanded="false"><code class="text-sm font-mono param-name-text">' +
687
1353
  name +
688
- '</code><span class="text-xs text-brand ml-2">' +
1354
+ '</code></button><span class="text-xs text-brand shrink-0">' +
689
1355
  requiredLabel +
690
- '</span></div><span class="text-xs font-mono opacity-60">' +
1356
+ '</span></div><button type="button" class="param-tooltip-trigger param-type-fade text-xs font-mono opacity-60" data-param-tooltip-label="Type" data-param-tooltip-value="' +
1357
+ tooltipType +
1358
+ '" data-param-tooltip-description="' +
1359
+ tooltipDescription +
1360
+ '" aria-expanded="false">' +
691
1361
  type +
692
- "</span></div></div>"
1362
+ "</button></div>" + extra + "</div>"
693
1363
  );
694
1364
  }
695
1365
 
696
1366
  let nested = "";
697
1367
  for (const child of children) {
698
- nested += renderSchemaFieldNode(child, depth + 1);
1368
+ nested += renderSchemaFieldNode(child, depth + 1, fieldPath);
699
1369
  }
700
1370
 
701
1371
  return (
702
- '<details class="border-b border-light-border/50 dark:border-dark-border/50" open>' +
703
- '<summary class="list-none cursor-pointer py-2 flex justify-between items-center" style="padding-left:' +
1372
+ '<details open>' +
1373
+ '<summary class="list-none cursor-pointer py-2 border-b border-light-border/50 dark:border-dark-border/50" style="padding-left:' +
704
1374
  padding +
705
- 'px"><div class="flex items-center gap-2"><span class="text-xs opacity-70">\u25BE</span><code class="text-sm font-mono">' +
1375
+ 'px"><div class="param-row-head"><div class="param-row-main"><span class="text-xs opacity-70 shrink-0">\u25BE</span>' +
1376
+ '<button type="button" class="param-tooltip-trigger param-name-trigger" data-param-tooltip-label="Field" data-param-tooltip-value="' +
1377
+ tooltipName +
1378
+ '" data-param-tooltip-related="' +
1379
+ tooltipPath +
1380
+ '" data-param-tooltip-description="' +
1381
+ tooltipDescription +
1382
+ '" aria-expanded="false"><code class="text-sm font-mono param-name-text">' +
706
1383
  name +
707
- '</code><span class="text-xs text-brand">' +
1384
+ '</code></button><span class="text-xs text-brand shrink-0">' +
708
1385
  requiredLabel +
709
- '</span></div><span class="text-xs font-mono opacity-60">' +
1386
+ '</span></div><button type="button" class="param-tooltip-trigger param-type-fade text-xs font-mono opacity-60" data-param-tooltip-label="Type" data-param-tooltip-value="' +
1387
+ tooltipType +
1388
+ '" data-param-tooltip-description="' +
1389
+ tooltipDescription +
1390
+ '" aria-expanded="false">' +
710
1391
  type +
711
- "</span></summary>" +
712
- '<div class="pb-1">' +
1392
+ "</button></div>" + extra + "</summary>" +
1393
+ "<div>" +
713
1394
  nested +
714
1395
  "</div></details>"
715
1396
  );
@@ -722,7 +1403,7 @@ ${t.join(`,
722
1403
 
723
1404
  let rows = "";
724
1405
  for (const child of rootChildren) {
725
- rows += renderSchemaFieldNode(child, 0);
1406
+ rows += renderSchemaFieldNode(child, 0, "");
726
1407
  }
727
1408
 
728
1409
  return (
@@ -749,27 +1430,40 @@ ${t.join(`,
749
1430
  const responseDef = responses[statusCode];
750
1431
  if (!responseDef || typeof responseDef !== "object") continue;
751
1432
 
1433
+ const responseDesc = (typeof responseDef.description === "string" && responseDef.description.trim())
1434
+ ? responseDef.description.trim()
1435
+ : "";
1436
+
752
1437
  const jsonSchema =
753
1438
  responseDef.content &&
754
1439
  responseDef.content["application/json"] &&
755
1440
  responseDef.content["application/json"].schema;
756
1441
 
757
- if (!jsonSchema || typeof jsonSchema !== "object") continue;
758
-
759
- const rootChildren = buildSchemaChildren(jsonSchema);
760
- if (!rootChildren.length) continue;
761
-
762
1442
  let rows = "";
763
- for (const child of rootChildren) {
764
- rows += renderSchemaFieldNode(child, 0);
1443
+ if (jsonSchema && typeof jsonSchema === "object") {
1444
+ const rootChildren = buildSchemaChildren(jsonSchema);
1445
+ for (const child of rootChildren) {
1446
+ rows += renderSchemaFieldNode(child, 0, "");
1447
+ }
765
1448
  }
766
1449
 
1450
+ if (!responseDesc && !rows) continue;
1451
+
1452
+ const descHtml = responseDesc
1453
+ ? ' <span class="normal-case font-sans opacity-70 ml-1">\u2014 ' + escapeHtml(responseDesc) + '</span>'
1454
+ : "";
1455
+ const contentHtml = rows || '<p class="text-xs opacity-60 mt-1">No schema fields</p>';
1456
+
767
1457
  sections +=
768
- '<div class="mb-4"><h4 class="text-xs font-mono uppercase tracking-wider opacity-70 mb-2">Status ' +
1458
+ '<details class="mb-4">' +
1459
+ '<summary class="list-none cursor-pointer">' +
1460
+ '<h4 class="text-xs font-mono uppercase tracking-wider opacity-70 mb-2">Status ' +
769
1461
  escapeHtml(statusCode) +
1462
+ descHtml +
770
1463
  "</h4>" +
771
- rows +
772
- "</div>";
1464
+ "</summary>" +
1465
+ contentHtml +
1466
+ "</details>";
773
1467
  }
774
1468
 
775
1469
  if (!sections) return "";
@@ -861,6 +1555,7 @@ ${t.join(`,
861
1555
  "w-full text-xs px-2.5 py-2 rounded border border-light-border dark:border-dark-border bg-light-bg dark:bg-dark-bg focus:outline-none focus:border-brand dark:focus:border-brand transition-colors font-mono";
862
1556
  keyInput.addEventListener("input", () => {
863
1557
  entry.key = keyInput.value;
1558
+ saveHeaders();
864
1559
  updateRequestPreview();
865
1560
  });
866
1561
 
@@ -875,6 +1570,7 @@ ${t.join(`,
875
1570
  "w-full text-xs px-2.5 py-2 rounded border border-light-border dark:border-dark-border bg-light-bg dark:bg-dark-bg focus:outline-none focus:border-brand dark:focus:border-brand transition-colors font-mono";
876
1571
  valueInput.addEventListener("input", () => {
877
1572
  entry.value = valueInput.value;
1573
+ saveHeaders();
878
1574
  updateRequestPreview();
879
1575
  });
880
1576
 
@@ -888,6 +1584,7 @@ ${t.join(`,
888
1584
  '<svg class="w-3.5 h-3.5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 12h12"></path></svg>';
889
1585
  removeButton.addEventListener("click", () => {
890
1586
  requestHeaders.splice(index, 1);
1587
+ saveHeaders();
891
1588
  renderHeaderInputs();
892
1589
  updateRequestPreview();
893
1590
  });
@@ -904,15 +1601,32 @@ ${t.join(`,
904
1601
  return Object.keys(headers).some((key) => key.toLowerCase() === target);
905
1602
  }
906
1603
 
907
- function getRequestHeadersObject() {
908
- const headers = {};
1604
+ function buildCookieHeaderValue(cookieValues) {
1605
+ const entries = Object.entries(cookieValues);
1606
+ if (!entries.length) return "";
1607
+ return entries
1608
+ .map(([name, value]) => String(name) + "=" + encodeURIComponent(String(value)))
1609
+ .join("; ");
1610
+ }
1611
+
1612
+ function getRequestHeadersObject(op) {
1613
+ const auth = getAuthHeaders(op);
1614
+ const authCookies = getAuthCookieParams(op);
1615
+ if (Object.keys(authCookies).length > 0) {
1616
+ const cookieHeader = buildCookieHeaderValue(authCookies);
1617
+ if (cookieHeader) {
1618
+ auth["Cookie"] = cookieHeader;
1619
+ }
1620
+ }
1621
+ const manual = {};
909
1622
  for (const entry of requestHeaders) {
910
1623
  const key = String(entry.key || "").trim();
911
1624
  const value = String(entry.value || "").trim();
912
1625
  if (!key || !value) continue;
913
- headers[key] = value;
1626
+ manual[key] = value;
914
1627
  }
915
- return headers;
1628
+ // Auth provides defaults; manual headers win on conflict
1629
+ return Object.assign({}, auth, manual);
916
1630
  }
917
1631
 
918
1632
  function buildCurl(op, headers, body, requestPath) {
@@ -949,6 +1663,33 @@ ${t.join(`,
949
1663
  .replace(/>/g, "&gt;");
950
1664
  }
951
1665
 
1666
+ function escapeHtmlAttribute(value) {
1667
+ return String(value)
1668
+ .replace(/&/g, "&amp;")
1669
+ .replace(/</g, "&lt;")
1670
+ .replace(/>/g, "&gt;")
1671
+ .replace(/"/g, "&quot;")
1672
+ .replace(/'/g, "&#39;");
1673
+ }
1674
+
1675
+ function renderMarkdown(text) {
1676
+ if (!text || typeof text !== "string") return "";
1677
+ var s = escapeHtml(text);
1678
+ // inline code \u2014 process first to protect content inside backticks
1679
+ s = s.replace(/\`([^\`\\n]+)\`/g, '<code class="text-xs font-mono bg-black/5 dark:bg-white/5 px-1 py-0.5 rounded">$1</code>');
1680
+ // bold **text**
1681
+ s = s.replace(/\\*\\*([^*\\n]+)\\*\\*/g, '<strong>$1</strong>');
1682
+ // italic *text*
1683
+ s = s.replace(/\\*([^*\\n]+)\\*/g, '<em>$1</em>');
1684
+ // links [text](url)
1685
+ s = s.replace(/\\[([^\\]]+)\\]\\(([^)]+)\\)/g, function(m, txt, url) {
1686
+ var lc = url.toLowerCase().replace(/\\s/g, "");
1687
+ if (lc.indexOf("javascript:") === 0 || lc.indexOf("data:") === 0 || lc.indexOf("vbscript:") === 0) return txt;
1688
+ return '<a href="' + url.replace(/"/g, '&quot;') + '" target="_blank" rel="noopener noreferrer" class="text-brand hover:underline">' + txt + '</a>';
1689
+ });
1690
+ return s;
1691
+ }
1692
+
952
1693
  function toPrettyJson(value) {
953
1694
  const trimmed = (value || "").trim();
954
1695
  if (!trimmed) return null;
@@ -1082,10 +1823,10 @@ ${t.join(`,
1082
1823
 
1083
1824
  const { path, query } = getOperationParameterGroups(selected);
1084
1825
  const values = getParameterValues(selected);
1085
- const requestPath = buildRequestPath(selected, path, query, values);
1826
+ const requestPath = buildRequestPath(selected, path, query, values, getAuthQueryParams(selected));
1086
1827
  const bodyInput = document.getElementById("body-input");
1087
1828
  const body = bodyInput ? bodyInput.value.trim() : "";
1088
- const headers = getRequestHeadersObject();
1829
+ const headers = getRequestHeadersObject(selected);
1089
1830
  if (body && !hasHeaderName(headers, "Content-Type")) {
1090
1831
  headers["Content-Type"] = "application/json";
1091
1832
  }
@@ -1136,8 +1877,13 @@ ${t.join(`,
1136
1877
  }
1137
1878
  setResponseContent("", "", false);
1138
1879
 
1880
+ const deprecatedBanner = document.getElementById("deprecated-banner");
1881
+ if (deprecatedBanner) {
1882
+ deprecatedBanner.classList.toggle("hidden", !op.deprecated);
1883
+ }
1884
+
1139
1885
  document.getElementById("tag-title").textContent = selected.tag;
1140
- document.getElementById("tag-description").textContent = op.description || "Interactive API documentation.";
1886
+ document.getElementById("tag-description").innerHTML = op.description ? renderMarkdown(op.description) : "Interactive API documentation.";
1141
1887
  const methodNode = document.getElementById("endpoint-method");
1142
1888
  methodNode.textContent = selected.method;
1143
1889
  methodNode.className = "px-2.5 py-0.5 rounded-full text-xs font-mono font-medium " + (methodBadge[selected.method] || methodBadgeDefault);
@@ -1154,7 +1900,13 @@ ${t.join(`,
1154
1900
 
1155
1901
  html += renderRequestBodySchemaSection(reqSchema);
1156
1902
  html += renderResponseSchemasSection(op.responses);
1157
- document.getElementById("params-column").innerHTML = html || '<div class="text-sm opacity-70">No parameters</div>';
1903
+ const paramsColumn = document.getElementById("params-column");
1904
+ if (paramsColumn) {
1905
+ hideParamTooltip();
1906
+ paramsColumn.innerHTML = html || '<div class="text-sm opacity-70">No parameters</div>';
1907
+ registerParamTooltipTargets(paramsColumn);
1908
+ }
1909
+ renderAuthPanel();
1158
1910
  renderTryItParameterInputs(path, query);
1159
1911
  renderHeaderInputs();
1160
1912
  updateRequestPreview();
@@ -1165,6 +1917,24 @@ ${t.join(`,
1165
1917
  document.getElementById("copy-curl").addEventListener("click", async () => {
1166
1918
  try { await navigator.clipboard.writeText(document.getElementById("curl-code").textContent || ""); } catch {}
1167
1919
  });
1920
+ if (paramTooltipRoot) {
1921
+ paramTooltipRoot.addEventListener("mouseenter", () => {
1922
+ if (paramTooltipHideTimer) {
1923
+ window.clearTimeout(paramTooltipHideTimer);
1924
+ paramTooltipHideTimer = null;
1925
+ }
1926
+ });
1927
+ paramTooltipRoot.addEventListener("mouseleave", () => {
1928
+ scheduleParamTooltipHide();
1929
+ });
1930
+ }
1931
+ document.addEventListener("pointerdown", (event) => {
1932
+ if (!paramTooltipRoot) return;
1933
+ const target = event.target;
1934
+ if (target && paramTooltipRoot.contains(target)) return;
1935
+ if (target && target.closest && target.closest("[data-param-tooltip-value]")) return;
1936
+ hideParamTooltip();
1937
+ });
1168
1938
  document.getElementById("sidebar-search").addEventListener("input", (event) => {
1169
1939
  sidebarSearchQuery = event.currentTarget.value || "";
1170
1940
  renderSidebar();
@@ -1190,7 +1960,7 @@ ${t.join(`,
1190
1960
  return;
1191
1961
  }
1192
1962
 
1193
- const requestPath = buildRequestPath(selected, path, query, values);
1963
+ const requestPath = buildRequestPath(selected, path, query, values, getAuthQueryParams(selected));
1194
1964
  formatBodyJsonInput();
1195
1965
  updateBodyJsonPresentation();
1196
1966
  const op = selected.operation || {};
@@ -1199,7 +1969,7 @@ ${t.join(`,
1199
1969
  const bodyInput = document.getElementById("body-input");
1200
1970
  const body =
1201
1971
  supportsBody && bodyInput ? bodyInput.value.trim() : "";
1202
- const headers = getRequestHeadersObject();
1972
+ const headers = getRequestHeadersObject(selected);
1203
1973
  if (body && !hasHeaderName(headers, "Content-Type")) {
1204
1974
  headers["Content-Type"] = "application/json";
1205
1975
  }
@@ -1207,7 +1977,13 @@ ${t.join(`,
1207
1977
  setSubmitLoading(true);
1208
1978
  try {
1209
1979
  const requestStart = performance.now();
1210
- const response = await fetch(requestPath, { method: selected.method, headers, body: body || undefined });
1980
+ applyAuthCookies(selected);
1981
+ const response = await fetch(requestPath, {
1982
+ method: selected.method,
1983
+ headers,
1984
+ body: body || undefined,
1985
+ credentials: "same-origin",
1986
+ });
1211
1987
  const text = await response.text();
1212
1988
  const responseTimeMs = Math.round(performance.now() - requestStart);
1213
1989
  const contentType = response.headers.get("content-type") || "unknown";
@@ -1283,6 +2059,7 @@ ${t.join(`,
1283
2059
 
1284
2060
  document.getElementById("add-header-btn").addEventListener("click", () => {
1285
2061
  requestHeaders.push({ key: "", value: "" });
2062
+ saveHeaders();
1286
2063
  renderHeaderInputs();
1287
2064
  updateRequestPreview();
1288
2065
  });
@@ -1396,12 +2173,21 @@ ${t.join(`,
1396
2173
  setMobileSidebarOpen(false);
1397
2174
  });
1398
2175
  window.addEventListener("resize", () => {
2176
+ if (activeParamTooltipTrigger) {
2177
+ positionParamTooltip(activeParamTooltipTrigger);
2178
+ }
1399
2179
  if (window.innerWidth >= 768 && isMobileSidebarOpen) {
1400
2180
  setMobileSidebarOpen(false);
1401
2181
  }
1402
2182
  });
2183
+ window.addEventListener("scroll", () => {
2184
+ if (activeParamTooltipTrigger) {
2185
+ positionParamTooltip(activeParamTooltipTrigger);
2186
+ }
2187
+ }, true);
1403
2188
  document.addEventListener("keydown", (event) => {
1404
2189
  if (event.key === "Escape") {
2190
+ hideParamTooltip();
1405
2191
  if (isMobileSidebarOpen) {
1406
2192
  setMobileSidebarOpen(false);
1407
2193
  }
@@ -1426,9 +2212,446 @@ ${t.join(`,
1426
2212
  }
1427
2213
  });
1428
2214
 
2215
+ function getOperationSecurityRequirements(op) {
2216
+ const operationSecurity = op && op.operation && Array.isArray(op.operation.security)
2217
+ ? op.operation.security
2218
+ : null;
2219
+ if (operationSecurity) {
2220
+ return operationSecurity;
2221
+ }
2222
+ return Array.isArray(spec.security) ? spec.security : [];
2223
+ }
2224
+
2225
+ function getAuthSelectionKeyForOperation(op) {
2226
+ if (!op) return "";
2227
+ return getOperationKey(op);
2228
+ }
2229
+
2230
+ function getAuthSchemeOptionsForOperation(op) {
2231
+ const requirements = getOperationSecurityRequirements(op).filter((requirement) =>
2232
+ requirement && typeof requirement === "object" && !Array.isArray(requirement)
2233
+ );
2234
+ if (!requirements.length) return [];
2235
+
2236
+ const seen = new Set();
2237
+ const options = [];
2238
+ for (const requirement of requirements) {
2239
+ for (const schemeName of Object.keys(requirement)) {
2240
+ if (!Object.prototype.hasOwnProperty.call(authSchemes, schemeName)) continue;
2241
+ if (seen.has(schemeName)) continue;
2242
+ seen.add(schemeName);
2243
+ options.push(schemeName);
2244
+ }
2245
+ }
2246
+ return options;
2247
+ }
2248
+
2249
+ function getSelectedAuthSchemeForOperation(op) {
2250
+ const selectionKey = getAuthSelectionKeyForOperation(op);
2251
+ if (!selectionKey) return null;
2252
+
2253
+ const selectedScheme = authSelectionState[selectionKey];
2254
+ if (!selectedScheme || typeof selectedScheme !== "string") return null;
2255
+
2256
+ const options = Object.keys(authSchemes);
2257
+ if (!options.includes(selectedScheme)) {
2258
+ delete authSelectionState[selectionKey];
2259
+ saveAuthSelectionState();
2260
+ return null;
2261
+ }
2262
+
2263
+ return selectedScheme;
2264
+ }
2265
+
2266
+ function setSelectedAuthSchemeForOperation(op, schemeName) {
2267
+ const selectionKey = getAuthSelectionKeyForOperation(op);
2268
+ if (!selectionKey) return;
2269
+
2270
+ if (!schemeName) {
2271
+ delete authSelectionState[selectionKey];
2272
+ } else {
2273
+ authSelectionState[selectionKey] = schemeName;
2274
+ }
2275
+ saveAuthSelectionState();
2276
+ }
2277
+
2278
+ function hasAuthStateForScheme(schemeName) {
2279
+ const scheme = authSchemes[schemeName];
2280
+ if (!scheme) return false;
2281
+
2282
+ const state = authState[schemeName] || {};
2283
+ const type = (scheme.type || "").toLowerCase();
2284
+ const httpScheme = (scheme.scheme || "").toLowerCase();
2285
+
2286
+ if (type === "http" && httpScheme === "basic") {
2287
+ return Boolean(state.username && state.password);
2288
+ }
2289
+ if (type === "http") {
2290
+ return Boolean(state.token);
2291
+ }
2292
+ if (type === "apikey") {
2293
+ return Boolean(state.value);
2294
+ }
2295
+ if (type === "oauth2" || type === "openidconnect") {
2296
+ return Boolean(state.token);
2297
+ }
2298
+
2299
+ return false;
2300
+ }
2301
+
2302
+ function chooseOperationSecurityRequirement(op) {
2303
+ const requirements = getOperationSecurityRequirements(op).filter((requirement) =>
2304
+ requirement && typeof requirement === "object" && !Array.isArray(requirement)
2305
+ );
2306
+ if (!requirements.length) return null;
2307
+
2308
+ const selectedScheme = getSelectedAuthSchemeForOperation(op);
2309
+ if (selectedScheme) {
2310
+ const selectedRequirement = requirements.find((requirement) =>
2311
+ Object.prototype.hasOwnProperty.call(requirement, selectedScheme)
2312
+ );
2313
+ if (selectedRequirement) return selectedRequirement;
2314
+ }
2315
+
2316
+ let bestRequirement = null;
2317
+ let bestScore = -1;
2318
+
2319
+ for (const requirement of requirements) {
2320
+ const schemeNames = Object.keys(requirement).filter((schemeName) =>
2321
+ Object.prototype.hasOwnProperty.call(authSchemes, schemeName)
2322
+ );
2323
+ if (!schemeNames.length) continue;
2324
+
2325
+ const providedCount = schemeNames.filter((schemeName) => hasAuthStateForScheme(schemeName)).length;
2326
+ const isComplete = providedCount === schemeNames.length;
2327
+ const score = isComplete ? 1000 + providedCount : providedCount;
2328
+
2329
+ if (score > bestScore) {
2330
+ bestScore = score;
2331
+ bestRequirement = requirement;
2332
+ }
2333
+ }
2334
+
2335
+ return bestRequirement || requirements[0];
2336
+ }
2337
+
2338
+ function getAuthSchemeNamesForOperation(op) {
2339
+ const schemeNames = Object.keys(authSchemes);
2340
+ if (!schemeNames.length) return [];
2341
+
2342
+ const selectedScheme = getSelectedAuthSchemeForOperation(op);
2343
+ if (selectedScheme) {
2344
+ const requirement = chooseOperationSecurityRequirement(op);
2345
+ if (requirement && Object.prototype.hasOwnProperty.call(requirement, selectedScheme)) {
2346
+ return Object.keys(requirement).filter((schemeName) =>
2347
+ Object.prototype.hasOwnProperty.call(authSchemes, schemeName)
2348
+ );
2349
+ }
2350
+ return [selectedScheme];
2351
+ }
2352
+
2353
+ const requirement = chooseOperationSecurityRequirement(op);
2354
+ if (!requirement) return [];
2355
+
2356
+ return Object.keys(requirement).filter((schemeName) =>
2357
+ Object.prototype.hasOwnProperty.call(authSchemes, schemeName)
2358
+ );
2359
+ }
2360
+
2361
+ function getAuthHeaders(op) {
2362
+ const headers = {};
2363
+ const schemeNames = getAuthSchemeNamesForOperation(op);
2364
+ const allSchemeNames = Object.keys(authSchemes);
2365
+
2366
+ if (!allSchemeNames.length) {
2367
+ const state = authState["__default__"] || {};
2368
+ if (state.token) headers["Authorization"] = "Bearer " + state.token;
2369
+ return headers;
2370
+ }
2371
+ if (!schemeNames.length) return headers;
2372
+
2373
+ for (const schemeName of schemeNames) {
2374
+ const scheme = authSchemes[schemeName];
2375
+ const state = authState[schemeName] || {};
2376
+ const type = (scheme.type || "").toLowerCase();
2377
+ const httpScheme = (scheme.scheme || "").toLowerCase();
2378
+
2379
+ if (type === "http" && httpScheme === "basic") {
2380
+ if (state.username && state.password) {
2381
+ try {
2382
+ headers["Authorization"] = "Basic " + btoa(state.username + ":" + state.password);
2383
+ } catch {}
2384
+ }
2385
+ } else if (type === "http") {
2386
+ if (state.token) headers["Authorization"] = "Bearer " + state.token;
2387
+ } else if (type === "apikey" && (scheme.in || "").toLowerCase() === "header") {
2388
+ if (state.value && scheme.name) headers[scheme.name] = state.value;
2389
+ } else if (type === "oauth2" || type === "openidconnect") {
2390
+ if (state.token) headers["Authorization"] = "Bearer " + state.token;
2391
+ }
2392
+ }
2393
+ return headers;
2394
+ }
2395
+
2396
+ function getAuthQueryParams(op) {
2397
+ const params = {};
2398
+ for (const schemeName of getAuthSchemeNamesForOperation(op)) {
2399
+ const scheme = authSchemes[schemeName];
2400
+ if ((scheme.type || "").toLowerCase() === "apikey" && (scheme.in || "").toLowerCase() === "query") {
2401
+ const state = authState[schemeName] || {};
2402
+ if (state.value && scheme.name) params[scheme.name] = state.value;
2403
+ }
2404
+ }
2405
+ return params;
2406
+ }
2407
+
2408
+ function getAuthCookieParams(op) {
2409
+ const cookies = {};
2410
+ for (const schemeName of getAuthSchemeNamesForOperation(op)) {
2411
+ const scheme = authSchemes[schemeName];
2412
+ if ((scheme.type || "").toLowerCase() !== "apikey") continue;
2413
+ if ((scheme.in || "").toLowerCase() !== "cookie") continue;
2414
+ const state = authState[schemeName] || {};
2415
+ if (state.value && scheme.name) {
2416
+ cookies[scheme.name] = state.value;
2417
+ }
2418
+ }
2419
+ return cookies;
2420
+ }
2421
+
2422
+ function applyAuthCookies(op) {
2423
+ const cookies = getAuthCookieParams(op);
2424
+ for (const [name, value] of Object.entries(cookies)) {
2425
+ try {
2426
+ document.cookie = encodeURIComponent(String(name)) + "=" + encodeURIComponent(String(value)) + "; path=/";
2427
+ } catch {}
2428
+ }
2429
+ }
2430
+
2431
+ function renderAuthPanel() {
2432
+ const fields = document.getElementById("auth-fields");
2433
+ if (!fields) return;
2434
+ fields.innerHTML = "";
2435
+
2436
+ const schemeNames = Object.keys(authSchemes);
2437
+ const op = selected;
2438
+ const operationSchemeOptions = op ? getAuthSchemeOptionsForOperation(op) : [];
2439
+ const availableSchemeOptions = Object.keys(authSchemes);
2440
+ const selectedScheme = op ? getSelectedAuthSchemeForOperation(op) : null;
2441
+
2442
+ function getAuthSchemeDisplayLabel(schemeName) {
2443
+ const scheme = authSchemes[schemeName] || {};
2444
+ const type = (scheme.type || "").toLowerCase();
2445
+ const httpScheme = (scheme.scheme || "").toLowerCase();
2446
+ const location = (scheme.in || "").toLowerCase();
2447
+
2448
+ if (type === "http" && httpScheme === "basic") return "HTTP Basic";
2449
+ if (type === "http" && httpScheme === "bearer") return "HTTP Bearer";
2450
+ if (type === "http" && httpScheme === "digest") return "HTTP Digest";
2451
+ if (type === "http") return "HTTP " + (httpScheme || "Token");
2452
+ if (type === "apikey") return "API Key" + (location ? " (" + location + ")" : "");
2453
+ if (type === "oauth2") return "OAuth 2.0";
2454
+ if (type === "openidconnect") return "OpenID Connect";
2455
+ if (type === "mutualtls") return "Mutual TLS";
2456
+ return schemeName;
2457
+ }
2458
+
2459
+ function makeInput(placeholder, value, onInput, type) {
2460
+ const inp = document.createElement("input");
2461
+ inp.type = type || "text";
2462
+ inp.value = value || "";
2463
+ inp.placeholder = placeholder;
2464
+ inp.className = "w-full text-xs px-2.5 py-2 rounded-md border border-light-border dark:border-dark-border bg-light-bg dark:bg-dark-bg focus:outline-none focus:border-brand dark:focus:border-brand transition-colors font-mono";
2465
+ inp.addEventListener("input", onInput);
2466
+ return inp;
2467
+ }
2468
+
2469
+ function makeLabel(text, small) {
2470
+ const el = document.createElement("p");
2471
+ el.className = small
2472
+ ? "text-[10px] font-medium uppercase tracking-wider opacity-55"
2473
+ : "text-[10px] font-semibold uppercase tracking-wider opacity-55";
2474
+ el.textContent = text;
2475
+ return el;
2476
+ }
2477
+
2478
+ function makeField(label, input) {
2479
+ const wrapper = document.createElement("div");
2480
+ wrapper.className = "space-y-1";
2481
+ wrapper.appendChild(makeLabel(label, true));
2482
+ wrapper.appendChild(input);
2483
+ return wrapper;
2484
+ }
2485
+
2486
+ function makeSchemeCard(title, subtitle) {
2487
+ const card = document.createElement("div");
2488
+ card.className = "space-y-2 rounded-md border border-light-border dark:border-dark-border bg-light-bg/40 dark:bg-dark-bg/40 p-2.5";
2489
+
2490
+ const titleRow = document.createElement("div");
2491
+ titleRow.className = "flex items-center justify-between gap-2";
2492
+
2493
+ const heading = document.createElement("p");
2494
+ heading.className = "text-[11px] font-semibold tracking-wide";
2495
+ heading.textContent = title;
2496
+ titleRow.appendChild(heading);
2497
+
2498
+ if (subtitle) {
2499
+ const note = document.createElement("span");
2500
+ note.className = "text-[10px] opacity-60 font-mono";
2501
+ note.textContent = subtitle;
2502
+ titleRow.appendChild(note);
2503
+ }
2504
+
2505
+ card.appendChild(titleRow);
2506
+ return card;
2507
+ }
2508
+
2509
+ if (!schemeNames.length) {
2510
+ if (!authState["__default__"]) authState["__default__"] = {};
2511
+ const defaultCard = makeSchemeCard("Default Auth", "bearer");
2512
+ defaultCard.appendChild(makeField("Token", makeInput("Enter token\u2026", authState["__default__"].token, function(e) {
2513
+ authState["__default__"].token = e.target.value;
2514
+ saveAuthState();
2515
+ updateRequestPreview();
2516
+ })));
2517
+ fields.appendChild(defaultCard);
2518
+ return;
2519
+ }
2520
+
2521
+ if (op && availableSchemeOptions.length > 0) {
2522
+ const selectorWrap = document.createElement("div");
2523
+ selectorWrap.className = "space-y-1";
2524
+ selectorWrap.appendChild(makeLabel("Auth Type"));
2525
+ const select = document.createElement("select");
2526
+ select.className = "w-full text-xs px-2.5 py-2 rounded-md border border-light-border dark:border-dark-border bg-light-bg dark:bg-dark-bg focus:outline-none focus:border-brand dark:focus:border-brand transition-colors font-mono";
2527
+
2528
+ const autoOption = document.createElement("option");
2529
+ autoOption.value = "";
2530
+ autoOption.textContent = "Auto";
2531
+ select.appendChild(autoOption);
2532
+
2533
+ for (const schemeName of availableSchemeOptions) {
2534
+ const option = document.createElement("option");
2535
+ option.value = schemeName;
2536
+ const isOperationScheme = operationSchemeOptions.includes(schemeName);
2537
+ const label = getAuthSchemeDisplayLabel(schemeName);
2538
+ option.textContent = isOperationScheme
2539
+ ? label
2540
+ : (label + " \u2022 override");
2541
+ select.appendChild(option);
2542
+ }
2543
+
2544
+ select.value = selectedScheme || "";
2545
+ select.addEventListener("change", function(e) {
2546
+ setSelectedAuthSchemeForOperation(op, e.target.value || "");
2547
+ renderAuthPanel();
2548
+ updateRequestPreview();
2549
+ });
2550
+ selectorWrap.appendChild(select);
2551
+ fields.appendChild(selectorWrap);
2552
+ }
2553
+
2554
+ const schemesToRender = selectedScheme
2555
+ ? [selectedScheme]
2556
+ : (operationSchemeOptions.length ? operationSchemeOptions : schemeNames);
2557
+
2558
+ for (const schemeName of schemesToRender) {
2559
+ const scheme = authSchemes[schemeName];
2560
+ if (!authState[schemeName]) authState[schemeName] = {};
2561
+ const state = authState[schemeName];
2562
+ const type = (scheme.type || "").toLowerCase();
2563
+ const httpScheme = (scheme.scheme || "").toLowerCase();
2564
+ const card = makeSchemeCard(getAuthSchemeDisplayLabel(schemeName), schemeName);
2565
+
2566
+ if (type === "http" && httpScheme === "basic") {
2567
+ card.appendChild(makeField("Username", makeInput("Username", state.username, function(e) {
2568
+ authState[schemeName].username = e.target.value;
2569
+ saveAuthState();
2570
+ updateRequestPreview();
2571
+ })));
2572
+ card.appendChild(makeField("Password", makeInput("Password", state.password, function(e) {
2573
+ authState[schemeName].password = e.target.value;
2574
+ saveAuthState();
2575
+ updateRequestPreview();
2576
+ }, "password")));
2577
+ } else if (type === "apikey") {
2578
+ const paramName = scheme.name || "key";
2579
+ const location = (scheme.in || "header").toLowerCase();
2580
+ card.appendChild(makeField("API Key", makeInput(paramName + " (" + location + ")", state.value, function(e) {
2581
+ authState[schemeName].value = e.target.value;
2582
+ saveAuthState();
2583
+ updateRequestPreview();
2584
+ })));
2585
+ } else if (type === "oauth2") {
2586
+ card.appendChild(makeField("Access Token", makeInput("OAuth2 access token\u2026", state.token, function(e) {
2587
+ authState[schemeName].token = e.target.value;
2588
+ saveAuthState();
2589
+ updateRequestPreview();
2590
+ })));
2591
+ } else if (type === "openidconnect") {
2592
+ card.appendChild(makeField("ID Token / Access Token", makeInput("OpenID Connect token\u2026", state.token, function(e) {
2593
+ authState[schemeName].token = e.target.value;
2594
+ saveAuthState();
2595
+ updateRequestPreview();
2596
+ })));
2597
+ } else if (type === "http" && httpScheme === "digest") {
2598
+ card.appendChild(makeField("Digest Credential", makeInput("Digest token\u2026", state.token, function(e) {
2599
+ authState[schemeName].token = e.target.value;
2600
+ saveAuthState();
2601
+ updateRequestPreview();
2602
+ })));
2603
+ } else if (type === "http" && httpScheme === "bearer") {
2604
+ card.appendChild(makeField("Bearer Token", makeInput("Bearer token\u2026", state.token, function(e) {
2605
+ authState[schemeName].token = e.target.value;
2606
+ saveAuthState();
2607
+ updateRequestPreview();
2608
+ })));
2609
+ } else if (type === "mutualtls") {
2610
+ const hint = document.createElement("p");
2611
+ hint.className = "text-xs opacity-70 leading-relaxed";
2612
+ hint.textContent = "Configured by your client certificate. No token input required.";
2613
+ card.appendChild(hint);
2614
+ } else {
2615
+ card.appendChild(makeField("Token", makeInput("Token\u2026", state.token, function(e) {
2616
+ authState[schemeName].token = e.target.value;
2617
+ saveAuthState();
2618
+ updateRequestPreview();
2619
+ })));
2620
+ }
2621
+ fields.appendChild(card);
2622
+ }
2623
+ }
2624
+
2625
+ let authPanelOpen = true;
2626
+ document.getElementById("auth-toggle").addEventListener("click", function() {
2627
+ authPanelOpen = !authPanelOpen;
2628
+ const fieldsEl = document.getElementById("auth-fields");
2629
+ const chevron = document.getElementById("auth-chevron");
2630
+ if (fieldsEl) fieldsEl.classList.toggle("hidden", !authPanelOpen);
2631
+ if (chevron) chevron.style.transform = authPanelOpen ? "" : "rotate(-90deg)";
2632
+ });
2633
+
2634
+ // Restore selected operation from URL hash, or set hash for the default selection
2635
+ var initMatch = findOpByHash(window.location.hash);
2636
+ if (initMatch) {
2637
+ selected = initMatch;
2638
+ } else if (selected) {
2639
+ history.replaceState(null, "", getOpHash(selected));
2640
+ }
2641
+
2642
+ window.addEventListener("popstate", function() {
2643
+ var match = findOpByHash(window.location.hash);
2644
+ if (match) {
2645
+ selected = match;
2646
+ renderSidebar();
2647
+ renderEndpoint();
2648
+ }
2649
+ });
2650
+
1429
2651
  setMobileSidebarOpen(false);
2652
+ renderAuthPanel();
1430
2653
  renderSidebar();
1431
2654
  renderEndpoint();
1432
2655
  </script>
1433
2656
  </body>
1434
- </html>`}function z(e){let t=e?.["~standard"],d=t?.jsonSchema;return!!t&&typeof t==="object"&&t.version===1&&!!d&&typeof d.input==="function"&&typeof d.output==="function"}function fe(e){let t=0,d=[];return{openapiPath:e.split("/").map((r)=>{let o=/^:([A-Za-z0-9_]+)\+$/.exec(r);if(o?.[1])return d.push(o[1]),`{${o[1]}}`;let i=/^:([A-Za-z0-9_]+)$/.exec(r);if(i?.[1])return d.push(i[1]),`{${i[1]}}`;if(r==="*"){t+=1;let a=t===1?"wildcard":`wildcard${t}`;return d.push(a),`{${a}}`}return r}).join("/"),pathParamNames:d}}function Re(e){return fe(e).openapiPath}function Ue(e,t){return`${e.toLowerCase()}_${t}`.replace(/[:{}]/g,"").replace(/[^A-Za-z0-9_]+/g,"_").replace(/^_+|_+$/g,"")||`${e.toLowerCase()}_operation`}function $e(e){let t=e.split("/").filter(Boolean);for(let d of t)if(!d.startsWith(":")&&d!=="*")return d.toLowerCase();return"default"}function Pe(e){return fe(e).pathParamNames}function _e(e,t){let d=new Set((e.parameters||[]).filter((n)=>n.in==="path").map((n)=>String(n.name)));for(let n of Pe(t)){if(d.has(n))continue;(e.parameters||=[]).push({name:n,in:"path",required:!0,schema:{type:"string"}})}}function Je(e){let t=Number(e);if(!Number.isInteger(t))return!1;return t>=100&&t<200||t===204||t===205||t===304}function Se(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 Fe(e,t,d,n){if(!z(t)){let r=O(t);return S(r)?null:r}try{return t["~standard"].jsonSchema.input({target:d})}catch(r){let o=he(t,"input",d,r,e,void 0,n);if(o)return o;n.push(`[OpenAPI] Failed input schema conversion for ${e}: ${r instanceof Error?r.message:String(r)}. Falling back to a permissive JSON Schema.`);let i=O(t);return S(i)?null:i}}function pe(e,t,d,n,r){if(!z(d)){let o=O(d);return S(o)?null:o}try{return d["~standard"].jsonSchema.output({target:n})}catch(o){let i=he(d,"output",n,o,e,t,r);if(i)return i;return r.push(`[OpenAPI] Failed output schema conversion for ${e} (${t}): ${o instanceof Error?o.message:String(o)}. Falling back to a permissive JSON Schema.`),O(d)}}function y(e){return!!e&&typeof e==="object"&&!Array.isArray(e)}function S(e){return y(e)&&Object.keys(e).length===0}function he(e,t,d,n,r,o,i){if(!z(e))return null;let a=n instanceof Error?n.message:String(n);if(!(d==="openapi-3.0"&&a.includes("target 'openapi-3.0' is not supported")&&a.includes("draft-2020-12")&&a.includes("draft-07")))return null;try{let c=e["~standard"].jsonSchema[t]({target:"draft-07"});return i.push(t==="input"?`[OpenAPI] ${r} converter does not support openapi-3.0 target; using draft-07 conversion output.`:`[OpenAPI] ${r} (${o}) converter does not support openapi-3.0 target; using draft-07 conversion output.`),c}catch{return null}}function G(e){if(!e||typeof e!=="object")return null;let t=e;if(y(t._def))return t._def;if(y(t._zod)&&y(t._zod.def))return t._zod.def;if(t.kind==="schema"&&typeof t.type==="string")return t;return null}function ye(e){if(!e)return null;let t=e.typeName;if(typeof t==="string")return t;let d=e.type;if(typeof d==="string")return d;return null}function F(e){let t=["innerType","schema","type","out","in","left","right","wrapped","element"];for(let d of t)if(d in e)return e[d];return}function ze(e,t){for(let d of t){let n=e[d];if(n&&typeof n==="object"&&!Array.isArray(n))return n}return}function Ge(e){if(!e)return!1;let t=e.toLowerCase();return t.includes("optional")||t.includes("default")||t.includes("catch")}function Ve(e){let t=e,d=!1,n=0;while(n<8){n+=1;let r=G(t),o=ye(r);if(!r||!Ge(o))break;d=!0;let i=F(r);if(!i)break;t=i}return{schema:t,optional:d}}function Qe(e){let t=e.entries;if(y(t))return t;let d=e.shape;if(typeof d==="function")try{let n=d();return y(n)?n:{}}catch{return{}}return y(d)?d:{}}function ue(e){let t=e.values;if(Array.isArray(t))return t;if(t&&typeof t==="object")return Object.values(t);let d=e.entries;if(d&&typeof d==="object")return Object.values(d);let n=e.enum;if(n&&typeof n==="object")return Object.values(n);let r=e.options;if(Array.isArray(r))return r.map((o)=>{if(o&&typeof o==="object"&&"unit"in o)return o.unit;return o}).filter((o)=>o!==void 0);return[]}function Ye(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==="null"||t.includes("zodnull"))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 g(e,t=new WeakSet){if(!e||typeof e!=="object")return{};if(t.has(e))return{};t.add(e);let d=G(e),n=ye(d);if(!d||!n)return{};let r=Ye(n);if(r)return r;let o=n.toLowerCase();if(o.includes("object")){let a=Qe(d),s={},c=[];for(let[b,p]of Object.entries(a)){let x=Ve(p);if(s[b]=g(x.schema,t),!x.optional)c.push(b)}let m={type:"object",properties:s,additionalProperties:!0};if(c.length>0)m.required=c;return m}if(o.includes("array")){let a=ze(d,["element","items","innerType","type"])??{};return{type:"array",items:g(a,t)}}if(o.includes("record")){let a=d.valueType??d.valueSchema;return{type:"object",additionalProperties:a?g(a,t):!0}}if(o.includes("tuple")){let s=(Array.isArray(d.items)?d.items:[]).map((c)=>g(c,t));return{type:"array",prefixItems:s,minItems:s.length,maxItems:s.length}}if(o.includes("union")){let a=d.options??d.schemas??[];if(!Array.isArray(a)||a.length===0)return{};return{anyOf:a.map((s)=>g(s,t))}}if(o.includes("intersection")){let{left:a,right:s}=d;if(!a||!s)return{};return{allOf:[g(a,t),g(s,t)]}}if(o.includes("enum")){let a=ue(d);if(a.length>0){let s=a.every((b)=>typeof b==="string"),c=a.every((b)=>typeof b==="number"),m=a.every((b)=>typeof b==="boolean");if(s)return{type:"string",enum:a};if(c)return{type:"number",enum:a};if(m)return{type:"boolean",enum:a};return{enum:a}}return{}}if(o.includes("picklist")){let a=ue(d);if(a.length>0){if(a.every((c)=>typeof c==="string"))return{type:"string",enum:a};return{enum:a}}return{}}if(o.includes("literal")){let a=d.value;if(a===void 0)return{};let s=a===null?"null":typeof a;if(s==="string"||s==="number"||s==="boolean"||s==="null")return{type:s,const:a};return{const:a}}if(o.includes("nullable")){let a=F(d);if(!a)return{};return{anyOf:[g(a,t),{type:"null"}]}}if(o.includes("lazy")){let a=d.getter;if(typeof a!=="function")return{};try{return g(a(),t)}catch{return{}}}let i=F(d);if(i)return g(i,t);return{}}function O(e){if(!G(e))return{};return g(e)}function Xe(e,t){if(!y(t))return;if(t.type!=="object"||!y(t.properties)){e.requestBody={required:!0,content:{"application/json":{schema:t}}};return}let d=new Set(Array.isArray(t.required)?t.required:[]),n=t.properties,r=Array.isArray(e.parameters)?e.parameters:[],o=[{key:"params",in:"path"},{key:"query",in:"query"},{key:"headers",in:"header"},{key:"cookies",in:"cookie"}];for(let a of o){let s=n[a.key];if(!y(s))continue;if(s.type!=="object"||!y(s.properties))continue;let c=new Set(Array.isArray(s.required)?s.required:[]);for(let[m,b]of Object.entries(s.properties))r.push({name:m,in:a.in,required:a.in==="path"?!0:c.has(m),schema:y(b)?b:{}})}if(r.length>0){let a=new Map;for(let s of r)a.set(`${s.in}:${s.name}`,s);e.parameters=[...a.values()]}let i=n.body;if(i)e.requestBody={required:d.has("body"),content:{"application/json":{schema:y(i)?i:{}}}}}function We(e,t,d,n,r){let o=d.output;if(!o){e.responses={200:{description:"OK"}};return}let i={};if(typeof o==="object"&&o!==null&&"~standard"in o){let a=pe(t,"200",o,n,r);if(a)i["200"]={description:"OK",content:{"application/json":{schema:a}}};else i["200"]={description:"OK"}}else for(let[a,s]of Object.entries(o)){let c=String(a),m=pe(t,c,s,n,r),b=Se(c);if(m&&!Je(c))i[c]={description:b,content:{"application/json":{schema:m}}};else i[c]={description:b}}if(Object.keys(i).length===0)i["200"]={description:"OK"};e.responses=i}function xe(e,t){let d=[],n={};for(let i of e){if(i.options.expose===!1)continue;if(!i.method||!i.path)continue;let a=i.method.toLowerCase();if(a==="options")continue;let s=Re(i.path),c={operationId:Ue(a,s),tags:[i.options.schema?.tag||$e(i.path)]},m=Fe(i.path,i.options.schema?.input,t.target,d);if(m)Xe(c,m);_e(c,i.path),We(c,i.path,i.options.schema||{},t.target,d),n[s]||={},n[s][a]=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:n},warnings:d}}var V="/_vector/openapi/tailwindcdn.js",Q="/_vector/openapi/logo_dark.svg",Y="/_vector/openapi/logo_white.svg",Ie="/_vector/openapi/favicon/apple-touch-icon.png",we="/_vector/openapi/favicon/favicon-32x32.png",Le="/_vector/openapi/favicon/favicon-16x16.png",Ze="/_vector/openapi/favicon/favicon.ico",De="/_vector/openapi/favicon/site.webmanifest",qe="/_vector/openapi/favicon/android-chrome-192x192.png",et="/_vector/openapi/favicon/android-chrome-512x512.png",tt=["../openapi/assets/tailwindcdn.js","../src/openapi/assets/tailwindcdn.js","../../src/openapi/assets/tailwindcdn.js"],dt=["../openapi/assets/logo_dark.svg","../src/openapi/assets/logo_dark.svg","../../src/openapi/assets/logo_dark.svg"],nt=["../openapi/assets/logo_white.svg","../src/openapi/assets/logo_white.svg","../../src/openapi/assets/logo_white.svg"],rt=["src/openapi/assets/tailwindcdn.js","openapi/assets/tailwindcdn.js","dist/openapi/assets/tailwindcdn.js"],ot=["src/openapi/assets/logo_dark.svg","openapi/assets/logo_dark.svg","dist/openapi/assets/logo_dark.svg"],at=["src/openapi/assets/logo_white.svg","openapi/assets/logo_white.svg","dist/openapi/assets/logo_white.svg"],B=["../openapi/assets/favicon","../src/openapi/assets/favicon","../../src/openapi/assets/favicon"],I=["src/openapi/assets/favicon","openapi/assets/favicon","dist/openapi/assets/favicon"],it="/* OpenAPI docs runtime asset missing: tailwind disabled */";function h(e,t){return e.map((d)=>`${d}/${t}`)}function k(e,t){for(let n of e)try{let r=new URL(n,import.meta.url);if(ge(r))return Bun.file(r)}catch{}let d=process.cwd();for(let n of t){let r=Ke(d,n);if(ge(r))return Bun.file(r)}return null}var ke=k(tt,rt),Ee=k(dt,ot),ve=k(nt,at),st=k(h(B,"apple-touch-icon.png"),h(I,"apple-touch-icon.png")),lt=k(h(B,"favicon-32x32.png"),h(I,"favicon-32x32.png")),ct=k(h(B,"favicon-16x16.png"),h(I,"favicon-16x16.png")),bt=k(h(B,"favicon.ico"),h(I,"favicon.ico")),mt=k(h(B,"site.webmanifest"),h(I,"site.webmanifest")),pt=k(h(B,"android-chrome-192x192.png"),h(I,"android-chrome-192x192.png")),ut=k(h(B,"android-chrome-512x512.png"),h(I,"android-chrome-512x512.png")),Be=[{path:Ie,file:st,contentType:"image/png",filename:"apple-touch-icon.png"},{path:we,file:lt,contentType:"image/png",filename:"favicon-32x32.png"},{path:Le,file:ct,contentType:"image/png",filename:"favicon-16x16.png"},{path:Ze,file:bt,contentType:"image/x-icon",filename:"favicon.ico"},{path:De,file:mt,contentType:"application/manifest+json; charset=utf-8",filename:"site.webmanifest"},{path:qe,file:pt,contentType:"image/png",filename:"android-chrome-192x192.png"},{path:et,file:ut,contentType:"image/png",filename:"android-chrome-512x512.png"}],X="public, max-age=0, must-revalidate",A="public, max-age=31536000, immutable",W="no-store";function ft(e){return e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function ht(e){let t="^";for(let d of e){if(d==="*"){t+=".*";continue}t+=ft(d)}return t+="$",new RegExp(t)}function yt(e,t){if(!t.includes("*"))return e===t;return ht(t).test(e)}class K{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 d=this.normalizeCorsOptions(t.cors),{preflight:n,corsify:r}=be(d);if(this.corsHandler={preflight:n,corsify:r},typeof d.origin==="string"&&(d.origin!=="*"||!d.credentials)){let i={"access-control-allow-origin":d.origin,"access-control-allow-methods":d.allowMethods,"access-control-allow-headers":d.allowHeaders,"access-control-expose-headers":d.exposeHeaders,"access-control-max-age":String(d.maxAge)};if(d.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 n=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||{},o=r.docs,i=typeof o==="boolean"?{enabled:o,path:"/docs",exposePaths:void 0}:{enabled:o?.enabled===!0,path:o?.path||"/docs",exposePaths:Array.isArray(o?.exposePaths)?o.exposePaths.map((a)=>typeof a==="string"?a.trim():"").filter((a)=>a.length>0):void 0};return{enabled:r.enabled??n,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}shouldLogOpenAPIConversionWarnings(){if(this.config.development===!1)return!1;let d=process.env.LOG_LEVEL;return typeof d==="string"&&d.toLowerCase()==="debug"}getOpenAPIDocument(){if(this.openapiDocCache)return this.openapiDocCache;let e=this.router.getRouteDefinitions().filter((d)=>!this.isDocsReservedPath(d.path)),t=xe(e,{target:this.openapiConfig.target,info:this.openapiConfig.info});if(!this.openapiWarningsLogged&&t.warnings.length>0){if(this.shouldLogOpenAPIConversionWarnings())for(let d of t.warnings)console.warn(d);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 d=t.paths&&typeof t.paths==="object"&&!Array.isArray(t.paths)?t.paths:{},n={};for(let[r,o]of Object.entries(d))if(e.some((i)=>yt(r,i)))n[r]=o;return{...t,paths:n}}getOpenAPIDocsHtmlCacheEntry(){if(this.openapiDocsHtmlCache)return this.openapiDocsHtmlCache;let e=me(this.getOpenAPIDocumentForDocs(),this.openapiConfig.path,V,Q,Y,Ie,we,Le,De),t=Bun.gzipSync(e),d=`"${Bun.hash(e).toString(16)}"`;return this.openapiDocsHtmlCache={html:e,gzip:t,etag:d},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(V),e.add(Q),e.add(Y);for(let r of Be)e.add(r.path)}let t=this.router.getRouteDefinitions().filter((r)=>e.has(r.path)).map((r)=>`${r.method} ${r.path}`),d=Object.entries(this.router.getRouteTable()).filter(([r,o])=>e.has(r)&&o instanceof Response).map(([r])=>`STATIC ${r}`),n=[...t,...d];if(n.length>0)throw new Error(`OpenAPI reserved path conflict: ${n.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:d,gzip:n,etag:r}=this.getOpenAPIDocsHtmlCacheEntry();if(e.headers.get("if-none-match")===r)return new Response(null,{status:304,headers:{etag:r,"cache-control":X,vary:"accept-encoding"}});if(this.requestAcceptsGzip(e))return new Response(n,{status:200,headers:{"content-type":"text/html; charset=utf-8","content-encoding":"gzip",etag:r,"cache-control":X,vary:"accept-encoding"}});return new Response(d,{status:200,headers:{"content-type":"text/html; charset=utf-8",etag:r,"cache-control":X,vary:"accept-encoding"}})}if(this.openapiConfig.docs.enabled&&t===V){if(!ke){if(!this.openapiTailwindMissingLogged)this.openapiTailwindMissingLogged=!0,console.warn('[OpenAPI] Missing docs runtime asset "tailwindcdn.js". Serving inline fallback script instead.');return new Response(it,{status:200,headers:{"content-type":"application/javascript; charset=utf-8","cache-control":A}})}return new Response(ke,{status:200,headers:{"content-type":"application/javascript; charset=utf-8","cache-control":A}})}if(this.openapiConfig.docs.enabled&&t===Q){if(!Ee){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":W}})}return new Response(Ee,{status:200,headers:{"content-type":"image/svg+xml; charset=utf-8","cache-control":A}})}if(this.openapiConfig.docs.enabled&&t===Y){if(!ve){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":W}})}return new Response(ve,{status:200,headers:{"content-type":"image/svg+xml; charset=utf-8","cache-control":A}})}if(this.openapiConfig.docs.enabled){let d=Be.find((n)=>n.path===t);if(d){if(!d.file)return new Response(`OpenAPI docs runtime asset missing: ${d.filename}`,{status:404,headers:{"content-type":"text/plain; charset=utf-8","cache-control":W}});return new Response(d.file,{status:200,headers:{"content-type":d.contentType,"cache-control":A}})}}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[d,n]of this.corsHeadersEntries)e.headers.set(d,n);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 d=async(n)=>{try{if(this.corsHandler&&n.method==="OPTIONS")return this.corsHandler.preflight(n);let r=this.tryHandleOpenAPIRequest(n);if(r)return this.applyCors(r,n);return this.applyCors(j.NOT_FOUND.clone(),n)}catch(r){return console.error("Server error:",r),this.applyCors(new Response("Internal Server Error",{status:500}),n)}};try{if(this.server=Bun.serve({port:e,hostname:t,reusePort:this.config.reusePort!==!1,routes:this.router.getRouteTable(),fetch:d,idleTimeout:this.config.idleTimeout??60,error:(n,r)=>{return console.error("[ERROR] Server error:",n),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(n){if(n.code==="EADDRINUSE"||n.message?.includes("address already in use"))n.message=`Port ${e} is already in use`,n.port=e;else if(n.code==="EACCES"||n.message?.includes("permission denied"))n.message=`Permission denied to bind to port ${e}`,n.port=e;else if(n.message?.includes("EADDRNOTAVAIL"))n.message=`Cannot bind to hostname ${t}`,n.hostname=t;throw n}}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 w{static instance;router;server=null;middlewareManager;authManager;cacheManager;config={};routeScanner=null;routeGenerator=null;_protectedHandler=null;_cacheHandler=null;shutdownPromise=null;constructor(){this.middlewareManager=new C,this.authManager=new R,this.cacheManager=new U,this.router=new N(this.middlewareManager,this.authManager,this.cacheManager)}static getInstance(){if(!w.instance)w.instance=new w;return w.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 K(this.router,this.config),await this.server.start()}async discoverRoutes(){let e=this.config.routesDir||"./routes",t=this.config.routeExcludePatterns;if(this.routeScanner=new M(e,t),!this.routeGenerator)this.routeGenerator=new $;try{let d=await this.routeScanner.scan();if(d.length>0){if(this.config.development)await this.routeGenerator.generate(d);for(let n of d)try{let o=await import(H(n.path)),i=n.name==="default"?o.default:o[n.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(n.options,i),this.logRouteLoaded(n.options)}}catch(r){console.error(`Failed to load route ${n.name} from ${n.path}:`,r)}}}catch(d){if(d.code!=="ENOENT"&&d.code!=="ENOTDIR")console.error("Failed to discover routes:",d)}}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 d=t();if(this.isRouteEntry(d))this.router.addRoute(d)}}}isRouteEntry(e){if(!Array.isArray(e)||e.length<3)return!1;let[t,d,n,r]=e;return typeof t==="string"&&d instanceof RegExp&&Array.isArray(n)&&n.length>0&&n.every((o)=>typeof o==="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(){w.instance=null}}var Z=w.getInstance;function xt(e,t){return{entry:{method:e.method.toUpperCase(),path:e.path},options:e,handler:t}}function gt(e){let t=e??null;try{return JSON.stringify(t)}catch(d){if(d instanceof TypeError&&/\bbigint\b/i.test(d.message))return JSON.stringify(t,(n,r)=>typeof r==="bigint"?r.toString():r);throw d}}function l(e,t,d){let n={error:!0,message:t,statusCode:e,timestamp:new Date().toISOString()};return D(e,n,d)}var v={badRequest:(e="Bad Request",t)=>l(E.BAD_REQUEST,e,t),unauthorized:(e="Unauthorized",t)=>l(E.UNAUTHORIZED,e,t),paymentRequired:(e="Payment Required",t)=>l(402,e,t),forbidden:(e="Forbidden",t)=>l(E.FORBIDDEN,e,t),notFound:(e="Not Found",t)=>l(E.NOT_FOUND,e,t),methodNotAllowed:(e="Method Not Allowed",t)=>l(405,e,t),notAcceptable:(e="Not Acceptable",t)=>l(406,e,t),requestTimeout:(e="Request Timeout",t)=>l(408,e,t),conflict:(e="Conflict",t)=>l(E.CONFLICT,e,t),gone:(e="Gone",t)=>l(410,e,t),lengthRequired:(e="Length Required",t)=>l(411,e,t),preconditionFailed:(e="Precondition Failed",t)=>l(412,e,t),payloadTooLarge:(e="Payload Too Large",t)=>l(413,e,t),uriTooLong:(e="URI Too Long",t)=>l(414,e,t),unsupportedMediaType:(e="Unsupported Media Type",t)=>l(415,e,t),rangeNotSatisfiable:(e="Range Not Satisfiable",t)=>l(416,e,t),expectationFailed:(e="Expectation Failed",t)=>l(417,e,t),imATeapot:(e="I'm a teapot",t)=>l(418,e,t),misdirectedRequest:(e="Misdirected Request",t)=>l(421,e,t),unprocessableEntity:(e="Unprocessable Entity",t)=>l(E.UNPROCESSABLE_ENTITY,e,t),locked:(e="Locked",t)=>l(423,e,t),failedDependency:(e="Failed Dependency",t)=>l(424,e,t),tooEarly:(e="Too Early",t)=>l(425,e,t),upgradeRequired:(e="Upgrade Required",t)=>l(426,e,t),preconditionRequired:(e="Precondition Required",t)=>l(428,e,t),tooManyRequests:(e="Too Many Requests",t)=>l(429,e,t),requestHeaderFieldsTooLarge:(e="Request Header Fields Too Large",t)=>l(431,e,t),unavailableForLegalReasons:(e="Unavailable For Legal Reasons",t)=>l(451,e,t),internalServerError:(e="Internal Server Error",t)=>l(E.INTERNAL_SERVER_ERROR,e,t),notImplemented:(e="Not Implemented",t)=>l(501,e,t),badGateway:(e="Bad Gateway",t)=>l(502,e,t),serviceUnavailable:(e="Service Unavailable",t)=>l(503,e,t),gatewayTimeout:(e="Gateway Timeout",t)=>l(504,e,t),httpVersionNotSupported:(e="HTTP Version Not Supported",t)=>l(505,e,t),variantAlsoNegotiates:(e="Variant Also Negotiates",t)=>l(506,e,t),insufficientStorage:(e="Insufficient Storage",t)=>l(507,e,t),loopDetected:(e="Loop Detected",t)=>l(508,e,t),notExtended:(e="Not Extended",t)=>l(510,e,t),networkAuthenticationRequired:(e="Network Authentication Required",t)=>l(511,e,t),invalidArgument:(e="Invalid Argument",t)=>l(E.UNPROCESSABLE_ENTITY,e,t),rateLimitExceeded:(e="Rate Limit Exceeded",t)=>l(429,e,t),maintenance:(e="Service Under Maintenance",t)=>l(503,e,t),custom:(e,t,d)=>l(e,t,d)};function D(e,t,d=T.JSON){let n=d===T.JSON?gt(t):t;return new Response(n,{status:e,headers:{"content-type":d}})}import{existsSync as kt}from"fs";import{resolve as Et,isAbsolute as vt}from"path";class q{configPath;config=null;configSource="default";constructor(e){let t=e||"vector.config.ts";this.configPath=vt(t)?t:Et(process.cwd(),t)}async load(){if(kt(this.configPath))try{let t=await import(H(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 Bt(e={}){let t=new q(e.configPath),d=await t.load(),n=t.getConfigSource(),r={...d};if(e.mutateConfig)r=await e.mutateConfig(r,{configSource:n});if(e.config)r={...r,...e.config};if(e.autoDiscover!==void 0)r.autoDiscover=e.autoDiscover;let o=Z(),i=e.protectedHandler!==void 0?e.protectedHandler:await t.loadAuthHandler(),a=e.cacheHandler!==void 0?e.cacheHandler:await t.loadCacheHandler();o.setProtectedHandler(i??null),o.setCacheHandler(a??null);let s=await o.startServer(r),c={...r,port:s.port??r.port??L.PORT,hostname:s.hostname||r.hostname||L.HOSTNAME,reusePort:r.reusePort!==!1,idleTimeout:r.idleTimeout??60};return{server:s,config:c,stop:()=>o.stop(),shutdown:()=>o.shutdown()}}export{Bt as startVector,xt as route,D as createResponse,v as APIError};
2657
+ </html>`}var fr=new Set(Object.values(J)),gr={ApiKey:"apiKeyAuth",HttpBasic:"basicAuth",HttpBearer:"bearerAuth",HttpDigest:"digestAuth",OAuth2:"oauth2Auth",OpenIdConnect:"openIdConnectAuth",MutualTls:"mutualTlsAuth"};function yr(e){return typeof e==="string"&&fr.has(e)}function wr(e,t){if(e===void 0||e===!1||e===null)return null;if(e===!0)return t;if(yr(e))return e;return t}function qe(e,t){let r=t?.securitySchemeNames?.[e];if(typeof r==="string"&&r.trim().length>0)return r.trim();return gr[e]}function xr(e){switch(e){case"ApiKey":return{type:"apiKey",name:"X-API-Key",in:"header"};case"HttpBasic":return{type:"http",scheme:"basic"};case"HttpBearer":return{type:"http",scheme:"bearer",bearerFormat:"JWT"};case"HttpDigest":return{type:"http",scheme:"digest"};case"OAuth2":return{type:"oauth2",flows:{authorizationCode:{authorizationUrl:"https://example.com/oauth/authorize",tokenUrl:"https://example.com/oauth/token",scopes:{}}}};case"OpenIdConnect":return{type:"openIdConnect",openIdConnectUrl:"https://example.com/.well-known/openid-configuration"};case"MutualTls":return{type:"mutualTLS"};default:return e}}function vr(e,t){let r=xr(e),a=t?.securitySchemes?.[e];if(!a)return r;let n={...r,...a};if(y(r.flows)&&y(a.flows))n.flows={...r.flows,...a.flows};return n}function se(e){let t=e?.["~standard"],r=t?.jsonSchema;return!!t&&typeof t==="object"&&t.version===1&&!!r&&typeof r.input==="function"&&typeof r.output==="function"}function tt(e){let t=0,r=[];return{openapiPath:e.split("/").map((n)=>{let o=/^:([A-Za-z0-9_]+)\+$/.exec(n);if(o?.[1])return r.push(o[1]),`{${o[1]}}`;let i=/^:([A-Za-z0-9_]+)$/.exec(n);if(i?.[1])return r.push(i[1]),`{${i[1]}}`;if(n==="*"){t+=1;let d=t===1?"wildcard":`wildcard${t}`;return r.push(d),`{${d}}`}return n}).join("/"),pathParamNames:r}}function Er(e){return tt(e).openapiPath}function kr(e,t){return`${e.toLowerCase()}_${t}`.replace(/[:{}]/g,"").replace(/[^A-Za-z0-9_]+/g,"_").replace(/^_+|_+$/g,"")||`${e.toLowerCase()}_operation`}function Br(e){let t=e.split("/").filter(Boolean);for(let r of t)if(!r.startsWith(":")&&r!=="*")return r.toLowerCase();return"default"}function Ir(e){return tt(e).pathParamNames}function Tr(e,t){let r=new Set((e.parameters||[]).filter((a)=>a.in==="path").map((a)=>String(a.name)));for(let a of Ir(t)){if(r.has(a))continue;(e.parameters||=[]).push({name:a,in:"path",required:!0,schema:{type:"string"}})}}function Cr(e){let t=Number(e);if(!Number.isInteger(t))return!1;return t>=100&&t<200||t===204||t===205||t===304}function Lr(e){let t={"100":"Continue","101":"Switching Protocols","102":"Processing","103":"Early Hints","200":"OK","201":"Created","202":"Accepted","203":"Non-Authoritative Information","204":"No Content","205":"Reset Content","206":"Partial Content","207":"Multi-Status","208":"Already Reported","226":"IM Used","300":"Multiple Choices","301":"Moved Permanently","302":"Found","303":"See Other","304":"Not Modified","305":"Use Proxy","307":"Temporary Redirect","308":"Permanent Redirect","400":"Bad Request","401":"Unauthorized","402":"Payment Required","403":"Forbidden","404":"Not Found","405":"Method Not Allowed","406":"Not Acceptable","407":"Proxy Authentication Required","408":"Request Timeout","409":"Conflict","410":"Gone","411":"Length Required","412":"Precondition Failed","413":"Payload Too Large","414":"URI Too Long","415":"Unsupported Media Type","416":"Range Not Satisfiable","417":"Expectation Failed","418":"I'm a teapot","421":"Misdirected Request","422":"Unprocessable Content","423":"Locked","424":"Failed Dependency","425":"Too Early","426":"Upgrade Required","428":"Precondition Required","429":"Too Many Requests","431":"Request Header Fields Too Large","451":"Unavailable For Legal Reasons","500":"Internal Server Error","501":"Not Implemented","502":"Bad Gateway","503":"Service Unavailable","504":"Gateway Timeout","505":"HTTP Version Not Supported","506":"Variant Also Negotiates","507":"Insufficient Storage","508":"Loop Detected","510":"Not Extended","511":"Network Authentication Required"};if(t[e])return t[e];let r=Number(e);if(Number.isInteger(r)&&r>=100&&r<200)return"Informational Response";if(Number.isInteger(r)&&r>=200&&r<300)return"Successful Response";if(Number.isInteger(r)&&r>=300&&r<400)return"Redirection";if(Number.isInteger(r)&&r>=400&&r<500)return"Client Error";if(Number.isInteger(r)&&r>=500&&r<600)return"Server Error";return"OK"}function Nr(e,t,r,a){if(!se(t)){let n=Z(t);return ie(n)?null:n}try{return t["~standard"].jsonSchema.input({target:r})}catch(n){let o=rt(t,"input",r,n,e,void 0,a);if(o)return o;a.push(`[OpenAPI] Failed input schema conversion for ${e}: ${n instanceof Error?n.message:String(n)}. Falling back to a permissive JSON Schema.`);let i=Z(t);return ie(i)?null:i}}function Ke(e,t,r,a,n){if(!se(r)){let o=Z(r);return ie(o)?null:o}try{return r["~standard"].jsonSchema.output({target:a})}catch(o){let i=rt(r,"output",a,o,e,t,n);if(i)return i;return n.push(`[OpenAPI] Failed output schema conversion for ${e} (${t}): ${o instanceof Error?o.message:String(o)}. Falling back to a permissive JSON Schema.`),Z(r)}}function y(e){return!!e&&typeof e==="object"&&!Array.isArray(e)}function ie(e){return y(e)&&Object.keys(e).length===0}function rt(e,t,r,a,n,o,i){if(!se(e))return null;let d=a instanceof Error?a.message:String(a);if(!(r==="openapi-3.0"&&d.includes("target 'openapi-3.0' is not supported")&&d.includes("draft-2020-12")&&d.includes("draft-07")))return null;try{let c=e["~standard"].jsonSchema[t]({target:"draft-07"});return i.push(t==="input"?`[OpenAPI] ${n} converter does not support openapi-3.0 target; using draft-07 conversion output.`:`[OpenAPI] ${n} (${o}) converter does not support openapi-3.0 target; using draft-07 conversion output.`),c}catch{return null}}function ce(e){if(!e||typeof e!=="object")return null;let t=e;if(y(t._def))return t._def;if(y(t._zod)&&y(t._zod.def))return t._zod.def;if(t.kind==="schema"&&typeof t.type==="string")return t;return null}function at(e){if(!e)return null;let t=e.typeName;if(typeof t==="string")return t;let r=e.type;if(typeof r==="string")return r;return null}function le(e){let t=["innerType","schema","type","out","in","left","right","wrapped","element"];for(let r of t)if(r in e)return e[r];return}function Ar(e,t){for(let r of t){let a=e[r];if(a&&typeof a==="object"&&!Array.isArray(a))return a}return}function Sr(e){if(!e)return!1;let t=e.toLowerCase();return t.includes("optional")||t.includes("default")||t.includes("catch")}function Rr(e){let t=e,r=!1,a=0;while(a<8){a+=1;let n=ce(t),o=at(n);if(!n||!Sr(o))break;r=!0;let i=le(n);if(!i)break;t=i}return{schema:t,optional:r}}function Hr(e){let t=e.entries;if(y(t))return t;let r=e.shape;if(typeof r==="function")try{let a=r();return y(a)?a:{}}catch{return{}}return y(r)?r:{}}function et(e){let t=e.values;if(Array.isArray(t))return t;if(t&&typeof t==="object")return Object.values(t);let r=e.entries;if(r&&typeof r==="object")return Object.values(r);let a=e.enum;if(a&&typeof a==="object")return Object.values(a);let n=e.options;if(Array.isArray(n))return n.map((o)=>{if(o&&typeof o==="object"&&"unit"in o)return o.unit;return o}).filter((o)=>o!==void 0);return[]}function Or(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==="null"||t.includes("zodnull"))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 k(e,t=new WeakSet){if(!e||typeof e!=="object")return{};if(t.has(e))return{};t.add(e);let r=ce(e),a=at(r);if(!r||!a)return{};let n=Or(a);if(n)return n;let o=a.toLowerCase();if(o.includes("object")){let d=Hr(r),l={},c=[];for(let[s,p]of Object.entries(d)){let h=Rr(p);if(l[s]=k(h.schema,t),!h.optional)c.push(s)}let m={type:"object",properties:l,additionalProperties:!0};if(c.length>0)m.required=c;return m}if(o.includes("array")){let d=Ar(r,["element","items","innerType","type"])??{};return{type:"array",items:k(d,t)}}if(o.includes("record")){let d=r.valueType??r.valueSchema;return{type:"object",additionalProperties:d?k(d,t):!0}}if(o.includes("tuple")){let l=(Array.isArray(r.items)?r.items:[]).map((c)=>k(c,t));return{type:"array",prefixItems:l,minItems:l.length,maxItems:l.length}}if(o.includes("union")){let d=r.options??r.schemas??[];if(!Array.isArray(d)||d.length===0)return{};return{anyOf:d.map((l)=>k(l,t))}}if(o.includes("intersection")){let{left:d,right:l}=r;if(!d||!l)return{};return{allOf:[k(d,t),k(l,t)]}}if(o.includes("enum")){let d=et(r);if(d.length>0){let l=d.every((s)=>typeof s==="string"),c=d.every((s)=>typeof s==="number"),m=d.every((s)=>typeof s==="boolean");if(l)return{type:"string",enum:d};if(c)return{type:"number",enum:d};if(m)return{type:"boolean",enum:d};return{enum:d}}return{}}if(o.includes("picklist")){let d=et(r);if(d.length>0){if(d.every((c)=>typeof c==="string"))return{type:"string",enum:d};return{enum:d}}return{}}if(o.includes("literal")){let d=r.value;if(d===void 0)return{};let l=d===null?"null":typeof d;if(l==="string"||l==="number"||l==="boolean"||l==="null")return{type:l,const:d};return{const:d}}if(o.includes("nullable")){let d=le(r);if(!d)return{};return{anyOf:[k(d,t),{type:"null"}]}}if(o.includes("lazy")){let d=r.getter;if(typeof d!=="function")return{};try{return k(d(),t)}catch{return{}}}let i=le(r);if(i)return k(i,t);return{}}function Z(e){if(!ce(e))return{};return k(e)}function Dr(e,t){if(!y(t))return;if(t.type!=="object"||!y(t.properties)){e.requestBody={required:!0,content:{"application/json":{schema:t}}};return}let r=new Set(Array.isArray(t.required)?t.required:[]),a=t.properties,n=Array.isArray(e.parameters)?e.parameters:[],o=[{key:"params",in:"path"},{key:"query",in:"query"},{key:"headers",in:"header"},{key:"cookies",in:"cookie"}];for(let d of o){let l=a[d.key];if(!y(l))continue;if(l.type!=="object"||!y(l.properties))continue;let c=new Set(Array.isArray(l.required)?l.required:[]);for(let[m,s]of Object.entries(l.properties))n.push({name:m,in:d.in,required:d.in==="path"?!0:c.has(m),schema:y(s)?s:{}})}if(n.length>0){let d=new Map;for(let l of n)d.set(`${l.in}:${l.name}`,l);e.parameters=[...d.values()]}let i=a.body;if(i)e.requestBody={required:r.has("body"),content:{"application/json":{schema:y(i)?i:{}}}}}function jr(e,t,r,a,n){let o=r.output;if(!o){e.responses={200:{description:"OK"}};return}let i={};if(typeof o==="object"&&o!==null&&"~standard"in o){let d=Ke(t,"200",o,a,n);if(d)i["200"]={description:"OK",content:{"application/json":{schema:d}}};else i["200"]={description:"OK"}}else for(let[d,l]of Object.entries(o)){let c=String(d),m=Ke(t,c,l,a,n),s=Lr(c);if(m&&!Cr(c))i[c]={description:s,content:{"application/json":{schema:m}}};else i[c]={description:s}}if(Object.keys(i).length===0)i["200"]={description:"OK"};e.responses=i}function nt(e,t){let r=[],a={},n="HttpBearer",o=new Set;for(let l of e){if(l.options.expose===!1)continue;if(!l.method||!l.path)continue;let c=l.method.toLowerCase();if(c==="options")continue;let m=Er(l.path),s={operationId:kr(c,m),tags:[l.options.schema?.tag||Br(l.path)]};if(typeof l.options.schema?.summary==="string"&&l.options.schema.summary.trim())s.summary=l.options.schema.summary.trim();let p=typeof l.options.schema?.description==="string"&&l.options.schema.description.trim()?l.options.schema.description.trim():typeof l.options.schema?.descrition==="string"&&l.options.schema.descrition.trim()?l.options.schema.descrition.trim():void 0;if(p)s.description=p;if(l.options.deprecated===!0)s.deprecated=!0;let h=wr(l.options.auth,n);if(h){o.add(h);let f=qe(h,t.auth);s.security=[{[f]:[]}]}let u=Nr(l.path,l.options.schema?.input,t.target,r);if(u){if(!s.summary&&typeof u.title==="string"&&u.title.trim())s.summary=u.title.trim();if(!s.description&&typeof u.description==="string"&&u.description.trim())s.description=u.description.trim();Dr(s,u)}if(Tr(s,l.path),jr(s,l.path,l.options.schema||{},t.target,r),!s.summary||!s.description){let f=Object.values(s.responses||{});for(let L of f){let x=L?.content?.["application/json"]?.schema;if(!x||typeof x!=="object")continue;if(!s.summary&&typeof x.title==="string"&&x.title.trim())s.summary=x.title.trim();if(!s.description&&typeof x.description==="string"&&x.description.trim())s.description=x.description.trim();if(s.summary&&s.description)break}}a[m]||={},a[m][c]=s}let d={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:a};if(o.size>0){let l={};for(let c of o){let m=qe(c,t.auth);l[m]=vr(c,t.auth)}d.components={securitySchemes:l}}return{document:d,warnings:r}}var pe="/_vector/openapi/tailwindcdn.js",me="/_vector/openapi/logo_dark.svg",be="/_vector/openapi/logo_white.svg",pt="/_vector/openapi/favicon/apple-touch-icon.png",mt="/_vector/openapi/favicon/favicon-32x32.png",bt="/_vector/openapi/favicon/favicon-16x16.png",_r="/_vector/openapi/favicon/favicon.ico",ut="/_vector/openapi/favicon/site.webmanifest",Ur="/_vector/openapi/favicon/android-chrome-192x192.png",Mr="/_vector/openapi/favicon/android-chrome-512x512.png",Pr=["../openapi/assets/tailwindcdn.js","../src/openapi/assets/tailwindcdn.js","../../src/openapi/assets/tailwindcdn.js"],zr=["../openapi/assets/logo_dark.svg","../src/openapi/assets/logo_dark.svg","../../src/openapi/assets/logo_dark.svg"],Jr=["../openapi/assets/logo_white.svg","../src/openapi/assets/logo_white.svg","../../src/openapi/assets/logo_white.svg"],Fr=["src/openapi/assets/tailwindcdn.js","openapi/assets/tailwindcdn.js","dist/openapi/assets/tailwindcdn.js"],Gr=["src/openapi/assets/logo_dark.svg","openapi/assets/logo_dark.svg","dist/openapi/assets/logo_dark.svg"],Yr=["src/openapi/assets/logo_white.svg","openapi/assets/logo_white.svg","dist/openapi/assets/logo_white.svg"],R=["../openapi/assets/favicon","../src/openapi/assets/favicon","../../src/openapi/assets/favicon"],H=["src/openapi/assets/favicon","openapi/assets/favicon","dist/openapi/assets/favicon"],Qr="/* OpenAPI docs runtime asset missing: tailwind disabled */";function w(e,t){return e.map((r)=>`${r}/${t}`)}function I(e,t){for(let a of e)try{let n=new URL(a,import.meta.url);if(ot(n))return Bun.file(n)}catch{}let r=process.cwd();for(let a of t){let n=$r(r,a);if(ot(n))return Bun.file(n)}return null}var dt=I(Pr,Fr),it=I(zr,Gr),lt=I(Jr,Yr),Vr=I(w(R,"apple-touch-icon.png"),w(H,"apple-touch-icon.png")),Wr=I(w(R,"favicon-32x32.png"),w(H,"favicon-32x32.png")),Xr=I(w(R,"favicon-16x16.png"),w(H,"favicon-16x16.png")),Zr=I(w(R,"favicon.ico"),w(H,"favicon.ico")),qr=I(w(R,"site.webmanifest"),w(H,"site.webmanifest")),Kr=I(w(R,"android-chrome-192x192.png"),w(H,"android-chrome-192x192.png")),ea=I(w(R,"android-chrome-512x512.png"),w(H,"android-chrome-512x512.png")),st=[{path:pt,file:Vr,contentType:"image/png",filename:"apple-touch-icon.png"},{path:mt,file:Wr,contentType:"image/png",filename:"favicon-32x32.png"},{path:bt,file:Xr,contentType:"image/png",filename:"favicon-16x16.png"},{path:_r,file:Zr,contentType:"image/x-icon",filename:"favicon.ico"},{path:ut,file:qr,contentType:"application/manifest+json; charset=utf-8",filename:"site.webmanifest"},{path:Ur,file:Kr,contentType:"image/png",filename:"android-chrome-192x192.png"},{path:Mr,file:ea,contentType:"image/png",filename:"android-chrome-512x512.png"}],ue="public, max-age=0, must-revalidate",G="public, max-age=31536000, immutable",he="no-store",ta=3000;function ct(e){if(e===void 0)return ta;let t=Number(e);if(!Number.isInteger(t)||t<0||t>65535)throw new Error(`Invalid port: ${String(e)}. Port must be an integer between 0 and 65535.`);return t}function ra(e){return e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function aa(e){let t="^";for(let r of e){if(r==="*"){t+=".*";continue}t+=ra(r)}return t+="$",new RegExp(t)}function na(e,t){if(!t.includes("*"))return e===t;return aa(t).test(e)}class fe{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 r=this.normalizeCorsOptions(t.cors),{preflight:a,corsify:n}=Xe(r);if(this.corsHandler={preflight:a,corsify:n},typeof r.origin==="string"&&(r.origin!=="*"||!r.credentials)){let i={"access-control-allow-origin":r.origin,"access-control-allow-methods":r.allowMethods,"access-control-allow-headers":r.allowHeaders,"access-control-expose-headers":r.exposeHeaders,"access-control-max-age":String(r.maxAge)};if(r.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)}}setCheckpointGateway(e){this.router.setCheckpointGateway(e)}normalizeOpenAPIConfig(e,t){let a=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 n=e||{},o=n.docs,i=typeof o==="boolean"?{enabled:o,path:"/docs",exposePaths:void 0}:{enabled:o?.enabled===!0,path:o?.path||"/docs",exposePaths:Array.isArray(o?.exposePaths)?o.exposePaths.map((d)=>typeof d==="string"?d.trim():"").filter((d)=>d.length>0):void 0};return{enabled:n.enabled??a,path:n.path||"/openapi.json",target:n.target||"openapi-3.0",docs:i,info:n.info,auth:n.auth}}isDocsReservedPath(e){return e===this.openapiConfig.path||this.openapiConfig.docs.enabled&&e===this.openapiConfig.docs.path}shouldLogOpenAPIConversionWarnings(){if(this.config.development===!1)return!1;let r=process.env.LOG_LEVEL;return typeof r==="string"&&r.toLowerCase()==="debug"}getOpenAPIDocument(){if(this.openapiDocCache)return this.openapiDocCache;let e=this.router.getRouteDefinitions().filter((r)=>!this.isDocsReservedPath(r.path)),t=nt(e,{target:this.openapiConfig.target,info:this.openapiConfig.info,auth:this.openapiConfig.auth});if(!this.openapiWarningsLogged&&t.warnings.length>0){if(this.shouldLogOpenAPIConversionWarnings())for(let r of t.warnings)console.warn(r);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 r=t.paths&&typeof t.paths==="object"&&!Array.isArray(t.paths)?t.paths:{},a={};for(let[n,o]of Object.entries(r))if(e.some((i)=>na(n,i)))a[n]=o;return{...t,paths:a}}getOpenAPIDocsHtmlCacheEntry(){if(this.openapiDocsHtmlCache)return this.openapiDocsHtmlCache;let e=Ze(this.getOpenAPIDocumentForDocs(),this.openapiConfig.path,pe,me,be,pt,mt,bt,ut),t=Bun.gzipSync(e),r=`"${Bun.hash(e).toString(16)}"`;return this.openapiDocsHtmlCache={html:e,gzip:t,etag:r},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(pe),e.add(me),e.add(be);for(let n of st)e.add(n.path)}let t=this.router.getRouteDefinitions().filter((n)=>e.has(n.path)).map((n)=>`${n.method} ${n.path}`),r=Object.entries(this.router.getRouteTable()).filter(([n,o])=>e.has(n)&&o instanceof Response).map(([n])=>`STATIC ${n}`),a=[...t,...r];if(a.length>0)throw new Error(`OpenAPI reserved path conflict: ${a.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:r,gzip:a,etag:n}=this.getOpenAPIDocsHtmlCacheEntry();if(e.headers.get("if-none-match")===n)return new Response(null,{status:304,headers:{etag:n,"cache-control":ue,vary:"accept-encoding"}});if(this.requestAcceptsGzip(e))return new Response(a,{status:200,headers:{"content-type":"text/html; charset=utf-8","content-encoding":"gzip",etag:n,"cache-control":ue,vary:"accept-encoding"}});return new Response(r,{status:200,headers:{"content-type":"text/html; charset=utf-8",etag:n,"cache-control":ue,vary:"accept-encoding"}})}if(this.openapiConfig.docs.enabled&&t===pe){if(!dt){if(!this.openapiTailwindMissingLogged)this.openapiTailwindMissingLogged=!0,console.warn('[OpenAPI] Missing docs runtime asset "tailwindcdn.js". Serving inline fallback script instead.');return new Response(Qr,{status:200,headers:{"content-type":"application/javascript; charset=utf-8","cache-control":G}})}return new Response(dt,{status:200,headers:{"content-type":"application/javascript; charset=utf-8","cache-control":G}})}if(this.openapiConfig.docs.enabled&&t===me){if(!it){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":he}})}return new Response(it,{status:200,headers:{"content-type":"image/svg+xml; charset=utf-8","cache-control":G}})}if(this.openapiConfig.docs.enabled&&t===be){if(!lt){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":he}})}return new Response(lt,{status:200,headers:{"content-type":"image/svg+xml; charset=utf-8","cache-control":G}})}if(this.openapiConfig.docs.enabled){let r=st.find((a)=>a.path===t);if(r){if(!r.file)return new Response(`OpenAPI docs runtime asset missing: ${r.filename}`,{status:404,headers:{"content-type":"text/plain; charset=utf-8","cache-control":he}});return new Response(r.file,{status:200,headers:{"content-type":r.contentType,"cache-control":G}})}}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[r,a]of this.corsHeadersEntries)e.headers.set(r,a);return e}if(this.corsHandler&&t)return this.corsHandler.corsify(e,t);return e}async start(){let e=ct(this.config.port),t=this.config.hostname||"localhost";this.validateReservedOpenAPIPaths();let r=async(a)=>{try{if(this.corsHandler&&a.method==="OPTIONS")return this.corsHandler.preflight(a);let n=this.tryHandleOpenAPIRequest(a);if(n)return this.applyCors(n,a);return await this.router.handle(a)}catch(n){return console.error("Server error:",n),this.applyCors(new Response("Internal Server Error",{status:500}),a)}};try{if(this.server=Bun.serve({port:e,hostname:t,reusePort:this.config.reusePort!==!1,fetch:r,idleTimeout:this.config.idleTimeout??60,error:(a,n)=>{return console.error("[ERROR] Server error:",a),this.applyCors(new Response("Internal Server Error",{status:500}),n)}}),!this.server||!this.server.port)throw new Error(`Failed to start server on ${t}:${e} - server object is invalid`);return this.server}catch(a){if(a.code==="EADDRINUSE"||a.message?.includes("address already in use"))a.message=`Port ${e} is already in use`,a.port=e;else if(a.code==="EACCES"||a.message?.includes("permission denied"))a.message=`Permission denied to bind to port ${e}`,a.port=e;else if(a.message?.includes("EADDRNOTAVAIL"))a.message=`Cannot bind to hostname ${t}`,a.hostname=t;throw a}}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??ct(this.config.port)}getHostname(){return this.server?.hostname||this.config.hostname||"localhost"}getUrl(){let e=this.getPort();return`http://${this.getHostname()}:${e}`}}class j{static instance;router;server=null;middlewareManager;authManager;cacheManager;config={};routeScanner=null;routeGenerator=null;_protectedHandler=null;_cacheHandler=null;shutdownPromise=null;checkpointProcessManager=null;constructor(){this.middlewareManager=new W,this.authManager=new te,this.cacheManager=new re,this.router=new F(this.middlewareManager,this.authManager,this.cacheManager)}static getInstance(){if(!j.instance)j.instance=new j;return j.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){if(this.checkpointProcessManager)await this.checkpointProcessManager.stopAll(),this.checkpointProcessManager=null;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();this.server=new fe(this.router,this.config);let r=await this.server.start();if(this.config.checkpoint&&this.config.checkpoint.enabled!==!1)await this.enableCheckpointGateway(this.config.checkpoint);return r}async discoverRoutes(){let e=this.config.routesDir||"./routes",t=this.config.routeExcludePatterns;if(this.routeScanner=new V(e,t),!this.routeGenerator)this.routeGenerator=new ae;try{let r=await this.routeScanner.scan();if(r.length>0){if(this.config.development)await this.routeGenerator.generate(r);for(let a of r)try{let o=await import(`${X(a.path)}?t=${Date.now()}`),i=a.name==="default"?o.default:o[a.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(a.options,i),this.logRouteLoaded(a.options)}}catch(n){console.error(`Failed to load route ${a.name} from ${a.path}:`,n)}}}catch(r){if(r.code!=="ENOENT"&&r.code!=="ENOTDIR")console.error("Failed to discover routes:",r)}}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 r=t();if(this.isRouteEntry(r))this.router.addRoute(r)}}}isRouteEntry(e){if(!Array.isArray(e)||e.length<3)return!1;let[t,r,a,n]=e;return typeof t==="string"&&r instanceof RegExp&&Array.isArray(a)&&a.length>0&&a.every((o)=>typeof o==="function")&&(n===void 0||typeof n==="string")}isRouteDefinition(e){return e!==null&&typeof e==="object"&&"entry"in e&&"options"in e&&"handler"in e&&typeof e.handler==="function"}logRouteLoaded(e){}async enableCheckpointGateway(e){if(!this.server)throw new Error("Cannot enable checkpoint gateway before server is started. Call startServer() first.");let{CheckpointManager:t}=await Promise.resolve().then(() => (zt(),Pt)),{CheckpointProcessManager:r}=await Promise.resolve().then(() => (Kt(),qt)),{CheckpointResolver:a}=await Promise.resolve().then(() => tr),{CheckpointForwarder:n}=await Promise.resolve().then(() => ar),{CheckpointGateway:o}=await Promise.resolve().then(() => or);if(this.checkpointProcessManager)await this.checkpointProcessManager.stopAll(),this.checkpointProcessManager=null;let i=new t(e),d=new r({idleTimeoutMs:e?.idleTimeoutMs});this.checkpointProcessManager=d;let l=new a(i,d,{versionHeader:e?.versionHeader,cacheKeyOverride:e?.cacheKeyOverride}),c=new n,m=new o(l,c);this.server.setCheckpointGateway(m);let s=await i.getActive();if(s)try{let p=await i.readManifest(s.version);await d.spawn(p,i.getStorageDir())}catch(p){console.error(`[Checkpoint] Failed to start active checkpoint ${s.version}:`,p)}}stop(){if(this.server)this.server.stop(),this.server=null}async shutdown(){if(this.shutdownPromise)return this.shutdownPromise;this.shutdownPromise=(async()=>{if(this.stop(),this.checkpointProcessManager)await this.checkpointProcessManager.stopAll(),this.checkpointProcessManager=null;if(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(){j.instance=null}}var He=j.getInstance;function dr(e,t){return{entry:{method:e.method.toUpperCase(),path:e.path},options:e,handler:t}}function Xa(e,t){return dr({...e,deprecated:!0},t)}function Za(e){let t=e??null;try{return JSON.stringify(t)}catch(r){if(r instanceof TypeError&&/\bbigint\b/i.test(r.message))return JSON.stringify(t,(a,n)=>typeof n==="bigint"?n.toString():n);throw r}}function qa(e){return(e.split(";",1)[0]??e).trim().toLowerCase()===z.JSON}function Ka(e){let t=[`${e.name}=${e.value}`];if(e.maxAge!==void 0&&Number.isFinite(e.maxAge))t.push(`Max-Age=${Math.trunc(e.maxAge)}`);if(e.domain)t.push(`Domain=${e.domain}`);if(e.path)t.push(`Path=${e.path}`);if(e.expires!==void 0){let r=e.expires instanceof Date?e.expires:new Date(e.expires);if(!Number.isNaN(r.getTime()))t.push(`Expires=${r.toUTCString()}`)}if(e.httpOnly)t.push("HttpOnly");if(e.secure)t.push("Secure");if(e.sameSite)t.push(`SameSite=${e.sameSite}`);if(e.partitioned)t.push("Partitioned");if(e.priority)t.push(`Priority=${e.priority}`);return t.join("; ")}function en(e,t){if(!t||t.length===0)return;for(let r of t)e.append("set-cookie",typeof r==="string"?r:Ka(r))}function b(e,t,r){let a={error:!0,message:t,statusCode:e,timestamp:new Date().toISOString()};return _(e,a,r)}var S={badRequest:(e="Bad Request",t)=>b(A.BAD_REQUEST,e,t),unauthorized:(e="Unauthorized",t)=>b(A.UNAUTHORIZED,e,t),paymentRequired:(e="Payment Required",t)=>b(402,e,t),forbidden:(e="Forbidden",t)=>b(A.FORBIDDEN,e,t),notFound:(e="Not Found",t)=>b(A.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(A.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(A.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(A.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(A.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,r)=>b(e,t,r)};function _(e,t,r=z.JSON){let a=typeof r==="string"?{contentType:r}:r??{},n=new Headers(a.headers),o=a.contentType??n.get("content-type")??z.JSON;if(a.contentType||!n.has("content-type"))n.set("content-type",o);en(n,a.cookies);let i=qa(o)?Za(t):t;return new Response(i,{status:e,statusText:a.statusText,headers:n})}import{existsSync as tn}from"fs";import{resolve as rn,isAbsolute as an}from"path";class Oe{configPath;config=null;configSource="default";constructor(e){let t=e||"vector.config.ts";this.configPath=an(t)?t:rn(process.cwd(),t)}async load(){if(tn(this.configPath))try{let t=await import(`${X(this.configPath)}?t=${Date.now()}`);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.normalizePort(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,e.checkpoint=this.config.checkpoint;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}normalizePort(e){if(e===void 0)return;return Number(e)}async loadAuthHandler(){return this.config?.auth||null}async loadCacheHandler(){return this.config?.cache||null}getConfig(){return this.config}}async function nn(e={}){let t=new Oe(e.configPath),r=await t.load(),a=t.getConfigSource(),n={...r};if(e.mutateConfig)n=await e.mutateConfig(n,{configSource:a});if(e.config)n={...n,...e.config};if(e.autoDiscover!==void 0)n.autoDiscover=e.autoDiscover;let o=He(),i=e.protectedHandler!==void 0?e.protectedHandler:await t.loadAuthHandler(),d=e.cacheHandler!==void 0?e.cacheHandler:await t.loadCacheHandler();o.setProtectedHandler(i??null),o.setCacheHandler(d??null);let l=await o.startServer(n),c={...n,port:l.port??n.port??$.PORT,hostname:l.hostname||n.hostname||$.HOSTNAME,reusePort:n.reusePort!==!1,idleTimeout:n.idleTimeout??60};return{server:l,config:c,stop:()=>o.stop(),shutdown:()=>o.shutdown()}}export{nn as startVector,dr as route,Xa as depRoute,_ as createResponse,ze as OpenApiSecuritySchemeType,Je as HttpAuthScheme,J as AuthKind,S as APIError};