vector-framework 1.2.1 → 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 (190) 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 +3817 -350
  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 +3 -0
  113. package/dist/core/server.d.ts.map +1 -1
  114. package/dist/core/server.js +35 -10
  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/errors/index.cjs +2 -0
  124. package/dist/http.d.ts +32 -7
  125. package/dist/http.d.ts.map +1 -1
  126. package/dist/http.js +144 -13
  127. package/dist/http.js.map +1 -1
  128. package/dist/index.cjs +2657 -0
  129. package/dist/index.d.ts +3 -2
  130. package/dist/index.d.ts.map +1 -1
  131. package/dist/index.js +12 -1433
  132. package/dist/index.js.map +1 -1
  133. package/dist/index.mjs +1301 -77
  134. package/dist/middleware/manager.d.ts +3 -3
  135. package/dist/middleware/manager.d.ts.map +1 -1
  136. package/dist/middleware/manager.js +9 -8
  137. package/dist/middleware/manager.js.map +1 -1
  138. package/dist/openapi/docs-ui.d.ts.map +1 -1
  139. package/dist/openapi/docs-ui.js +1097 -61
  140. package/dist/openapi/docs-ui.js.map +1 -1
  141. package/dist/openapi/generator.d.ts +2 -1
  142. package/dist/openapi/generator.d.ts.map +1 -1
  143. package/dist/openapi/generator.js +332 -16
  144. package/dist/openapi/generator.js.map +1 -1
  145. package/dist/types/index.d.ts +71 -28
  146. package/dist/types/index.d.ts.map +1 -1
  147. package/dist/types/index.js +24 -1
  148. package/dist/types/index.js.map +1 -1
  149. package/dist/utils/validation.d.ts.map +1 -1
  150. package/dist/utils/validation.js +3 -2
  151. package/dist/utils/validation.js.map +1 -1
  152. package/package.json +9 -14
  153. package/src/auth/protected.ts +11 -8
  154. package/src/cache/manager.ts +23 -4
  155. package/src/checkpoint/artifacts/compressor.ts +30 -0
  156. package/src/checkpoint/artifacts/decompress-worker.ts +49 -0
  157. package/src/checkpoint/artifacts/hasher.ts +6 -0
  158. package/src/checkpoint/artifacts/manifest.ts +72 -0
  159. package/src/checkpoint/artifacts/materializer.ts +211 -0
  160. package/src/checkpoint/artifacts/packager.ts +100 -0
  161. package/src/checkpoint/artifacts/repository.ts +36 -0
  162. package/src/checkpoint/artifacts/store.ts +102 -0
  163. package/src/checkpoint/artifacts/types.ts +24 -0
  164. package/src/checkpoint/artifacts/worker-decompressor.ts +192 -0
  165. package/src/checkpoint/asset-store.ts +61 -0
  166. package/src/checkpoint/bundler.ts +64 -0
  167. package/src/checkpoint/cli.ts +177 -0
  168. package/src/checkpoint/entrypoint-generator.ts +275 -0
  169. package/src/checkpoint/forwarder.ts +84 -0
  170. package/src/checkpoint/gateway.ts +40 -0
  171. package/src/checkpoint/ipc.ts +107 -0
  172. package/src/checkpoint/manager.ts +254 -0
  173. package/src/checkpoint/process-manager.ts +250 -0
  174. package/src/checkpoint/resolver.ts +124 -0
  175. package/src/checkpoint/socket-path.ts +61 -0
  176. package/src/checkpoint/types.ts +63 -0
  177. package/src/cli/index.ts +11 -2
  178. package/src/cli/option-resolution.ts +5 -1
  179. package/src/core/config-loader.ts +11 -2
  180. package/src/core/router.ts +505 -264
  181. package/src/core/server.ts +51 -11
  182. package/src/core/vector.ts +60 -1
  183. package/src/dev/route-scanner.ts +2 -1
  184. package/src/http.ts +219 -19
  185. package/src/index.ts +3 -2
  186. package/src/middleware/manager.ts +10 -10
  187. package/src/openapi/docs-ui.ts +1097 -61
  188. package/src/openapi/generator.ts +380 -13
  189. package/src/types/index.ts +83 -30
  190. package/src/utils/validation.ts +5 -3
package/dist/index.mjs CHANGED
@@ -1,33 +1,221 @@
1
- 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},C={PORT:3000,HOSTNAME:"localhost",ROUTES_DIR:"./routes",CACHE_TTL:0,CORS_MAX_AGE:86400},_={JSON:"application/json",TEXT:"text/plain",HTML:"text/html",FORM_URLENCODED:"application/x-www-form-urlencoded",MULTIPART:"multipart/form-data"};var H={NOT_FOUND:new Response(JSON.stringify({error:!0,message:"Not Found",statusCode:404}),{status:404,headers:{"content-type":"application/json"}})};class ${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 J{cacheHandler=null;memoryCache=new Map;cleanupInterval=null;inflight=new Map;setCacheHandler(e){this.cacheHandler=e}clearCacheHandler(){this.cacheHandler=null}async get(e,t,n=C.CACHE_TTL){if(n<=0)return t();if(this.cacheHandler)return this.cacheHandler(e,t,n);return this.getFromMemoryCache(e,t,n)}async getFromMemoryCache(e,t,n){let d=Date.now(),r=this.memoryCache.get(e);if(this.isCacheValid(r,d))return r.value;if(this.inflight.has(e))return await this.inflight.get(e);let a=(async()=>{let i=await t();return this.setInMemoryCache(e,i,n),i})();this.inflight.set(e,a);try{return await a}finally{this.inflight.delete(e)}}isCacheValid(e,t){return e!==void 0&&e.expires>t}setInMemoryCache(e,t,n){let d=Date.now()+n*1000;this.memoryCache.set(e,{value:t,expires:d}),this.scheduleCleanup()}scheduleCleanup(){if(this.cleanupInterval)return;this.cleanupInterval=setInterval(()=>{this.cleanupExpired()},60000)}cleanupExpired(){let e=Date.now();for(let[t,n]of this.memoryCache.entries())if(n.expires<=e)this.memoryCache.delete(t);if(this.memoryCache.size===0&&this.cleanupInterval)clearInterval(this.cleanupInterval),this.cleanupInterval=null}clear(){if(this.memoryCache.clear(),this.cleanupInterval)clearInterval(this.cleanupInterval),this.cleanupInterval=null}async set(e,t,n=C.CACHE_TTL){if(n<=0)return;if(this.cacheHandler){await this.cacheHandler(e,async()=>t,n);return}this.setInMemoryCache(e,t,n)}delete(e){return this.memoryCache.delete(e)}has(e){let t=this.memoryCache.get(e);if(!t)return!1;if(t.expires<=Date.now())return this.memoryCache.delete(e),!1;return!0}generateKey(e,t){let n=e._parsedUrl??new URL(e.url),d=t?.authUser?.id!=null?String(t.authUser.id):"anonymous";return`${e.method}:${n.pathname}:${n.search}:${d}`}}var{promises:oe}=(()=>({}));function v(e){if(typeof e!=="string")throw new TypeError("Path must be a string. Received "+JSON.stringify(e))}function re(e,t){var n="",d=0,r=-1,a=0,i;for(var o=0;o<=e.length;++o){if(o<e.length)i=e.charCodeAt(o);else if(i===47)break;else i=47;if(i===47){if(r===o-1||a===1);else if(r!==o-1&&a===2){if(n.length<2||d!==2||n.charCodeAt(n.length-1)!==46||n.charCodeAt(n.length-2)!==46){if(n.length>2){var s=n.lastIndexOf("/");if(s!==n.length-1){if(s===-1)n="",d=0;else n=n.slice(0,s),d=n.length-1-n.lastIndexOf("/");r=o,a=0;continue}}else if(n.length===2||n.length===1){n="",d=0,r=o,a=0;continue}}if(t){if(n.length>0)n+="/..";else n="..";d=2}}else{if(n.length>0)n+="/"+e.slice(r+1,o);else n=e.slice(r+1,o);d=o-r-1}r=o,a=0}else if(i===46&&a!==-1)++a;else a=-1}return n}function Oe(e,t){var n=t.dir||t.root,d=t.base||(t.name||"")+(t.ext||"");if(!n)return d;if(n===t.root)return n+d;return n+e+d}function B(){var e="",t=!1,n;for(var d=arguments.length-1;d>=-1&&!t;d--){var r;if(d>=0)r=arguments[d];else{if(n===void 0)n=process.cwd();r=n}if(v(r),r.length===0)continue;e=r+"/"+e,t=r.charCodeAt(0)===47}if(e=re(e,!t),t)if(e.length>0)return"/"+e;else return"/";else if(e.length>0)return e;else return"."}function ae(e){if(v(e),e.length===0)return".";var t=e.charCodeAt(0)===47,n=e.charCodeAt(e.length-1)===47;if(e=re(e,!t),e.length===0&&!t)e=".";if(e.length>0&&n)e+="/";if(t)return"/"+e;return e}function V(e){return v(e),e.length>0&&e.charCodeAt(0)===47}function j(){if(arguments.length===0)return".";var e;for(var t=0;t<arguments.length;++t){var n=arguments[t];if(v(n),n.length>0)if(e===void 0)e=n;else e+="/"+n}if(e===void 0)return".";return ae(e)}function D(e,t){if(v(e),v(t),e===t)return"";if(e=B(e),t=B(t),e===t)return"";var n=1;for(;n<e.length;++n)if(e.charCodeAt(n)!==47)break;var d=e.length,r=d-n,a=1;for(;a<t.length;++a)if(t.charCodeAt(a)!==47)break;var i=t.length,o=i-a,s=r<o?r:o,c=-1,l=0;for(;l<=s;++l){if(l===s){if(o>s){if(t.charCodeAt(a+l)===47)return t.slice(a+l+1);else if(l===0)return t.slice(a+l)}else if(r>s){if(e.charCodeAt(n+l)===47)c=l;else if(l===0)c=0}break}var u=e.charCodeAt(n+l),m=t.charCodeAt(a+l);if(u!==m)break;else if(u===47)c=l}var h="";for(l=n+c+1;l<=d;++l)if(l===d||e.charCodeAt(l)===47)if(h.length===0)h+="..";else h+="/..";if(h.length>0)return h+t.slice(a+c);else{if(a+=c,t.charCodeAt(a)===47)++a;return t.slice(a)}}function He(e){return e}function T(e){if(v(e),e.length===0)return".";var t=e.charCodeAt(0),n=t===47,d=-1,r=!0;for(var a=e.length-1;a>=1;--a)if(t=e.charCodeAt(a),t===47){if(!r){d=a;break}}else r=!1;if(d===-1)return n?"/":".";if(n&&d===1)return"//";return e.slice(0,d)}function Te(e,t){if(t!==void 0&&typeof t!=="string")throw new TypeError('"ext" argument must be a string');v(e);var n=0,d=-1,r=!0,a;if(t!==void 0&&t.length>0&&t.length<=e.length){if(t.length===e.length&&t===e)return"";var i=t.length-1,o=-1;for(a=e.length-1;a>=0;--a){var s=e.charCodeAt(a);if(s===47){if(!r){n=a+1;break}}else{if(o===-1)r=!1,o=a+1;if(i>=0)if(s===t.charCodeAt(i)){if(--i===-1)d=a}else i=-1,d=o}}if(n===d)d=o;else if(d===-1)d=e.length;return e.slice(n,d)}else{for(a=e.length-1;a>=0;--a)if(e.charCodeAt(a)===47){if(!r){n=a+1;break}}else if(d===-1)r=!1,d=a+1;if(d===-1)return"";return e.slice(n,d)}}function Se(e){v(e);var t=-1,n=0,d=-1,r=!0,a=0;for(var i=e.length-1;i>=0;--i){var o=e.charCodeAt(i);if(o===47){if(!r){n=i+1;break}continue}if(d===-1)r=!1,d=i+1;if(o===46){if(t===-1)t=i;else if(a!==1)a=1}else if(t!==-1)a=-1}if(t===-1||d===-1||a===0||a===1&&t===d-1&&t===n+1)return"";return e.slice(t,d)}function Pe(e){if(e===null||typeof e!=="object")throw new TypeError('The "pathObject" argument must be of type Object. Received type '+typeof e);return Oe("/",e)}function Re(e){v(e);var t={root:"",dir:"",base:"",ext:"",name:""};if(e.length===0)return t;var n=e.charCodeAt(0),d=n===47,r;if(d)t.root="/",r=1;else r=0;var a=-1,i=0,o=-1,s=!0,c=e.length-1,l=0;for(;c>=r;--c){if(n=e.charCodeAt(c),n===47){if(!s){i=c+1;break}continue}if(o===-1)s=!1,o=c+1;if(n===46){if(a===-1)a=c;else if(l!==1)l=1}else if(a!==-1)l=-1}if(a===-1||o===-1||l===0||l===1&&a===o-1&&a===i+1){if(o!==-1)if(i===0&&d)t.base=t.name=e.slice(1,o);else t.base=t.name=e.slice(i,o)}else{if(i===0&&d)t.name=e.slice(1,a),t.base=e.slice(1,o);else t.name=e.slice(i,a),t.base=e.slice(i,o);t.ext=e.slice(a,o)}if(i>0)t.dir=e.slice(0,i-1);else if(d)t.dir="/";return t}var S="/",Ue=":",Ot=((e)=>(e.posix=e,e))({resolve:B,normalize:ae,isAbsolute:V,join:j,relative:D,_makeLong:He,dirname:T,basename:Te,extname:Se,format:Pe,parse:Re,sep:S,delimiter:Ue,win32:null,posix:null});class F{outputPath;constructor(e="./.vector/routes.generated.ts"){this.outputPath=e}async generate(e){let t=T(this.outputPath);await oe.mkdir(t,{recursive:!0});let n=[],d=new Map;for(let o of e){if(!d.has(o.path))d.set(o.path,[]);d.get(o.path).push(o)}let r=0,a=[];for(let[o,s]of d){let c=D(T(this.outputPath),o).replace(/\\/g,"/").replace(/\.(ts|js)$/,""),l=`route_${r++}`,u=s.filter((m)=>m.name!=="default").map((m)=>m.name);if(s.some((m)=>m.name==="default"))if(u.length>0)n.push(`import ${l}, { ${u.join(", ")} } from '${c}';`);else n.push(`import ${l} from '${c}';`);else if(u.length>0)n.push(`import { ${u.join(", ")} } from '${c}';`);for(let m of s){let h=m.name==="default"?l:m.name;a.push(` ${h},`)}}let i=`// This file is auto-generated. Do not edit manually.
1
+ // @bun
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.
2
190
  // Generated at: ${new Date().toISOString()}
3
191
 
4
- ${n.join(`
192
+ ${r.join(`
5
193
  `)}
6
194
 
7
195
  export const routes = [
8
- ${a.join(`
196
+ ${o.join(`
9
197
  `)}
10
198
  ];
11
199
 
12
200
  export default routes;
13
- `;await oe.writeFile(this.outputPath,i,"utf-8")}async generateDynamic(e){let t=[];for(let n of e){let d=JSON.stringify({method:n.method,path:n.options.path,options:n.options});t.push(` await import('${n.path}').then(m => ({
14
- ...${d},
15
- handler: m.${n.name==="default"?"default":n.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}
16
204
  }))`)}return`export const loadRoutes = async () => {
17
205
  return Promise.all([
18
206
  ${t.join(`,
19
207
  `)}
20
208
  ]);
21
- };`}}var{existsSync:_e,promises:ie}=(()=>({}));class P{routesDir;excludePatterns;static DEFAULT_EXCLUDE_PATTERNS=["*.test.ts","*.test.js","*.test.tsx","*.test.jsx","*.spec.ts","*.spec.js","*.spec.tsx","*.spec.jsx","*.tests.ts","*.tests.js","**/__tests__/**","*.interface.ts","*.type.ts","*.d.ts"];constructor(e="./routes",t){this.routesDir=B(process.cwd(),e),this.excludePatterns=t||P.DEFAULT_EXCLUDE_PATTERNS}async scan(){let e=[];if(!_e(this.routesDir))return[];try{await this.scanDirectory(this.routesDir,e)}catch(t){if(t.code==="ENOENT")return console.warn(` ✗ Routes directory not accessible: ${this.routesDir}`),[];throw t}return e}isExcluded(e){let t=D(this.routesDir,e);for(let n of this.excludePatterns){let d=n.replace(/\./g,"\\.").replace(/\*\*/g,"__GLOBSTAR__").replace(/\*/g,"[^/]*").replace(/__GLOBSTAR__/g,".*").replace(/\?/g,"."),r=new RegExp(`^${d}$`),a=t.split(S).pop()||"";if(r.test(t)||r.test(a))return!0}return!1}async scanDirectory(e,t,n=""){let d=await ie.readdir(e);for(let r of d){let a=j(e,r);if((await ie.stat(a)).isDirectory()){let o=n?`${n}/${r}`:r;await this.scanDirectory(a,t,o)}else if(r.endsWith(".ts")||r.endsWith(".js")){if(this.isExcluded(a))continue;let o=D(this.routesDir,a).replace(/\.(ts|js)$/,"").split(S).join("/");try{let c=await import(process.platform==="win32"?`file:///${a.replace(/\\/g,"/")}`:a);if(c.default&&typeof c.default==="function")t.push({name:"default",path:a,method:"GET",options:{method:"GET",path:`/${o}`,expose:!0}});for(let[l,u]of Object.entries(c)){if(l==="default")continue;if(u&&typeof u==="object"&&"entry"in u&&"options"in u&&"handler"in u){let m=u;t.push({name:l,path:a,method:m.options.method,options:m.options})}else if(Array.isArray(u)&&u.length>=4){let[m,,,h]=u;t.push({name:l,path:a,method:m,options:{method:m,path:h,expose:!0}})}}}catch(s){console.error(`Failed to load route from ${a}:`,s)}}}}enableWatch(e){if(typeof Bun!=="undefined"&&Bun.env.NODE_ENV==="development")console.log(`Watching for route changes in ${this.routesDir}`),setInterval(async()=>{await e()},1000)}}class R{beforeHandlers=[];finallyHandlers=[];addBefore(...e){this.beforeHandlers.push(...e)}addFinally(...e){this.finallyHandlers.push(...e)}async executeBefore(e){if(this.beforeHandlers.length===0)return e;let t=e;for(let n of this.beforeHandlers){let d=await n(t);if(d instanceof Response)return d;t=d}return t}async executeFinally(e,t){if(this.finallyHandlers.length===0)return e;let n=e;for(let d of this.finallyHandlers)try{n=await d(n,t)}catch(r){console.error("After middleware error:",r)}return n}clone(){let e=new R;return e.beforeHandlers=[...this.beforeHandlers],e.finallyHandlers=[...this.finallyHandlers],e}clear(){this.beforeHandlers=[],this.finallyHandlers=[]}}function U(e){return process.platform==="win32"?`file:///${e.replace(/\\/g,"/")}`:e}function z(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 se(e){let t=e?.["~standard"];return!!t&&typeof t==="object"&&typeof t.validate==="function"&&t.version===1}async function le(e,t){let n=await e["~standard"].validate(t),d=n?.issues;if(Array.isArray(d)&&d.length>0)return{success:!1,issues:d};return{success:!0,value:n?.value}}function ce(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 $e(e){if(!Array.isArray(e))return[];let t=[];for(let n=0;n<e.length;n++){let d=e[n],r=d;if(d&&typeof d==="object"&&"key"in d)r=d.key;if(typeof r==="string"||typeof r==="number")t.push(r);else if(typeof r==="symbol")t.push(String(r));else if(r!==void 0&&r!==null)t.push(String(r))}return t}function G(e,t){let n=[];for(let d=0;d<e.length;d++){let r=e[d],a=r,i={message:typeof a?.message==="string"&&a.message.length>0?a.message:"Invalid value",path:$e(a?.path)};if(typeof a?.code==="string")i.code=a.code;if(t)i.raw=r;n.push(i)}return n}function Q(e,t){return{error:!0,message:"Validation failed",statusCode:422,source:"validation",target:e,issues:t,timestamp:new Date().toISOString()}}class M{middlewareManager;authManager;cacheManager;routeBooleanDefaults={};developmentMode=void 0;routeDefinitions=[];routeTable=Object.create(null);routeMatchers=[];corsHeadersEntries=null;corsHandler=null;constructor(e,t,n){this.middlewareManager=e,this.authManager=t,this.cacheManager=n}setCorsHeaders(e){this.corsHeadersEntries=e}setCorsHandler(e){this.corsHandler=e}setRouteBooleanDefaults(e){this.routeBooleanDefaults={...e}}setDevelopmentMode(e){this.developmentMode=e}applyRouteBooleanDefaults(e){let t={...e},n=this.routeBooleanDefaults,d=["auth","expose","rawRequest","validate","rawResponse"];for(let r of d)if(t[r]===void 0&&n[r]!==void 0)t[r]=n[r];return t}route(e,t){let n=this.applyRouteBooleanDefaults(e),d=n.method.toUpperCase(),r=n.path,a=this.wrapHandler(n,t),i=this.getOrCreateMethodMap(r);i[d]=a,this.routeDefinitions.push({method:d,path:r,options:n})}addRoute(e){let[t,,n,d]=e;if(!d)return;let r=this.getOrCreateMethodMap(d);r[t.toUpperCase()]=n[0];let a=t.toUpperCase();this.routeDefinitions.push({method:a,path:d,options:{method:a,path:d,expose:!0}})}bulkAddRoutes(e){for(let t of e)this.addRoute(t)}addStaticRoute(e,t){let n=this.routeTable[e];if(n&&!(n instanceof Response))throw new Error(`Cannot register static route for path "${e}" because method routes already exist.`);this.routeTable[e]=t,this.removeRouteMatcher(e)}getRouteTable(){return this.routeTable}getRoutes(){let e=[];for(let t of this.routeMatchers){let n=this.routeTable[t.path];if(!n||n instanceof Response)continue;for(let[d,r]of Object.entries(n))e.push([d,t.regex,[r],t.path])}return e}getRouteDefinitions(){return[...this.routeDefinitions]}clearRoutes(){this.routeTable=Object.create(null),this.routeMatchers=[],this.routeDefinitions=[]}sortRoutes(){}async handle(e){let t;try{t=new URL(e.url)}catch{return w.badRequest("Malformed request URL")}e._parsedUrl=t;let n=t.pathname;for(let d of this.routeMatchers){let r=d.path,a=this.routeTable[r];if(!a)continue;if(a instanceof Response)continue;let i=a;if(e.method==="OPTIONS"||e.method in i){let o=n.match(d.regex);if(o){try{e.params=o.groups??{}}catch{}let s=i[e.method]??i.GET;if(s){let c=await s(e);if(c)return c}}}}return H.NOT_FOUND.clone()}prepareRequest(e,t){if(!e.context)e.context={};let n=!!e.params&&typeof e.params==="object"&&!Array.isArray(e.params)&&Object.keys(e.params).length===0;if(t?.params!==void 0&&(e.params===void 0||n))try{e.params=t.params}catch{}if(t?.route!==void 0)e.route=t.route;if(t?.metadata!==void 0)e.metadata=t.metadata;if(e.query==null&&e.url)try{Object.defineProperty(e,"query",{get(){let d=this._parsedUrl??new URL(this.url),r=M.parseQuery(d);return Object.defineProperty(this,"query",{value:r,writable:!0,configurable:!0,enumerable:!0}),r},set(d){Object.defineProperty(this,"query",{value:d,writable:!0,configurable:!0,enumerable:!0})},configurable:!0,enumerable:!0})}catch{let d=e._parsedUrl??new URL(e.url);try{e.query=M.parseQuery(d)}catch{}}if(!Object.getOwnPropertyDescriptor(e,"cookies"))Object.defineProperty(e,"cookies",{get(){let d=this.headers.get("cookie")??"",r={};if(d)for(let a of d.split(";")){let i=a.indexOf("=");if(i>0)r[a.slice(0,i).trim()]=a.slice(i+1).trim()}return Object.defineProperty(this,"cookies",{value:r,writable:!0,configurable:!0,enumerable:!0}),r},configurable:!0,enumerable:!0})}resolveFallbackParams(e,t){if(!t)return;let n=e.params;if(n&&typeof n==="object"&&!Array.isArray(n)&&Object.keys(n).length>0)return;let d;try{d=(e._parsedUrl??new URL(e.url)).pathname}catch{return}let r=d.match(t);if(!r?.groups)return;return r.groups}wrapHandler(e,t){let n=e.path,d=n.includes(":")?z(n):null;return async(r)=>{let a=r,i=this.resolveFallbackParams(r,d);this.prepareRequest(a,{params:i,route:n,metadata:e.metadata});try{if(e.expose===!1)return w.forbidden("Forbidden");let o=await this.middlewareManager.executeBefore(a);if(o instanceof Response)return o;let s=o;if(e.auth)try{await this.authManager.authenticate(s)}catch(f){return w.unauthorized(f instanceof Error?f.message:"Authentication failed",e.responseContentType)}if(!e.rawRequest&&s.method!=="GET"&&s.method!=="HEAD"){let f=null;try{let p=s.headers.get("content-type");if(p?.startsWith("application/json"))f=await s.json();else if(p?.startsWith("application/x-www-form-urlencoded"))f=Object.fromEntries(await s.formData());else if(p?.startsWith("multipart/form-data"))f=await s.formData();else f=await s.text()}catch{f=null}this.setContentAndBodyAlias(s,f)}let c=await this.validateInputSchema(s,e);if(c)return c;let l,u=e.cache;if(u&&typeof u==="number"&&u>0){let f=this.cacheManager.generateKey(s,{authUser:s.authUser});l=await this.cacheManager.get(f,async()=>{let p=await t(s);if(p instanceof Response)return{_isResponse:!0,body:await p.text(),status:p.status,headers:Object.fromEntries(p.headers.entries())};return p},u)}else if(u&&typeof u==="object"&&u.ttl){let f=u.key||this.cacheManager.generateKey(s,{authUser:s.authUser});l=await this.cacheManager.get(f,async()=>{let p=await t(s);if(p instanceof Response)return{_isResponse:!0,body:await p.text(),status:p.status,headers:Object.fromEntries(p.headers.entries())};return p},u.ttl)}else l=await t(s);if(l&&typeof l==="object"&&l._isResponse===!0)l=new Response(l.body,{status:l.status,headers:l.headers});let m;if(e.rawResponse||l instanceof Response)m=l instanceof Response?l:new Response(l);else m=N(200,l,e.responseContentType);m=await this.middlewareManager.executeFinally(m,s);let h=this.corsHeadersEntries;if(h)for(let[f,p]of h)m.headers.set(f,p);else{let f=this.corsHandler;if(f)m=f(m,s)}return m}catch(o){if(o instanceof Response)return o;return console.error("Route handler error:",o),w.internalServerError(o instanceof Error?o.message:String(o),e.responseContentType)}}}isDevelopmentMode(){if(this.developmentMode!==void 0)return this.developmentMode;return(typeof Bun!=="undefined"?Bun.env.NODE_ENV:"development")!=="production"}async buildInputValidationPayload(e,t){let n=e.content;if(t.rawRequest&&e.method!=="GET"&&e.method!=="HEAD")try{n=await e.clone().text()}catch{n=null}return{params:e.params??{},query:e.query??{},headers:Object.fromEntries(e.headers.entries()),cookies:e.cookies??{},body:n}}applyValidatedInput(e,t){if(e.validatedInput=t,!t||typeof t!=="object")return;let n=t;if("params"in n)try{e.params=n.params}catch{}if("query"in n)try{e.query=n.query}catch{}if("cookies"in n)try{e.cookies=n.cookies}catch{}if("body"in n)this.setContentAndBodyAlias(e,n.body)}setContentAndBodyAlias(e,t){try{e.content=t}catch{return}this.setBodyAlias(e,t)}setBodyAlias(e,t){try{e.body=t}catch{}}async validateInputSchema(e,t){let n=t.schema?.input;if(!n)return null;if(t.validate===!1)return null;if(!se(n))return w.internalServerError("Invalid route schema configuration",t.responseContentType);let d=this.isDevelopmentMode(),r=await this.buildInputValidationPayload(e,t);try{let a=await le(n,r);if(a.success===!1){let i=G(a.issues,d);return N(422,Q("input",i),t.responseContentType)}return this.applyValidatedInput(e,a.value),null}catch(a){let i=ce(a);if(i){let o=G(i,d);return N(422,Q("input",o),t.responseContentType)}return w.internalServerError(a instanceof Error?a.message:"Validation failed",t.responseContentType)}}getOrCreateMethodMap(e){let t=this.routeTable[e];if(t instanceof Response)throw new Error(`Cannot register method route for path "${e}" because a static route already exists.`);if(t)return t;let n=Object.create(null);return this.routeTable[e]=n,this.addRouteMatcher(e),n}addRouteMatcher(e){if(this.routeMatchers.some((t)=>t.path===e))return;this.routeMatchers.push({path:e,regex:z(e),specificity:this.routeSpecificityScore(e)}),this.routeMatchers.sort((t,n)=>{if(t.specificity!==n.specificity)return n.specificity-t.specificity;return t.path.localeCompare(n.path)})}removeRouteMatcher(e){this.routeMatchers=this.routeMatchers.filter((t)=>t.path!==e)}static parseQuery(e){let t={};for(let[n,d]of e.searchParams)if(n in t){let r=t[n];if(Array.isArray(r))r.push(d);else t[n]=[r,d]}else t[n]=d;return t}routeSpecificityScore(e){let a=e.split("/").filter(Boolean),i=0;for(let o of a)if(o.includes("*"))i+=1;else if(o.startsWith(":"))i+=10;else i+=1000;if(i+=e.length,!e.includes(":")&&!e.includes("*"))i+=1e4;return i}}var{existsSync:Ee}=(()=>({}));function be(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 ue(e){return typeof e.origin==="string"&&e.origin==="*"&&e.credentials||Array.isArray(e.origin)||typeof e.origin==="function"}function me(e,t,n){let d={};if(e){if(d["access-control-allow-origin"]=e,d["access-control-allow-methods"]=t.allowMethods,d["access-control-allow-headers"]=t.allowHeaders,d["access-control-expose-headers"]=t.exposeHeaders,d["access-control-max-age"]=String(t.maxAge),t.credentials)d["access-control-allow-credentials"]="true";if(n)d.vary="Origin"}return d}function Je(e,t){if(!e)return t;let n=e.split(",").map((r)=>r.trim()).filter(Boolean);if(!n.map((r)=>r.toLowerCase()).includes(t.toLowerCase()))n.push(t);return n.join(", ")}function fe(e){return{preflight(t){let n=t.headers.get("origin")??void 0,d=be(n,e),r=Boolean(n&&d&&ue(e));return new Response(null,{status:204,headers:me(d,e,r)})},corsify(t,n){let d=n.headers.get("origin")??void 0,r=be(d,e);if(!r)return t;let a=Boolean(d&&ue(e)),i=me(r,e,a);for(let[o,s]of Object.entries(i)){if(o==="vary"){t.headers.set("vary",Je(t.headers.get("vary"),s));continue}t.headers.set(o,s)}return t}}}function pe(e,t,n,d,r,a,i,o,s){let c=JSON.stringify(e).replace(/<\/script/gi,"<\\/script"),l=JSON.stringify(t),u=JSON.stringify(n),m=JSON.stringify(d),h=JSON.stringify(r),f=JSON.stringify(a),p=JSON.stringify(i),je=JSON.stringify(o),Me=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>
22
210
  <html lang="en">
23
211
  <head>
24
212
  <meta charset="UTF-8">
25
213
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
26
214
  <title>Vector API Documentation</title>
27
- <link rel="apple-touch-icon" sizes="180x180" href=${f}>
28
- <link rel="icon" type="image/png" sizes="32x32" href=${p}>
29
- <link rel="icon" type="image/png" sizes="16x16" href=${je}>
30
- <link rel="manifest" href=${Me}>
215
+ <link rel="apple-touch-icon" sizes="180x180" href=${u}>
216
+ <link rel="icon" type="image/png" sizes="32x32" href=${f}>
217
+ <link rel="icon" type="image/png" sizes="16x16" href=${L}>
218
+ <link rel="manifest" href=${x}>
31
219
  <script>
32
220
  if (localStorage.getItem('theme') === 'dark' || (!('theme' in localStorage) && window.matchMedia('(prefers-color-scheme: dark)').matches)) {
33
221
  document.documentElement.classList.add('dark');
@@ -35,7 +223,7 @@ ${t.join(`,
35
223
  document.documentElement.classList.remove('dark');
36
224
  }
37
225
  </script>
38
- <script src=${u}></script>
226
+ <script src=${s}></script>
39
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">
40
228
  <script>
41
229
  tailwind.config = {
@@ -143,6 +331,124 @@ ${t.join(`,
143
331
  .dark .json-number { color: #7dc9ff; }
144
332
  .dark .json-boolean { color: #93a4bf; }
145
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
+ }
146
452
  </style>
147
453
  </head>
148
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">
@@ -150,7 +456,7 @@ ${t.join(`,
150
456
  <aside id="docs-sidebar" class="fixed inset-y-0 left-0 z-40 w-72 md:w-64 border-r border-light-border dark:border-dark-border bg-light-surface dark:bg-dark-surface flex flex-col flex-shrink-0 transition-transform duration-300 ease-out -translate-x-full md:translate-x-0 md:static md:z-auto transition-colors duration-150">
151
457
  <div class="h-14 flex items-center px-5 border-b border-light-border dark:border-dark-border">
152
458
  <div class="flex items-center">
153
- <img src=${m} alt="Vector" class="h-6 w-auto block dark:hidden" />
459
+ <img src=${p} alt="Vector" class="h-6 w-auto block dark:hidden" />
154
460
  <img src=${h} alt="Vector" class="h-6 w-auto hidden dark:block" />
155
461
  </div>
156
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">
@@ -172,6 +478,16 @@ ${t.join(`,
172
478
  />
173
479
  </div>
174
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>
175
491
  <nav class="flex-1 overflow-y-auto px-3 py-2 space-y-6 text-sm" id="sidebar-nav"></nav>
176
492
  </aside>
177
493
 
@@ -183,7 +499,7 @@ ${t.join(`,
183
499
  <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6h16M4 12h16M4 18h16"></path>
184
500
  </svg>
185
501
  </button>
186
- <img src=${m} alt="Vector" class="h-5 w-auto block dark:hidden" />
502
+ <img src=${p} alt="Vector" class="h-5 w-auto block dark:hidden" />
187
503
  <img src=${h} alt="Vector" class="h-5 w-auto hidden dark:block" />
188
504
  </div>
189
505
  <div class="flex-1"></div>
@@ -205,6 +521,9 @@ ${t.join(`,
205
521
  <span id="endpoint-method" class="px-2.5 py-0.5 rounded-full text-xs font-mono font-medium"></span>
206
522
  <h2 class="text-xl font-semibold tracking-tight" id="endpoint-title">Operation</h2>
207
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>
208
527
  <p class="text-sm opacity-80 mb-8 font-mono" id="endpoint-path">/</p>
209
528
  <div class="grid grid-cols-1 lg:grid-cols-12 gap-10">
210
529
  <div class="lg:col-span-5 space-y-8" id="params-column"></div>
@@ -300,10 +619,14 @@ ${t.join(`,
300
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>
301
620
  </div>
302
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>
303
626
 
304
627
  <script>
305
628
  const spec = ${c};
306
- const openapiPath = ${l};
629
+ const openapiPath = ${m};
307
630
  const methodBadgeDefault = "bg-black/5 text-light-text/80 dark:bg-white/10 dark:text-dark-text/80";
308
631
  const methodBadge = {
309
632
  GET: "bg-brand-soft text-brand-deep dark:bg-brand/20 dark:text-brand",
@@ -370,14 +693,71 @@ ${t.join(`,
370
693
  return ops;
371
694
  }
372
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
+
373
748
  const operations = getOperations();
374
749
  let selected = operations[0] || null;
375
750
  const operationParamValues = new Map();
376
751
  const operationBodyDrafts = new Map();
377
- const requestHeaders = [{ key: "Authorization", value: "" }];
752
+ const requestHeaders = loadSavedHeaders();
378
753
  let expandModalMode = null;
379
754
  let isMobileSidebarOpen = false;
380
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;
381
761
 
382
762
  function setMobileSidebarOpen(open) {
383
763
  const sidebar = document.getElementById("docs-sidebar");
@@ -397,6 +777,29 @@ ${t.join(`,
397
777
  return op.method + " " + op.path;
398
778
  }
399
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
+
400
803
  function getOperationParameterGroups(op) {
401
804
  const params =
402
805
  op &&
@@ -446,7 +849,7 @@ ${t.join(`,
446
849
  return resolved;
447
850
  }
448
851
 
449
- function buildRequestPath(op, pathParams, queryParams, values) {
852
+ function buildRequestPath(op, pathParams, queryParams, values, extraQuery) {
450
853
  const resolvedPath = resolvePath(op.path, pathParams, values);
451
854
  const query = new URLSearchParams();
452
855
 
@@ -458,6 +861,13 @@ ${t.join(`,
458
861
  query.append(param.name, String(rawValue));
459
862
  }
460
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
+
461
871
  const queryString = query.toString();
462
872
  return queryString ? resolvedPath + "?" + queryString : resolvedPath;
463
873
  }
@@ -597,14 +1007,25 @@ ${t.join(`,
597
1007
 
598
1008
  const name = document.createElement("span");
599
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
+ }
600
1014
 
601
1015
  row.appendChild(method);
602
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
+ }
603
1023
  a.appendChild(row);
604
1024
 
605
1025
  a.onclick = (e) => {
606
1026
  e.preventDefault();
607
1027
  selected = op;
1028
+ history.pushState(null, "", getOpHash(op));
608
1029
  renderSidebar();
609
1030
  renderEndpoint();
610
1031
  if (window.innerWidth < 768) {
@@ -618,51 +1039,257 @@ ${t.join(`,
618
1039
  }
619
1040
  }
620
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
+
621
1155
  function renderParamSection(title, params) {
622
1156
  if (!params.length) return "";
623
1157
  let rows = "";
624
1158
  for (const p of params) {
625
- const type = escapeHtml((p.schema && p.schema.type) || "unknown");
626
- const name = escapeHtml(p.name || "");
627
- 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>";
628
1200
  }
629
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>";
630
1202
  }
631
1203
 
632
1204
  function getSchemaTypeLabel(schema) {
633
- if (!schema || typeof schema !== "object") return "unknown";
634
- if (Array.isArray(schema.type)) return schema.type.join(" | ");
635
- if (schema.type) return String(schema.type);
636
- if (schema.properties) return "object";
637
- if (schema.items) return "array";
638
- if (Array.isArray(schema.oneOf)) return "oneOf";
639
- if (Array.isArray(schema.anyOf)) return "anyOf";
640
- 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";
641
1214
  return "unknown";
642
1215
  }
643
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
+
644
1265
  function buildSchemaChildren(schema) {
645
- if (!schema || typeof schema !== "object") return [];
1266
+ const resolved = resolveSchemaRef(schema);
1267
+ if (!resolved || typeof resolved !== "object") return [];
646
1268
 
647
1269
  const children = [];
648
1270
 
649
- if (schema.properties && typeof schema.properties === "object") {
1271
+ if (resolved.properties && typeof resolved.properties === "object") {
650
1272
  const requiredSet = new Set(
651
- Array.isArray(schema.required) ? schema.required : [],
1273
+ Array.isArray(resolved.required) ? resolved.required : [],
652
1274
  );
653
- 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;
654
1281
  children.push({
655
- name,
656
- schema: childSchema || {},
1282
+ name: isArrayLike ? (name + "[]") : name,
1283
+ schema: childDef,
657
1284
  required: requiredSet.has(name),
658
1285
  });
659
1286
  }
660
1287
  }
661
1288
 
662
- if (schema.items) {
1289
+ if (resolved.items) {
663
1290
  children.push({
664
- name: "items[]",
665
- schema: schema.items,
1291
+ name: getArrayItemNodeName(resolved.items),
1292
+ schema: resolved.items,
666
1293
  required: true,
667
1294
  });
668
1295
  }
@@ -670,45 +1297,100 @@ ${t.join(`,
670
1297
  return children;
671
1298
  }
672
1299
 
673
- function renderSchemaFieldNode(field, depth) {
674
- const schema = field.schema || {};
675
- 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);
676
1327
  const requiredLabel = field.required ? "required" : "optional";
677
- 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
+ : "";
678
1337
  const children = buildSchemaChildren(schema);
679
1338
  const padding = depth * 14;
1339
+ const extra = buildSchemaExtra(schema);
680
1340
 
681
1341
  if (!children.length) {
682
1342
  return (
683
- '<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:' +
684
1344
  padding +
685
- '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">' +
686
1353
  name +
687
- '</code><span class="text-xs text-brand ml-2">' +
1354
+ '</code></button><span class="text-xs text-brand shrink-0">' +
688
1355
  requiredLabel +
689
- '</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">' +
690
1361
  type +
691
- "</span></div></div>"
1362
+ "</button></div>" + extra + "</div>"
692
1363
  );
693
1364
  }
694
1365
 
695
1366
  let nested = "";
696
1367
  for (const child of children) {
697
- nested += renderSchemaFieldNode(child, depth + 1);
1368
+ nested += renderSchemaFieldNode(child, depth + 1, fieldPath);
698
1369
  }
699
1370
 
700
1371
  return (
701
- '<details class="border-b border-light-border/50 dark:border-dark-border/50" open>' +
702
- '<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:' +
703
1374
  padding +
704
- 'px"><div class="flex items-center gap-2"><span class="text-xs opacity-70">▾</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">' +
705
1383
  name +
706
- '</code><span class="text-xs text-brand">' +
1384
+ '</code></button><span class="text-xs text-brand shrink-0">' +
707
1385
  requiredLabel +
708
- '</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">' +
709
1391
  type +
710
- "</span></summary>" +
711
- '<div class="pb-1">' +
1392
+ "</button></div>" + extra + "</summary>" +
1393
+ "<div>" +
712
1394
  nested +
713
1395
  "</div></details>"
714
1396
  );
@@ -721,7 +1403,7 @@ ${t.join(`,
721
1403
 
722
1404
  let rows = "";
723
1405
  for (const child of rootChildren) {
724
- rows += renderSchemaFieldNode(child, 0);
1406
+ rows += renderSchemaFieldNode(child, 0, "");
725
1407
  }
726
1408
 
727
1409
  return (
@@ -748,27 +1430,40 @@ ${t.join(`,
748
1430
  const responseDef = responses[statusCode];
749
1431
  if (!responseDef || typeof responseDef !== "object") continue;
750
1432
 
1433
+ const responseDesc = (typeof responseDef.description === "string" && responseDef.description.trim())
1434
+ ? responseDef.description.trim()
1435
+ : "";
1436
+
751
1437
  const jsonSchema =
752
1438
  responseDef.content &&
753
1439
  responseDef.content["application/json"] &&
754
1440
  responseDef.content["application/json"].schema;
755
1441
 
756
- if (!jsonSchema || typeof jsonSchema !== "object") continue;
757
-
758
- const rootChildren = buildSchemaChildren(jsonSchema);
759
- if (!rootChildren.length) continue;
760
-
761
1442
  let rows = "";
762
- for (const child of rootChildren) {
763
- 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
+ }
764
1448
  }
765
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
+
766
1457
  sections +=
767
- '<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 ' +
768
1461
  escapeHtml(statusCode) +
1462
+ descHtml +
769
1463
  "</h4>" +
770
- rows +
771
- "</div>";
1464
+ "</summary>" +
1465
+ contentHtml +
1466
+ "</details>";
772
1467
  }
773
1468
 
774
1469
  if (!sections) return "";
@@ -860,6 +1555,7 @@ ${t.join(`,
860
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";
861
1556
  keyInput.addEventListener("input", () => {
862
1557
  entry.key = keyInput.value;
1558
+ saveHeaders();
863
1559
  updateRequestPreview();
864
1560
  });
865
1561
 
@@ -874,6 +1570,7 @@ ${t.join(`,
874
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";
875
1571
  valueInput.addEventListener("input", () => {
876
1572
  entry.value = valueInput.value;
1573
+ saveHeaders();
877
1574
  updateRequestPreview();
878
1575
  });
879
1576
 
@@ -887,6 +1584,7 @@ ${t.join(`,
887
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>';
888
1585
  removeButton.addEventListener("click", () => {
889
1586
  requestHeaders.splice(index, 1);
1587
+ saveHeaders();
890
1588
  renderHeaderInputs();
891
1589
  updateRequestPreview();
892
1590
  });
@@ -903,15 +1601,32 @@ ${t.join(`,
903
1601
  return Object.keys(headers).some((key) => key.toLowerCase() === target);
904
1602
  }
905
1603
 
906
- function getRequestHeadersObject() {
907
- 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 = {};
908
1622
  for (const entry of requestHeaders) {
909
1623
  const key = String(entry.key || "").trim();
910
1624
  const value = String(entry.value || "").trim();
911
1625
  if (!key || !value) continue;
912
- headers[key] = value;
1626
+ manual[key] = value;
913
1627
  }
914
- return headers;
1628
+ // Auth provides defaults; manual headers win on conflict
1629
+ return Object.assign({}, auth, manual);
915
1630
  }
916
1631
 
917
1632
  function buildCurl(op, headers, body, requestPath) {
@@ -948,6 +1663,33 @@ ${t.join(`,
948
1663
  .replace(/>/g, "&gt;");
949
1664
  }
950
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
+
951
1693
  function toPrettyJson(value) {
952
1694
  const trimmed = (value || "").trim();
953
1695
  if (!trimmed) return null;
@@ -1081,10 +1823,10 @@ ${t.join(`,
1081
1823
 
1082
1824
  const { path, query } = getOperationParameterGroups(selected);
1083
1825
  const values = getParameterValues(selected);
1084
- const requestPath = buildRequestPath(selected, path, query, values);
1826
+ const requestPath = buildRequestPath(selected, path, query, values, getAuthQueryParams(selected));
1085
1827
  const bodyInput = document.getElementById("body-input");
1086
1828
  const body = bodyInput ? bodyInput.value.trim() : "";
1087
- const headers = getRequestHeadersObject();
1829
+ const headers = getRequestHeadersObject(selected);
1088
1830
  if (body && !hasHeaderName(headers, "Content-Type")) {
1089
1831
  headers["Content-Type"] = "application/json";
1090
1832
  }
@@ -1135,8 +1877,13 @@ ${t.join(`,
1135
1877
  }
1136
1878
  setResponseContent("", "", false);
1137
1879
 
1880
+ const deprecatedBanner = document.getElementById("deprecated-banner");
1881
+ if (deprecatedBanner) {
1882
+ deprecatedBanner.classList.toggle("hidden", !op.deprecated);
1883
+ }
1884
+
1138
1885
  document.getElementById("tag-title").textContent = selected.tag;
1139
- document.getElementById("tag-description").textContent = op.description || "Interactive API documentation.";
1886
+ document.getElementById("tag-description").innerHTML = op.description ? renderMarkdown(op.description) : "Interactive API documentation.";
1140
1887
  const methodNode = document.getElementById("endpoint-method");
1141
1888
  methodNode.textContent = selected.method;
1142
1889
  methodNode.className = "px-2.5 py-0.5 rounded-full text-xs font-mono font-medium " + (methodBadge[selected.method] || methodBadgeDefault);
@@ -1153,7 +1900,13 @@ ${t.join(`,
1153
1900
 
1154
1901
  html += renderRequestBodySchemaSection(reqSchema);
1155
1902
  html += renderResponseSchemasSection(op.responses);
1156
- 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();
1157
1910
  renderTryItParameterInputs(path, query);
1158
1911
  renderHeaderInputs();
1159
1912
  updateRequestPreview();
@@ -1164,6 +1917,24 @@ ${t.join(`,
1164
1917
  document.getElementById("copy-curl").addEventListener("click", async () => {
1165
1918
  try { await navigator.clipboard.writeText(document.getElementById("curl-code").textContent || ""); } catch {}
1166
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
+ });
1167
1938
  document.getElementById("sidebar-search").addEventListener("input", (event) => {
1168
1939
  sidebarSearchQuery = event.currentTarget.value || "";
1169
1940
  renderSidebar();
@@ -1189,7 +1960,7 @@ ${t.join(`,
1189
1960
  return;
1190
1961
  }
1191
1962
 
1192
- const requestPath = buildRequestPath(selected, path, query, values);
1963
+ const requestPath = buildRequestPath(selected, path, query, values, getAuthQueryParams(selected));
1193
1964
  formatBodyJsonInput();
1194
1965
  updateBodyJsonPresentation();
1195
1966
  const op = selected.operation || {};
@@ -1198,7 +1969,7 @@ ${t.join(`,
1198
1969
  const bodyInput = document.getElementById("body-input");
1199
1970
  const body =
1200
1971
  supportsBody && bodyInput ? bodyInput.value.trim() : "";
1201
- const headers = getRequestHeadersObject();
1972
+ const headers = getRequestHeadersObject(selected);
1202
1973
  if (body && !hasHeaderName(headers, "Content-Type")) {
1203
1974
  headers["Content-Type"] = "application/json";
1204
1975
  }
@@ -1206,7 +1977,13 @@ ${t.join(`,
1206
1977
  setSubmitLoading(true);
1207
1978
  try {
1208
1979
  const requestStart = performance.now();
1209
- 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
+ });
1210
1987
  const text = await response.text();
1211
1988
  const responseTimeMs = Math.round(performance.now() - requestStart);
1212
1989
  const contentType = response.headers.get("content-type") || "unknown";
@@ -1282,6 +2059,7 @@ ${t.join(`,
1282
2059
 
1283
2060
  document.getElementById("add-header-btn").addEventListener("click", () => {
1284
2061
  requestHeaders.push({ key: "", value: "" });
2062
+ saveHeaders();
1285
2063
  renderHeaderInputs();
1286
2064
  updateRequestPreview();
1287
2065
  });
@@ -1395,12 +2173,21 @@ ${t.join(`,
1395
2173
  setMobileSidebarOpen(false);
1396
2174
  });
1397
2175
  window.addEventListener("resize", () => {
2176
+ if (activeParamTooltipTrigger) {
2177
+ positionParamTooltip(activeParamTooltipTrigger);
2178
+ }
1398
2179
  if (window.innerWidth >= 768 && isMobileSidebarOpen) {
1399
2180
  setMobileSidebarOpen(false);
1400
2181
  }
1401
2182
  });
2183
+ window.addEventListener("scroll", () => {
2184
+ if (activeParamTooltipTrigger) {
2185
+ positionParamTooltip(activeParamTooltipTrigger);
2186
+ }
2187
+ }, true);
1402
2188
  document.addEventListener("keydown", (event) => {
1403
2189
  if (event.key === "Escape") {
2190
+ hideParamTooltip();
1404
2191
  if (isMobileSidebarOpen) {
1405
2192
  setMobileSidebarOpen(false);
1406
2193
  }
@@ -1425,9 +2212,446 @@ ${t.join(`,
1425
2212
  }
1426
2213
  });
1427
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
+
1428
2651
  setMobileSidebarOpen(false);
2652
+ renderAuthPanel();
1429
2653
  renderSidebar();
1430
2654
  renderEndpoint();
1431
2655
  </script>
1432
2656
  </body>
1433
- </html>`}function ye(e){let t=e?.["~standard"],n=t?.jsonSchema;return!!t&&typeof t==="object"&&t.version===1&&!!n&&typeof n.input==="function"&&typeof n.output==="function"}function ge(e){let t=0,n=[];return{openapiPath:e.split("/").map((r)=>{let a=/^:([A-Za-z0-9_]+)\+$/.exec(r);if(a?.[1])return n.push(a[1]),`{${a[1]}}`;let i=/^:([A-Za-z0-9_]+)$/.exec(r);if(i?.[1])return n.push(i[1]),`{${i[1]}}`;if(r==="*"){t+=1;let o=t===1?"wildcard":`wildcard${t}`;return n.push(o),`{${o}}`}return r}).join("/"),pathParamNames:n}}function Ve(e){return ge(e).openapiPath}function Fe(e,t){return`${e.toLowerCase()}_${t}`.replace(/[:{}]/g,"").replace(/[^A-Za-z0-9_]+/g,"_").replace(/^_+|_+$/g,"")||`${e.toLowerCase()}_operation`}function ze(e){let t=e.split("/").filter(Boolean);for(let n of t)if(!n.startsWith(":")&&n!=="*")return n.toLowerCase();return"default"}function Ge(e){return ge(e).pathParamNames}function Qe(e,t){let n=new Set((e.parameters||[]).filter((d)=>d.in==="path").map((d)=>String(d.name)));for(let d of Ge(t)){if(n.has(d))continue;(e.parameters||=[]).push({name:d,in:"path",required:!0,schema:{type:"string"}})}}function Ye(e){let t=Number(e);if(!Number.isInteger(t))return!1;return t>=100&&t<200||t===204||t===205||t===304}function Xe(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 We(e,t,n,d){if(!ye(t))return null;try{return t["~standard"].jsonSchema.input({target:n})}catch(r){d.push(`[OpenAPI] Failed input schema conversion for ${e}: ${r instanceof Error?r.message:String(r)}. Falling back to a permissive JSON Schema.`);let a=ve(t);return Ke(a)?null:a}}function he(e,t,n,d,r){if(!ye(n))return null;try{return n["~standard"].jsonSchema.output({target:d})}catch(a){return r.push(`[OpenAPI] Failed output schema conversion for ${e} (${t}): ${a instanceof Error?a.message:String(a)}. Falling back to a permissive JSON Schema.`),ve(n)}}function g(e){return!!e&&typeof e==="object"&&!Array.isArray(e)}function Ke(e){return g(e)&&Object.keys(e).length===0}function X(e){if(!e||typeof e!=="object")return null;let t=e;if(g(t._def))return t._def;if(g(t._zod)&&g(t._zod.def))return t._zod.def;return null}function xe(e){if(!e)return null;let t=e.typeName;if(typeof t==="string")return t;let n=e.type;if(typeof n==="string")return n;return null}function Y(e){let t=["innerType","schema","type","out","in","left","right"];for(let n of t)if(n in e)return e[n];return}function Ze(e,t){for(let n of t){let d=e[n];if(d&&typeof d==="object"&&!Array.isArray(d))return d}return}function qe(e){if(!e)return!1;let t=e.toLowerCase();return t.includes("optional")||t.includes("default")||t.includes("catch")}function et(e){let t=e,n=!1,d=0;while(d<8){d+=1;let r=X(t),a=xe(r);if(!r||!qe(a))break;n=!0;let i=Y(r);if(!i)break;t=i}return{schema:t,optional:n}}function tt(e){let t=e.shape;if(typeof t==="function")try{let n=t();return g(n)?n:{}}catch{return{}}return g(t)?t:{}}function nt(e){let t=e.toLowerCase();if(t.includes("string"))return{type:"string"};if(t.includes("number"))return{type:"number"};if(t.includes("boolean"))return{type:"boolean"};if(t.includes("bigint"))return{type:"string"};if(t.includes("null"))return{type:"null"};if(t.includes("any")||t.includes("unknown")||t.includes("never"))return{};if(t.includes("date"))return{type:"string",format:"date-time"};if(t.includes("custom"))return{type:"object",additionalProperties:!0};return null}function x(e,t=new WeakSet){if(!e||typeof e!=="object")return{};if(t.has(e))return{};t.add(e);let n=X(e),d=xe(n);if(!n||!d)return{};let r=nt(d);if(r)return r;let a=d.toLowerCase();if(a.includes("object")){let o=tt(n),s={},c=[];for(let[u,m]of Object.entries(o)){let h=et(m);if(s[u]=x(h.schema,t),!h.optional)c.push(u)}let l={type:"object",properties:s,additionalProperties:!0};if(c.length>0)l.required=c;return l}if(a.includes("array")){let o=Ze(n,["element","items","innerType","type"])??{};return{type:"array",items:x(o,t)}}if(a.includes("record")){let o=n.valueType??n.valueSchema;return{type:"object",additionalProperties:o?x(o,t):!0}}if(a.includes("tuple")){let s=(Array.isArray(n.items)?n.items:[]).map((c)=>x(c,t));return{type:"array",prefixItems:s,minItems:s.length,maxItems:s.length}}if(a.includes("union")){let o=n.options??n.schemas??[];if(!Array.isArray(o)||o.length===0)return{};return{anyOf:o.map((s)=>x(s,t))}}if(a.includes("intersection")){let{left:o,right:s}=n;if(!o||!s)return{};return{allOf:[x(o,t),x(s,t)]}}if(a.includes("enum")){let o=n.values;if(Array.isArray(o))return{enum:o};if(o&&typeof o==="object")return{enum:Object.values(o)};return{}}if(a.includes("literal")){let o=n.value;if(o===void 0)return{};let s=o===null?"null":typeof o;if(s==="string"||s==="number"||s==="boolean"||s==="null")return{type:s,const:o};return{const:o}}if(a.includes("nullable")){let o=Y(n);if(!o)return{};return{anyOf:[x(o,t),{type:"null"}]}}if(a.includes("lazy")){let o=n.getter;if(typeof o!=="function")return{};try{return x(o(),t)}catch{return{}}}let i=Y(n);if(i)return x(i,t);return{}}function ve(e){if(!X(e))return{};return x(e)}function dt(e,t){if(!g(t))return;if(t.type!=="object"||!g(t.properties)){e.requestBody={required:!0,content:{"application/json":{schema:t}}};return}let n=new Set(Array.isArray(t.required)?t.required:[]),d=t.properties,r=Array.isArray(e.parameters)?e.parameters:[],a=[{key:"params",in:"path"},{key:"query",in:"query"},{key:"headers",in:"header"},{key:"cookies",in:"cookie"}];for(let o of a){let s=d[o.key];if(!g(s))continue;if(s.type!=="object"||!g(s.properties))continue;let c=new Set(Array.isArray(s.required)?s.required:[]);for(let[l,u]of Object.entries(s.properties))r.push({name:l,in:o.in,required:o.in==="path"?!0:c.has(l),schema:g(u)?u:{}})}if(r.length>0){let o=new Map;for(let s of r)o.set(`${s.in}:${s.name}`,s);e.parameters=[...o.values()]}let i=d.body;if(i)e.requestBody={required:n.has("body"),content:{"application/json":{schema:g(i)?i:{}}}}}function rt(e,t,n,d,r){let a=n.output;if(!a){e.responses={200:{description:"OK"}};return}let i={};if(typeof a==="object"&&a!==null&&"~standard"in a){let o=he(t,"200",a,d,r);if(o)i["200"]={description:"OK",content:{"application/json":{schema:o}}};else i["200"]={description:"OK"}}else for(let[o,s]of Object.entries(a)){let c=String(o),l=he(t,c,s,d,r),u=Xe(c);if(l&&!Ye(c))i[c]={description:u,content:{"application/json":{schema:l}}};else i[c]={description:u}}if(Object.keys(i).length===0)i["200"]={description:"OK"};e.responses=i}function ke(e,t){let n=[],d={};for(let i of e){if(i.options.expose===!1)continue;if(!i.method||!i.path)continue;let o=i.method.toLowerCase();if(o==="options")continue;let s=Ve(i.path),c={operationId:Fe(o,s),tags:[i.options.schema?.tag||ze(i.path)]},l=We(i.path,i.options.schema?.input,t.target,n);if(l)dt(c,l);Qe(c,i.path),rt(c,i.path,i.options.schema||{},t.target,n),d[s]||={},d[s][o]=c}return{document:{openapi:t.target==="openapi-3.0"?"3.0.3":"3.1.0",info:{title:t.info?.title||"Vector API",version:t.info?.version||"1.0.0",...t.info?.description?{description:t.info.description}:{}},paths:d},warnings:n}}var W="/_vector/openapi/tailwindcdn.js",K="/_vector/openapi/logo_dark.svg",Z="/_vector/openapi/logo_white.svg",Ae="/_vector/openapi/favicon/apple-touch-icon.png",Ce="/_vector/openapi/favicon/favicon-32x32.png",De="/_vector/openapi/favicon/favicon-16x16.png",at="/_vector/openapi/favicon/favicon.ico",Ne="/_vector/openapi/favicon/site.webmanifest",ot="/_vector/openapi/favicon/android-chrome-192x192.png",it="/_vector/openapi/favicon/android-chrome-512x512.png",st=["../openapi/assets/tailwindcdn.js","../src/openapi/assets/tailwindcdn.js","../../src/openapi/assets/tailwindcdn.js"],lt=["../openapi/assets/logo_dark.svg","../src/openapi/assets/logo_dark.svg","../../src/openapi/assets/logo_dark.svg"],ct=["../openapi/assets/logo_white.svg","../src/openapi/assets/logo_white.svg","../../src/openapi/assets/logo_white.svg"],bt=["src/openapi/assets/tailwindcdn.js","openapi/assets/tailwindcdn.js","dist/openapi/assets/tailwindcdn.js"],ut=["src/openapi/assets/logo_dark.svg","openapi/assets/logo_dark.svg","dist/openapi/assets/logo_dark.svg"],mt=["src/openapi/assets/logo_white.svg","openapi/assets/logo_white.svg","dist/openapi/assets/logo_white.svg"],I=["../openapi/assets/favicon","../src/openapi/assets/favicon","../../src/openapi/assets/favicon"],L=["src/openapi/assets/favicon","openapi/assets/favicon","dist/openapi/assets/favicon"],ft="/* OpenAPI docs runtime asset missing: tailwind disabled */";function y(e,t){return e.map((n)=>`${n}/${t}`)}function k(e,t){for(let d of e)try{let r=new URL(d,import.meta.url);if(Ee(r))return Bun.file(r)}catch{}let n=process.cwd();for(let d of t){let r=j(n,d);if(Ee(r))return Bun.file(r)}return null}var we=k(st,bt),Be=k(lt,ut),Ie=k(ct,mt),pt=k(y(I,"apple-touch-icon.png"),y(L,"apple-touch-icon.png")),ht=k(y(I,"favicon-32x32.png"),y(L,"favicon-32x32.png")),yt=k(y(I,"favicon-16x16.png"),y(L,"favicon-16x16.png")),gt=k(y(I,"favicon.ico"),y(L,"favicon.ico")),xt=k(y(I,"site.webmanifest"),y(L,"site.webmanifest")),vt=k(y(I,"android-chrome-192x192.png"),y(L,"android-chrome-192x192.png")),kt=k(y(I,"android-chrome-512x512.png"),y(L,"android-chrome-512x512.png")),Le=[{path:Ae,file:pt,contentType:"image/png",filename:"apple-touch-icon.png"},{path:Ce,file:ht,contentType:"image/png",filename:"favicon-32x32.png"},{path:De,file:yt,contentType:"image/png",filename:"favicon-16x16.png"},{path:at,file:gt,contentType:"image/x-icon",filename:"favicon.ico"},{path:Ne,file:xt,contentType:"application/manifest+json; charset=utf-8",filename:"site.webmanifest"},{path:ot,file:vt,contentType:"image/png",filename:"android-chrome-192x192.png"},{path:it,file:kt,contentType:"image/png",filename:"android-chrome-512x512.png"}],q="public, max-age=0, must-revalidate",O="public, max-age=31536000, immutable",ee="no-store";function Et(e){return e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function wt(e){let t="^";for(let n of e){if(n==="*"){t+=".*";continue}t+=Et(n)}return t+="$",new RegExp(t)}function Bt(e,t){if(!t.includes("*"))return e===t;return wt(t).test(e)}class te{server=null;router;config;openapiConfig;openapiDocCache=null;openapiDocsHtmlCache=null;openapiWarningsLogged=!1;openapiTailwindMissingLogged=!1;openapiLogoDarkMissingLogged=!1;openapiLogoWhiteMissingLogged=!1;corsHandler=null;corsHeadersEntries=null;constructor(e,t){if(this.router=e,this.config=t,this.openapiConfig=this.normalizeOpenAPIConfig(t.openapi,t.development),t.cors){let n=this.normalizeCorsOptions(t.cors),{preflight:d,corsify:r}=fe(n);if(this.corsHandler={preflight:d,corsify:r},typeof n.origin==="string"&&(n.origin!=="*"||!n.credentials)){let i={"access-control-allow-origin":n.origin,"access-control-allow-methods":n.allowMethods,"access-control-allow-headers":n.allowHeaders,"access-control-expose-headers":n.exposeHeaders,"access-control-max-age":String(n.maxAge)};if(n.credentials)i["access-control-allow-credentials"]="true";this.corsHeadersEntries=Object.entries(i)}this.router.setCorsHeaders(this.corsHeadersEntries),this.router.setCorsHandler(this.corsHeadersEntries?null:this.corsHandler.corsify)}}normalizeOpenAPIConfig(e,t){let d=t!==!1&&!0;if(e===!1)return{enabled:!1,path:"/openapi.json",target:"openapi-3.0",docs:{enabled:!1,path:"/docs"}};if(e===!0)return{enabled:!0,path:"/openapi.json",target:"openapi-3.0",docs:{enabled:!1,path:"/docs"}};let r=e||{},a=r.docs,i=typeof a==="boolean"?{enabled:a,path:"/docs",exposePaths:void 0}:{enabled:a?.enabled===!0,path:a?.path||"/docs",exposePaths:Array.isArray(a?.exposePaths)?a.exposePaths.map((o)=>typeof o==="string"?o.trim():"").filter((o)=>o.length>0):void 0};return{enabled:r.enabled??d,path:r.path||"/openapi.json",target:r.target||"openapi-3.0",docs:i,info:r.info}}isDocsReservedPath(e){return e===this.openapiConfig.path||this.openapiConfig.docs.enabled&&e===this.openapiConfig.docs.path}getOpenAPIDocument(){if(this.openapiDocCache)return this.openapiDocCache;let e=this.router.getRouteDefinitions().filter((n)=>!this.isDocsReservedPath(n.path)),t=ke(e,{target:this.openapiConfig.target,info:this.openapiConfig.info});if(!this.openapiWarningsLogged&&t.warnings.length>0){for(let n of t.warnings)console.warn(n);this.openapiWarningsLogged=!0}return this.openapiDocCache=t.document,this.openapiDocCache}getOpenAPIDocumentForDocs(){let e=this.openapiConfig.docs.exposePaths,t=this.getOpenAPIDocument();if(!Array.isArray(e)||e.length===0)return t;let n=t.paths&&typeof t.paths==="object"&&!Array.isArray(t.paths)?t.paths:{},d={};for(let[r,a]of Object.entries(n))if(e.some((i)=>Bt(r,i)))d[r]=a;return{...t,paths:d}}getOpenAPIDocsHtmlCacheEntry(){if(this.openapiDocsHtmlCache)return this.openapiDocsHtmlCache;let e=pe(this.getOpenAPIDocumentForDocs(),this.openapiConfig.path,W,K,Z,Ae,Ce,De,Ne),t=Bun.gzipSync(e),n=`"${Bun.hash(e).toString(16)}"`;return this.openapiDocsHtmlCache={html:e,gzip:t,etag:n},this.openapiDocsHtmlCache}requestAcceptsGzip(e){let t=e.headers.get("accept-encoding");return Boolean(t&&/\bgzip\b/i.test(t))}validateReservedOpenAPIPaths(){if(!this.openapiConfig.enabled)return;let e=new Set([this.openapiConfig.path]);if(this.openapiConfig.docs.enabled){e.add(this.openapiConfig.docs.path),e.add(W),e.add(K),e.add(Z);for(let r of Le)e.add(r.path)}let t=this.router.getRouteDefinitions().filter((r)=>e.has(r.path)).map((r)=>`${r.method} ${r.path}`),n=Object.entries(this.router.getRouteTable()).filter(([r,a])=>e.has(r)&&a instanceof Response).map(([r])=>`STATIC ${r}`),d=[...t,...n];if(d.length>0)throw new Error(`OpenAPI reserved path conflict: ${d.join(", ")}. Change your route path(s) or reconfigure openapi.path/docs.path.`)}tryHandleOpenAPIRequest(e){if(!this.openapiConfig.enabled||e.method!=="GET")return null;let t=new URL(e.url).pathname;if(t===this.openapiConfig.path)return Response.json(this.getOpenAPIDocument());if(this.openapiConfig.docs.enabled&&t===this.openapiConfig.docs.path){let{html:n,gzip:d,etag:r}=this.getOpenAPIDocsHtmlCacheEntry();if(e.headers.get("if-none-match")===r)return new Response(null,{status:304,headers:{etag:r,"cache-control":q,vary:"accept-encoding"}});if(this.requestAcceptsGzip(e))return new Response(d,{status:200,headers:{"content-type":"text/html; charset=utf-8","content-encoding":"gzip",etag:r,"cache-control":q,vary:"accept-encoding"}});return new Response(n,{status:200,headers:{"content-type":"text/html; charset=utf-8",etag:r,"cache-control":q,vary:"accept-encoding"}})}if(this.openapiConfig.docs.enabled&&t===W){if(!we){if(!this.openapiTailwindMissingLogged)this.openapiTailwindMissingLogged=!0,console.warn('[OpenAPI] Missing docs runtime asset "tailwindcdn.js". Serving inline fallback script instead.');return new Response(ft,{status:200,headers:{"content-type":"application/javascript; charset=utf-8","cache-control":O}})}return new Response(we,{status:200,headers:{"content-type":"application/javascript; charset=utf-8","cache-control":O}})}if(this.openapiConfig.docs.enabled&&t===K){if(!Be){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":ee}})}return new Response(Be,{status:200,headers:{"content-type":"image/svg+xml; charset=utf-8","cache-control":O}})}if(this.openapiConfig.docs.enabled&&t===Z){if(!Ie){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":ee}})}return new Response(Ie,{status:200,headers:{"content-type":"image/svg+xml; charset=utf-8","cache-control":O}})}if(this.openapiConfig.docs.enabled){let n=Le.find((d)=>d.path===t);if(n){if(!n.file)return new Response(`OpenAPI docs runtime asset missing: ${n.filename}`,{status:404,headers:{"content-type":"text/plain; charset=utf-8","cache-control":ee}});return new Response(n.file,{status:200,headers:{"content-type":n.contentType,"cache-control":O}})}}return null}normalizeCorsOptions(e){return{origin:e.origin||"*",credentials:e.credentials!==!1,allowHeaders:Array.isArray(e.allowHeaders)?e.allowHeaders.join(", "):e.allowHeaders||"Content-Type, Authorization",allowMethods:Array.isArray(e.allowMethods)?e.allowMethods.join(", "):e.allowMethods||"GET, POST, PUT, PATCH, DELETE, OPTIONS",exposeHeaders:Array.isArray(e.exposeHeaders)?e.exposeHeaders.join(", "):e.exposeHeaders||"Authorization",maxAge:e.maxAge||86400}}applyCors(e,t){if(this.corsHeadersEntries){for(let[n,d]of this.corsHeadersEntries)e.headers.set(n,d);return e}if(this.corsHandler&&t)return this.corsHandler.corsify(e,t);return e}async start(){let e=this.config.port??3000,t=this.config.hostname||"localhost";this.validateReservedOpenAPIPaths();let n=async(d)=>{try{if(this.corsHandler&&d.method==="OPTIONS")return this.corsHandler.preflight(d);let r=this.tryHandleOpenAPIRequest(d);if(r)return this.applyCors(r,d);return this.applyCors(H.NOT_FOUND.clone(),d)}catch(r){return console.error("Server error:",r),this.applyCors(new Response("Internal Server Error",{status:500}),d)}};try{if(this.server=Bun.serve({port:e,hostname:t,reusePort:this.config.reusePort!==!1,routes:this.router.getRouteTable(),fetch:n,idleTimeout:this.config.idleTimeout??60,error:(d,r)=>{return console.error("[ERROR] Server error:",d),this.applyCors(new Response("Internal Server Error",{status:500}),r)}}),!this.server||!this.server.port)throw new Error(`Failed to start server on ${t}:${e} - server object is invalid`);return this.server}catch(d){if(d.code==="EADDRINUSE"||d.message?.includes("address already in use"))d.message=`Port ${e} is already in use`,d.port=e;else if(d.code==="EACCES"||d.message?.includes("permission denied"))d.message=`Permission denied to bind to port ${e}`,d.port=e;else if(d.message?.includes("EADDRNOTAVAIL"))d.message=`Cannot bind to hostname ${t}`,d.hostname=t;throw d}}stop(){if(this.server)this.server.stop(),this.server=null,this.openapiDocCache=null,this.openapiDocsHtmlCache=null,this.openapiWarningsLogged=!1,console.log("Server stopped")}getServer(){return this.server}getPort(){return this.server?.port??this.config.port??3000}getHostname(){return this.server?.hostname||this.config.hostname||"localhost"}getUrl(){let e=this.getPort();return`http://${this.getHostname()}:${e}`}}class A{static instance;router;server=null;middlewareManager;authManager;cacheManager;config={};routeScanner=null;routeGenerator=null;_protectedHandler=null;_cacheHandler=null;shutdownPromise=null;constructor(){this.middlewareManager=new R,this.authManager=new $,this.cacheManager=new J,this.router=new M(this.middlewareManager,this.authManager,this.cacheManager)}static getInstance(){if(!A.instance)A.instance=new A;return A.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 te(this.router,this.config),await this.server.start()}async discoverRoutes(){let e=this.config.routesDir||"./routes",t=this.config.routeExcludePatterns;if(this.routeScanner=new P(e,t),!this.routeGenerator)this.routeGenerator=new F;try{let n=await this.routeScanner.scan();if(n.length>0){if(this.config.development)await this.routeGenerator.generate(n);for(let d of n)try{let a=await import(U(d.path)),i=d.name==="default"?a.default:a[d.name];if(i){if(this.isRouteDefinition(i))this.router.route(i.options,i.handler),this.logRouteLoaded(i.options);else if(this.isRouteEntry(i))this.router.addRoute(i),this.logRouteLoaded(i);else if(typeof i==="function")this.router.route(d.options,i),this.logRouteLoaded(d.options)}}catch(r){console.error(`Failed to load route ${d.name} from ${d.path}:`,r)}}}catch(n){if(n.code!=="ENOENT"&&n.code!=="ENOTDIR")console.error("Failed to discover routes:",n)}}async loadRoute(e){if(typeof e==="function"){let t=e();if(this.isRouteEntry(t))this.router.addRoute(t)}else if(e&&typeof e==="object"){for(let[,t]of Object.entries(e))if(typeof t==="function"){let n=t();if(this.isRouteEntry(n))this.router.addRoute(n)}}}isRouteEntry(e){if(!Array.isArray(e)||e.length<3)return!1;let[t,n,d,r]=e;return typeof t==="string"&&n instanceof RegExp&&Array.isArray(d)&&d.length>0&&d.every((a)=>typeof a==="function")&&(r===void 0||typeof r==="string")}isRouteDefinition(e){return e!==null&&typeof e==="object"&&"entry"in e&&"options"in e&&"handler"in e&&typeof e.handler==="function"}logRouteLoaded(e){}stop(){if(this.server)this.server.stop(),this.server=null}async shutdown(){if(this.shutdownPromise)return this.shutdownPromise;this.shutdownPromise=(async()=>{if(this.stop(),typeof this.config.shutdown==="function")await this.config.shutdown()})();try{await this.shutdownPromise}finally{this.shutdownPromise=null}}getServer(){return this.server}getRouter(){return this.router}getCacheManager(){return this.cacheManager}getAuthManager(){return this.authManager}static resetInstance(){A.instance=null}}var ne=A.getInstance;function It(e,t){return{entry:{method:e.method.toUpperCase(),path:e.path},options:e,handler:t}}function Lt(e){let t=e??null;try{return JSON.stringify(t)}catch(n){if(n instanceof TypeError&&/\bbigint\b/i.test(n.message))return JSON.stringify(t,(d,r)=>typeof r==="bigint"?r.toString():r);throw n}}function b(e,t,n){let d={error:!0,message:t,statusCode:e,timestamp:new Date().toISOString()};return N(e,d,n)}var w={badRequest:(e="Bad Request",t)=>b(E.BAD_REQUEST,e,t),unauthorized:(e="Unauthorized",t)=>b(E.UNAUTHORIZED,e,t),paymentRequired:(e="Payment Required",t)=>b(402,e,t),forbidden:(e="Forbidden",t)=>b(E.FORBIDDEN,e,t),notFound:(e="Not Found",t)=>b(E.NOT_FOUND,e,t),methodNotAllowed:(e="Method Not Allowed",t)=>b(405,e,t),notAcceptable:(e="Not Acceptable",t)=>b(406,e,t),requestTimeout:(e="Request Timeout",t)=>b(408,e,t),conflict:(e="Conflict",t)=>b(E.CONFLICT,e,t),gone:(e="Gone",t)=>b(410,e,t),lengthRequired:(e="Length Required",t)=>b(411,e,t),preconditionFailed:(e="Precondition Failed",t)=>b(412,e,t),payloadTooLarge:(e="Payload Too Large",t)=>b(413,e,t),uriTooLong:(e="URI Too Long",t)=>b(414,e,t),unsupportedMediaType:(e="Unsupported Media Type",t)=>b(415,e,t),rangeNotSatisfiable:(e="Range Not Satisfiable",t)=>b(416,e,t),expectationFailed:(e="Expectation Failed",t)=>b(417,e,t),imATeapot:(e="I'm a teapot",t)=>b(418,e,t),misdirectedRequest:(e="Misdirected Request",t)=>b(421,e,t),unprocessableEntity:(e="Unprocessable Entity",t)=>b(E.UNPROCESSABLE_ENTITY,e,t),locked:(e="Locked",t)=>b(423,e,t),failedDependency:(e="Failed Dependency",t)=>b(424,e,t),tooEarly:(e="Too Early",t)=>b(425,e,t),upgradeRequired:(e="Upgrade Required",t)=>b(426,e,t),preconditionRequired:(e="Precondition Required",t)=>b(428,e,t),tooManyRequests:(e="Too Many Requests",t)=>b(429,e,t),requestHeaderFieldsTooLarge:(e="Request Header Fields Too Large",t)=>b(431,e,t),unavailableForLegalReasons:(e="Unavailable For Legal Reasons",t)=>b(451,e,t),internalServerError:(e="Internal Server Error",t)=>b(E.INTERNAL_SERVER_ERROR,e,t),notImplemented:(e="Not Implemented",t)=>b(501,e,t),badGateway:(e="Bad Gateway",t)=>b(502,e,t),serviceUnavailable:(e="Service Unavailable",t)=>b(503,e,t),gatewayTimeout:(e="Gateway Timeout",t)=>b(504,e,t),httpVersionNotSupported:(e="HTTP Version Not Supported",t)=>b(505,e,t),variantAlsoNegotiates:(e="Variant Also Negotiates",t)=>b(506,e,t),insufficientStorage:(e="Insufficient Storage",t)=>b(507,e,t),loopDetected:(e="Loop Detected",t)=>b(508,e,t),notExtended:(e="Not Extended",t)=>b(510,e,t),networkAuthenticationRequired:(e="Network Authentication Required",t)=>b(511,e,t),invalidArgument:(e="Invalid Argument",t)=>b(E.UNPROCESSABLE_ENTITY,e,t),rateLimitExceeded:(e="Rate Limit Exceeded",t)=>b(429,e,t),maintenance:(e="Service Under Maintenance",t)=>b(503,e,t),custom:(e,t,n)=>b(e,t,n)};function N(e,t,n=_.JSON){let d=n===_.JSON?Lt(t):t;return new Response(d,{status:e,headers:{"content-type":n}})}var{existsSync:At}=(()=>({}));class de{configPath;config=null;configSource="default";constructor(e){let t=e||"vector.config.ts";this.configPath=V(t)?t:B(process.cwd(),t)}async load(){if(At(this.configPath))try{let t=await import(U(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 Ct(e={}){let t=new de(e.configPath),n=await t.load(),d=t.getConfigSource(),r={...n};if(e.mutateConfig)r=await e.mutateConfig(r,{configSource:d});if(e.config)r={...r,...e.config};if(e.autoDiscover!==void 0)r.autoDiscover=e.autoDiscover;let a=ne(),i=e.protectedHandler!==void 0?e.protectedHandler:await t.loadAuthHandler(),o=e.cacheHandler!==void 0?e.cacheHandler:await t.loadCacheHandler();a.setProtectedHandler(i??null),a.setCacheHandler(o??null);let s=await a.startServer(r),c={...r,port:s.port??r.port??C.PORT,hostname:s.hostname||r.hostname||C.HOSTNAME,reusePort:r.reusePort!==!1,idleTimeout:r.idleTimeout??60};return{server:s,config:c,stop:()=>a.stop(),shutdown:()=>a.shutdown()}}export{Ct as startVector,It as route,N as createResponse,w 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};