mcp-scraper 0.95.2 → 0.96.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (121) hide show
  1. package/CHANGELOG.md +67 -1
  2. package/README.md +21 -3
  3. package/dist/actions-R4EJDLRO.js +1 -0
  4. package/dist/artifacts-4ZDNP2JW.js +1 -0
  5. package/dist/artifacts-N62OPIT5.js +1 -0
  6. package/dist/artifacts-PSADD5OC.js +1 -0
  7. package/dist/artifacts-RUR3OHAK.js +1 -0
  8. package/dist/bin/api-server.js +1 -1
  9. package/dist/bin/mcp-scraper-cli.js +22 -22
  10. package/dist/bin/mcp-scraper-core.js +1 -1
  11. package/dist/bin/mcp-scraper-install.js +1 -1
  12. package/dist/bin/mcp-stdio-server.js +1 -1
  13. package/dist/bin/paa-harvest.js +1 -1
  14. package/dist/blob-store-GIH26EDO.js +1 -0
  15. package/dist/bundle-FCXZMIRB.js +1 -0
  16. package/dist/chunk-24YDQ3EO.js +5 -0
  17. package/dist/chunk-3F7AFM53.js +1 -0
  18. package/dist/chunk-4HZXATHB.js +27 -0
  19. package/dist/chunk-55ZANTHL.js +3 -0
  20. package/dist/chunk-5BKSKLHX.js +1 -0
  21. package/dist/chunk-5LYINW7Z.js +8 -0
  22. package/dist/chunk-63VWBMYR.js +3 -0
  23. package/dist/chunk-6BD75VKS.js +218 -0
  24. package/dist/chunk-6N5EC7ZO.js +1 -0
  25. package/dist/chunk-7POHNTVW.js +1 -0
  26. package/dist/chunk-7SR7MEU5.js +62 -0
  27. package/dist/chunk-7WPCGRD7.js +182 -0
  28. package/dist/chunk-B3JRL45T.js +1 -0
  29. package/dist/chunk-B4ZKPLSP.js +1 -0
  30. package/dist/chunk-BPKTUCV7.js +12 -0
  31. package/dist/chunk-C7MGJUTU.js +1 -0
  32. package/dist/{chunk-W2BVJ7S2.js → chunk-CNSVZTTT.js} +4 -4
  33. package/dist/chunk-CORWWDHL.js +1 -0
  34. package/dist/chunk-CVQUHVHX.js +1 -0
  35. package/dist/chunk-FB4KBB5W.js +16 -0
  36. package/dist/{chunk-Y3Q4FIKK.js → chunk-H6MODA7W.js} +199 -84
  37. package/dist/chunk-HCK6PLM3.js +3 -0
  38. package/dist/chunk-HNNYXMSI.js +1 -0
  39. package/dist/chunk-HUNSEGUN.js +57 -0
  40. package/dist/{chunk-MC4W6TZT.js → chunk-HVQZRQRJ.js} +41 -8
  41. package/dist/chunk-IFPION5D.js +121 -0
  42. package/dist/chunk-IY6ZUUY7.js +173 -0
  43. package/dist/chunk-JHT6A4U6.js +11 -0
  44. package/dist/chunk-JMZIDHYQ.js +2 -0
  45. package/dist/chunk-KXJCGV3H.js +1 -0
  46. package/dist/chunk-MVMWPKRC.js +2 -0
  47. package/dist/chunk-NALXKTUU.js +1 -0
  48. package/dist/chunk-NNOX3FYG.js +198 -0
  49. package/dist/chunk-OILOHQNL.js +2 -0
  50. package/dist/chunk-OLYPLX5C.js +1 -0
  51. package/dist/chunk-QER2ELZP.js +1 -0
  52. package/dist/chunk-RDHGQ2WZ.js +1 -0
  53. package/dist/chunk-RIHI3KH7.js +955 -0
  54. package/dist/chunk-RN4VG3VH.js +4 -0
  55. package/dist/chunk-RYX4FJVH.js +1 -0
  56. package/dist/chunk-SDQW7IJN.js +1 -0
  57. package/dist/{chunk-ENZUJEIM.js → chunk-SE4VKLEC.js} +1 -1
  58. package/dist/chunk-SEZETSB3.js +1 -0
  59. package/dist/chunk-SFUOSJ3A.js +159 -0
  60. package/dist/chunk-UIOSADPB.js +1718 -0
  61. package/dist/{chunk-ZH75KWBI.js → chunk-UNEJYZ4T.js} +1 -1
  62. package/dist/chunk-UXNR3K6I.js +1 -0
  63. package/dist/{chunk-VREXSMC6.js → chunk-VVSHZV5S.js} +5 -5
  64. package/dist/chunk-WNUXMPVX.js +1 -0
  65. package/dist/chunk-WP3QS4CJ.js +1 -0
  66. package/dist/chunk-ZTMQEDIB.js +41 -0
  67. package/dist/contracts-GUXGFCVV.js +1 -0
  68. package/dist/core-schema-423BSTE6.js +936 -0
  69. package/dist/dispatch-P7IY75LH.js +1 -0
  70. package/dist/index.cjs +103 -213
  71. package/dist/index.d.cts +184 -169
  72. package/dist/index.d.ts +184 -169
  73. package/dist/index.js +1 -1
  74. package/dist/media-artifacts-67CJWI7O.js +1 -0
  75. package/dist/metering-ZH2P62IC.js +1 -0
  76. package/dist/migrations-3AKEC5QE.js +1 -0
  77. package/dist/queue-AC4XKD6Z.js +1 -0
  78. package/dist/reconciliation-UZUZ6B74.js +1 -0
  79. package/dist/report-artifact-offload-6OOY2PTM.js +1 -0
  80. package/dist/repository-4EC5EXVN.js +1 -0
  81. package/dist/{location-data-repository-A2QZVP7O.js → repository-CYXVMYAI.js} +1 -1
  82. package/dist/server-DXZ27KQO.js +5825 -0
  83. package/dist/settlement-6CS4JZTY.js +1 -0
  84. package/dist/worker-ATRD6VKM.js +1 -0
  85. package/package.json +2 -2
  86. package/dist/analytics-repository-DZZKDZL6.js +0 -1
  87. package/dist/chunk-6DRKDSXY.js +0 -182
  88. package/dist/chunk-6ND5AFV5.js +0 -27
  89. package/dist/chunk-7XDBGQDY.js +0 -6
  90. package/dist/chunk-7YOXSMHG.js +0 -1565
  91. package/dist/chunk-BLVBUMH5.js +0 -21
  92. package/dist/chunk-EDQ57S4P.js +0 -1
  93. package/dist/chunk-GLTECY3U.js +0 -1282
  94. package/dist/chunk-GPSPSJBJ.js +0 -1
  95. package/dist/chunk-HE45FFBU.js +0 -1
  96. package/dist/chunk-HUV2WTRW.js +0 -1
  97. package/dist/chunk-IXJQHXDC.js +0 -2595
  98. package/dist/chunk-K3D2S36Q.js +0 -16
  99. package/dist/chunk-KFOFU3LA.js +0 -1
  100. package/dist/chunk-LMWU7VPZ.js +0 -63
  101. package/dist/chunk-O4LUUIYG.js +0 -4
  102. package/dist/chunk-OLSW4AN4.js +0 -19
  103. package/dist/chunk-RLFCJGHA.js +0 -100
  104. package/dist/chunk-T4VTJNDZ.js +0 -84
  105. package/dist/chunk-TMB56NCA.js +0 -1
  106. package/dist/chunk-VXOXB3IB.js +0 -1
  107. package/dist/chunk-WO3N5FH2.js +0 -5
  108. package/dist/chunk-WO46LTBW.js +0 -1
  109. package/dist/chunk-XPEJB4BZ.js +0 -1
  110. package/dist/db-CDEZHBRN.js +0 -1
  111. package/dist/extract-bundle-SXC6EWJR.js +0 -26
  112. package/dist/gmail-service-EWR76XE7.js +0 -1
  113. package/dist/lead-list-enrichment-repository-SIWGXWQV.js +0 -1
  114. package/dist/operation-metering-UJ53YX7S.js +0 -1
  115. package/dist/server-QVEKDIDQ.js +0 -5014
  116. package/dist/site-extract-repository-23ND4N77.js +0 -1
  117. package/dist/stripe-event-worker-LPXTITVC.js +0 -1
  118. package/dist/worker-EDN2TJH3.js +0 -1
  119. /package/dist/{chunk-YGBTTW5D.js → chunk-2IATUJO6.js} +0 -0
  120. /package/dist/{chunk-6DTXIZY2.js → chunk-4ZVO6GX4.js} +0 -0
  121. /package/dist/{chunk-XG6GCEUE.js → chunk-U4WIJZCX.js} +0 -0
@@ -0,0 +1,4 @@
1
+ import{$ as E,B as R,D as S,La as C,Ma as P,Y as v,_ as h,ha as T,ja as w,ka as _,la as y,x as u,y as f,z as g}from"./chunk-RIHI3KH7.js";import{a as x}from"./chunk-FB4KBB5W.js";import{a as c}from"./chunk-CVQUHVHX.js";import{readFileSync as L}from"fs";import{homedir as B}from"os";import{join as U}from"path";import{serveStdio as Y}from"@modelcontextprotocol/server/stdio";import{McpServer as J}from"@modelcontextprotocol/server";var I=new Map(_.map(r=>[r.upstreamName,r.id]));function N(r){let s=r.split(`
2
+ `).filter(t=>t.startsWith("data:")).map(t=>t.slice(5).trim()).filter(Boolean);if(!s.length)return JSON.parse(r);for(let t of s){let e=JSON.parse(t);if(e.result||e.error)return e}throw new Error("hosted MCP returned no JSON-RPC result")}function l(r){return{content:[{type:"text",text:JSON.stringify({ok:!1,error:r})}],isError:!0}}var p=class{baseUrl;apiKey;constructor(s,t){this.baseUrl=s.replace(/\/$/,""),this.apiKey=t}async callMemoryTool(s,t){let e=I.get(s);if(!e)return l(`unknown memory tool: ${s}`);try{let n=await fetch(`${this.baseUrl}/mcp`,{method:"POST",headers:{"content-type":"application/json",accept:"application/json, text/event-stream","x-api-key":this.apiKey},body:JSON.stringify({jsonrpc:"2.0",id:`memory:${e}`,method:"tools/call",params:{name:e,arguments:t}})}),i=await n.text();if(!n.ok)return l(`hosted memory ${e} failed (HTTP ${n.status})`);let o=N(i);return o.error?l(o.error.message??`hosted memory ${e} failed`):o.result??l(`hosted memory ${e} returned no result`)}catch(n){return l(n instanceof Error?n.message:`hosted memory ${e} call failed`)}}};function M(r,s){if(s.length===0)throw new Error("Restricted MCP tool allowlist must contain at least one tool name");let t=new Set;for(let o of s){if(typeof o!="string"||o.trim()!==o||o.length===0)throw new Error("Restricted MCP tool allowlist contains a malformed tool name");if(t.has(o))throw new Error(`Restricted MCP tool allowlist contains duplicate tool name: ${o}`);t.add(o)}let e=new Set,n=r,i=n.registerTool.bind(r);return n.registerTool=(o,a,m)=>{if(t.has(o))return e.add(o),i(o,a,m)},{assertComplete(){let o=[...t].filter(a=>!e.has(a));if(o.length>0)throw new Error(`Restricted MCP tool allowlist contains unknown or unavailable tool names: ${o.join(", ")}`)},registeredToolNames(){return[...e]}}}import{Client as b,StreamableHTTPClientTransport as k}from"@modelcontextprotocol/client";var $=new Set(["artifact_read","artifact_describe","artifact_download","report_artifact_read"]),A=()=>({content:[{type:"text",text:"Retained file storage is unavailable. Preserve the artifactId and retry retrieval; do not repeat acquisition."}],isError:!0});function O(r,s,t={}){return async(e,n)=>{if(!$.has(e))return A();let i=new b({name:"mcp-scraper-artifact-client",version:c},{versionNegotiation:{mode:"auto"}}),o=AbortSignal.timeout(3e4);try{let a=new k(new URL(`${r.replace(/\/$/,"")}/mcp`),{requestInit:{signal:o,headers:{Authorization:`Bearer ${s}`,"x-api-key":s,...t.localNetworkAccess?{"x-mcp-scraper-local-network":"1"}:{}}}});return await i.connect(a,{signal:o,timeout:3e4}),await i.callTool({name:e,arguments:n},{signal:o,timeout:3e4})}catch{return A()}finally{await i.close().catch(()=>{})}}}var G=new Set(["paa","serp","browser-agent","scheduled-results","memory"]);function K(){let s=[process.env.MCP_SCRAPER_KEY_PATH?.trim(),U(B(),".mcp-scraper-key")].filter(Boolean);for(let t of s)try{let e=L(t,"utf8").trim();if(e)return e}catch{}}function j(r,s={}){let t=s.toolsets??G,e=process.env.MCP_SCRAPER_BASE_URL?.trim()||process.env.MCP_BASE_URL?.trim()||"https://mcpscraper.dev",n=R(),i=S({deploymentProfile:n,transportProfile:"stdio",baseUrl:e,explicitlyEnabled:process.env.MCP_SCRAPER_ALLOW_PRIVATE_NETWORK==="1"}),o=process.env.BROWSER_AGENT_CONSOLE_URL?.trim()||e,a=new J({name:"mcp-scraper",version:c},{instructions:f,cacheHints:{"server/discover":{ttlMs:3e5,cacheScope:"private"},"tools/list":{ttlMs:3e5,cacheScope:"private"},"prompts/list":{ttlMs:3e5,cacheScope:"private"},"resources/list":{ttlMs:3e5,cacheScope:"private"},"resources/templates/list":{ttlMs:3e5,cacheScope:"private"},"resources/read":{ttlMs:6e4,cacheScope:"private"}}});g(a);let m=s.allowedToolNames?M(a,s.allowedToolNames):void 0,d=s.httpExecutor??new T(e,r,{localNetworkAccess:i,analyticsIdentity:()=>E(a.server.getClientVersion()?.name)});return t.has("paa")&&h(a,d,{ownerId:v(r),deploymentProfile:n,transportProfile:"stdio",baseUrl:e,localNetworkAccess:i,taskHandleSecret:r,remoteArtifactAccess:O(e,r,{localNetworkAccess:i})}),t.has("serp")&&u(a,d,{exposeDevelopmentDiagnostics:n==="development"||n==="test"}),t.has("browser-agent")&&w(a,{baseUrl:e,apiKey:r,consoleBaseUrl:o}),t.has("scheduled-results")&&P(a,new C(e,r)),t.has("memory")&&y(a,new p(e,r)),m?.assertComplete(),a}function Re(r={}){let s=process.argv.includes("--stdio")||process.env.MCP_SCRAPER_FORCE_STDIO==="1",t=!!(process.stdin.isTTY&&process.stdout.isTTY),e=process.argv.includes("--help")||process.argv.includes("-h");if(!s&&(t||e)){let i=process.argv.includes("--no-color")||process.env.NO_COLOR!==void 0||process.env.FORCE_COLOR==="0"||!process.stdout.isTTY;process.stdout.write(x({version:c,color:!i,apiKeyConfigured:!!process.env.MCP_SCRAPER_API_KEY?.trim()})),process.exit(0)}let n=(process.env.MCP_SCRAPER_API_KEY??process.env.MCP_SCRAPER_KEY??process.env.MCP_API_KEY??K())?.trim();n||(process.stderr.write(`MCP_SCRAPER_API_KEY env var or ~/.mcp-scraper-key is required
3
+ `),process.exit(1)),Y(()=>j(n,r),{legacy:"serve",onerror(i){process.stderr.write(`${i.message}
4
+ `)}})}export{Re as a};
@@ -0,0 +1 @@
1
+ import{c as j}from"./chunk-BPKTUCV7.js";import{k as X}from"./chunk-ZTMQEDIB.js";import{c as A,d as $,g as b,h as C,n as K,o as U,p as G,q as M,r as D,s as W,y as q,z as F}from"./chunk-7WPCGRD7.js";import{a as B,b as L,c as H}from"./chunk-QER2ELZP.js";import{b as k,c as S,d as y,e as x,f as O,g as I,h,i as m,k as E,o as N}from"./chunk-HUNSEGUN.js";import{h as v,i as z}from"./chunk-C7MGJUTU.js";import{a as d,b as J,c as T,d as R}from"./chunk-HNNYXMSI.js";import{randomUUID as oe}from"crypto";import{createHash as Q,randomUUID as V}from"crypto";function _(e,i=new Set){if(e===null||typeof e=="string"||typeof e=="boolean"||typeof e=="number"&&Number.isFinite(e))return e;if(typeof e!="object"||!e)throw new d("Operation inputs must be finite JSON data");if(i.has(e))throw new d("Operation inputs cannot be cyclic");if(!Array.isArray(e)&&![Object.prototype,null].includes(Object.getPrototypeOf(e)))throw new d("Operation inputs must be plain JSON data");i.add(e);try{return Array.isArray(e)?e.map(t=>_(t,i)):Object.fromEntries(Object.keys(e).sort().map(t=>[t,_(e[t],i)]))}finally{i.delete(e)}}async function P(e){if(!Number.isSafeInteger(e.userId)||e.userId<=0)throw new d("Authenticated operation principal is required");if(e.jobId!=null&&(!e.jobId.trim()||e.jobId.length>512))throw new d("Operation job ID is invalid");let i=e.tool.trim();if(!i||i.length>100)throw new d("Operation tool is required and bounded");if(e.idempotencyKey!=null&&(!e.idempotencyKey.trim()||e.idempotencyKey.length>512))throw new d("Operation idempotency key is invalid");let t=e.leaseMs??3e5;if(!Number.isSafeInteger(t)||t<1e3||t>36e5)throw new d("Execution lease must be between one second and one hour");let n=JSON.stringify(_(e.normalizedInput));if(Buffer.byteLength(n)>64*1024)throw new d("Operation inputs exceed 64 KiB");let r=e.idempotencyKey?.trim()??V();return E({userId:e.userId,ownerScope:`user:${e.userId}`,tool:i,jobId:e.jobId??null,normalizedFlags:e.normalizedInput,idempotencyKey:r,requestFingerprint:Q("sha256").update(n).digest("hex")},V(),t,e.storeGate)}async function Y(e){let i=JSON.stringify(_(e.normalizedInput));if(!Number.isSafeInteger(e.userId)||e.userId<=0||Buffer.byteLength(i)>64*1024)throw new d("Invalid operation receipt principal/input");let{readOperationIntentResult:t}=await import("./repository-4EC5EXVN.js"),{operationIdentityHash:n}=await import("./contracts-GUXGFCVV.js");return t(e.userId,n(`user:${e.userId}\0${e.tool}\0${e.idempotencyKey}`),Q("sha256").update(i).digest("hex"))}async function we(e){let i=Date.now()+27e4,t=e.idempotencyKey?.trim()??oe();if(!t||t.length>512)return{status:400,body:{error_code:"invalid_request",message:"Idempotency-Key must contain 1 to 512 characters"}};let n=(a,c,p)=>({...a,body:{...a.body,operation:{runId:c,idempotencyKey:t,state:p}}}),r=(a,c,p)=>n({status:c==="pending"?202:503,headers:{"Retry-After":"2"},body:{...v({errorCode:"response_lost",retryable:!0,chargeStatus:p,details:{retry_guidance:"Retry the identical request with the returned idempotencyKey. Pending work is not started again; a saved response replays. Unknown work permits compensation only."}}),message:c==="pending"?"This operation is still running. Retry with the same idempotencyKey.":"The execution outcome is unknown. Retry with the same idempotencyKey for result or compensation recovery."}},a,c),s;try{s=await P({...e,idempotencyKey:t,leaseMs:3e5})}catch(a){return a instanceof d?n({status:400,body:{error_code:"invalid_request",message:a.message,retryable:!1}},null,"not_started"):a instanceof J?n({status:409,body:{error_code:"idempotency_conflict",message:a.message,retryable:!1}},null,"conflict"):r(null,"unknown")}let o=s.kind==="claimed"?s.claim.runId:s.runId;if(s.kind==="replay"){let a=JSON.parse(s.result.json);return!a||typeof a.status!="number"||!a.body||typeof a.body!="object"?r(o,"unknown"):n(a,o,"replayed")}if(s.kind==="pending")return r(o,"pending");if(s.kind==="unknown")try{let a=await y(o,e.userId);if(!a)return r(o,"unknown");let c=await e.recover(a);if(c.recover)return await h(a),n(c.reply,o,"unknown");let p=n(c.reply,o,"recovered_unknown"),l={json:JSON.stringify(p),status:"unknown"};return await O(a,l)?p:r(o,"unknown")}catch{return r(o,"unknown","refund_pending")}if(s.kind!=="claimed")return r(o,"unknown");let u=s.claim,f;try{if(f=await e.prepare(),f.rejection)return await I(u),n(f.rejection,o,"not_started");if(!await k(u))return r(o,"unknown");let a={claim:u,deadlineAt:i,assertActive:async()=>{if(B(i),!await m(u))throw Error("Execution ownership is no longer current")}},c;try{c=await e.execute(a,f.value)}catch{return await h(u),r(o,"unknown","refund_pending")}if(c.recover)return await h(u),n(c.reply,o,"unknown");let p=n(c.reply,o,c.reply.status<400?"succeeded":"failed");try{return await x(u,{json:JSON.stringify(p),status:p.status<400?"succeeded":"failed"})?p:r(o,"unknown")}catch{return await h(u).catch(()=>{}),r(o,"unknown")}}catch{return await I(u).catch(()=>{}),r(o,"unknown")}finally{await f?.release().catch(()=>{})}}var g=3e5;function ee(e){if(!e?.trim()||e.length>512)throw new d("A bounded framework workflow ID is required");return T(`workflow:${e}`)}async function ye(e){if(!Number.isSafeInteger(e.userId)||e.userId<=0)throw new d("Workflow principal is required");let i=ee(e.workflowId),t=await E(e,i,g);if(t.kind==="claimed"){let n;try{n=await k(t.claim)}catch(r){if(!await m(t.claim))throw r;n=!0}if(!n)throw Error("workflow_execution_start_unknown");return t}if(t.kind==="pending"){let n={runId:t.runId,userId:e.userId,token:i};if(await m(n)&&await S(n,g))return{kind:"claimed",claim:n}}return t}var te=e=>`${e.workflow.runId}:${e.phase}`;async function he(e){if(!await S(e.workflow,g))throw Error("workflow_execution_not_current");let i=te(e),t=await P({userId:e.workflow.userId,tool:e.tool,jobId:e.jobId,normalizedInput:e.normalizedInput,idempotencyKey:i,leaseMs:g});if(t.kind==="replay"){if(t.result.status!=="succeeded")throw Error(`operation_phase_unknown:${t.runId}`);return JSON.parse(t.result.json)}if(t.kind!=="claimed")throw Error(`operation_phase_${t.kind}:${t.runId}`);let n=t.claim;try{await e.prepare()}catch(r){throw await I(n).catch(()=>{}),r}try{let r;try{r=await k(n)}catch(a){if(!await m(n))throw a;r=!0}if(!r)throw Error("operation_phase_start_unknown");let s=Date.now()+g,o=async()=>{if(Date.now()>=s)throw new L(e.phase);if(!await m(e.workflow)||!await m(n))throw Error("operation_phase_claim_not_current")};await o();let u=await H(s,()=>e.execute({claim:n,deadlineAt:s,assertActive:o}),e.phase);await o();let f=JSON.stringify(u);if(f==null||!await x(n,{status:"succeeded",json:f}))throw Error("operation_phase_publication_unknown");return u}catch(r){await h(n).catch(()=>{});let s=await y(n.runId,n.userId).catch(()=>null);throw s&&await O(s,{status:"unknown",json:JSON.stringify({phase:e.phase,outcome:"unknown"})}).catch(()=>{}),r}}async function be(e,i){let t=await Y({userId:e.workflow.userId,tool:e.tool,idempotencyKey:te(e),normalizedInput:e.normalizedInput});if(!t||t.result.status!=="succeeded"||R({value:JSON.parse(t.result.json)})!==R({value:i}))throw Error("operation_phase_cache_receipt_unknown")}async function ge(e,i,t){let n={runId:e,userId:i,token:ee(t)};if(await m(n))return{claim:n,recovery:!1};let r=await y(e,i);return r?{claim:r,recovery:!0}:null}async function re(e,i,t){let n={json:JSON.stringify(i),status:e.recovery?"unknown":t};if(!(e.recovery?await O(e.claim,n,e.settlementGate):await x(e.claim,n)))throw Error("workflow_result_publication_unknown")}async function je(e){if(!await b(e))return{kind:"missing",body:{error:"job not found"}};let t=await M(e);if(!t)return{kind:"conflict",body:{error:"Only failed or expired recovery jobs can be re-finalized.",status:(await b(e))?.status??"missing"}};let n=t.executionGeneration;if(!await D(e,n))return{kind:"conflict",body:{error:"job state changed during re-finalization claim"}};let r;try{r=await X(t,{})}catch(l){throw await F(e,l instanceof Error?l.message:String(l),void 0,n).catch(()=>!1),l}let s=A(t),o=$(t,s.creditTruncated),u=o==="failed"?`No pages were extracted successfully (${t.failedUrls} failed, ${t.remainingUrls} remaining).`:o==="partial"?`${t.successfulUrls} pages succeeded; ${t.failedUrls} failed and ${t.remainingUrls} remain.${s.creditTruncated?` Credit availability limited this request from ${s.requestedMaxPages} to ${s.effectiveMaxPages} pages.`:""}`:null,f;try{f=await q(e,r,o,u,!1,null,n)}catch(l){let w=await b(e).catch(()=>null);if(!w||w.id!==e||w.executionGeneration!==n||w.status!==o||JSON.stringify(w.artifacts)!==JSON.stringify(r)||w.error!==(u?z(u).slice(0,2e3):null)||w.publicError!==null)throw l;f=!0}if(!f)return{kind:"conflict",body:{error:"job state changed during re-finalization"}};let a=await b(e);if(!a||a.executionGeneration!==n||a.status!==o)return{kind:"conflict",body:{error:"job state changed before re-finalization settlement"}};let c="already_settled_or_refunded";if(a.billedMc==null&&a.userId!=null){let l=await j(a);if(!l)throw Error("extract_settlement_acknowledgment_unknown");c=`settled: billed ${l.netChargeMc} mc, refunded ${l.refundMc} mc${l.expiredRefundMc?`, expired refund ${l.expiredRefundMc} mc`:""}`}let p=r.find(l=>l.contentType==="application/zip"||l.filename?.endsWith(".zip"));return{kind:"complete",body:{ok:!0,jobId:e,artifacts:r.length,settlement:c,bundleUrl:p?.url??null,bundleBytes:p?.bytes??null}}}async function Pe(e=25){let i=await U(e);for(let r of i)await G(r.id).catch(()=>!1);let t=await C(e),n={checked:new Set([...i,...t].map(r=>r.id)).size,settled:0,failed:0};for(let r of t){if(r.userId==null){await W(r.id,"Settlement abandoned because the legacy job has no user owner.",r.executionGeneration??0),n.failed+=1;continue}try{if(!await j(r))throw Error("extract_settlement_acknowledgment_unknown");if(r.executionGeneration===0&&await N(`extract-site:${r.id}`,r.userId)){let o=await y(`extract-site:${r.id}`,r.userId);o&&await re({claim:o,recovery:!0},{jobId:r.id,status:r.status,artifacts:r.artifacts??[]},"unknown")}n.settled+=1}catch(s){n.failed+=1;let o=s instanceof Error?s.message:String(s);await K(r.id,o,r.executionGeneration??0).catch(()=>{}),console.warn("[site-extract/reconcile]",r.id,o)}}return n}export{we as a,g as b,ee as c,ye as d,he as e,be as f,ge as g,re as h,je as i,Pe as j};
@@ -0,0 +1 @@
1
+ import{createHash as w}from"crypto";import{createReadStream as R}from"fs";import{createHash as A}from"crypto";var g=/--v1-([a-f0-9]{64})(?:\.[a-zA-Z0-9]{1,16})?$/,m=class extends Error{constructor(e,n,a){super(`private_artifact_storage_${n}`,{cause:a});this.artifactId=e;this.outcome=n}artifactId;outcome;name="ArtifactStorageError"},d=class extends Error{constructor(e,n){super(n);this.code=e}code;name="ArtifactReadError"};function P(t){let r=t.toLowerCase().split(";")[0].trim(),e=["download"],n=t.match(/;\s*charset\s*=\s*"?([^;"\s]+)/i)?.[1]?.toLowerCase();return(n===void 0||n==="utf-8"||n==="utf8")&&(r.startsWith("text/")||["application/json","application/x-ndjson","application/ndjson","application/xml","application/javascript","message/rfc822"].includes(r)||r.endsWith("+json")||r.endsWith("+xml"))&&e.push("text"),r==="application/zip"&&e.push("archive"),r.startsWith("image/")&&e.push("image"),r.startsWith("audio/")&&e.push("audio"),r.startsWith("video/")&&e.push("video"),e}function _(t){return(t.trim().replace(/[^a-zA-Z0-9_.-]+/g,"-").replace(/^-+|-+$/g,"")||"artifact").slice(0,160)}function T(t){let r=t.replace(/^\/+/,"").replace(/\/+$/,"");if(!r||r.includes("..")||!/^[a-zA-Z0-9/_-]+$/.test(r))throw new Error("private artifact prefix is invalid");return`${r}/`}function x(t,r){let e=t.trim();if(!/^[a-zA-Z0-9_-]{1,160}$/.test(e)||e==="_metadata")throw new Error(`${r} must contain only letters, numbers, underscores, or hyphens`);return e}function B(t){let r=t.trim();if(!/^[a-zA-Z0-9_.-]{1,600}$/.test(r)||r.includes(".."))throw new Error("private artifact key is invalid");return r}function O(t,r){let e=T(r);if(!t.startsWith(e))return null;let n=t.slice(e.length).split("/");if(n.length<2)return null;try{let a=x(n[0],"ownerId");return n.slice(1,-1).forEach(s=>x(s,"scope")),B(n.at(-1)),/^\d{13}-/.test(n.at(-1))?a:null}catch{return null}}function S(t){let r=t.split("/").at(-1)?.match(/^(\d{13})-/),e=r?Number(r[1]):NaN;return Number.isSafeInteger(e)&&e>0?e:null}function M(t,r,e,n){if(r>n||t.length&&(t[0]&192)===128)throw new d("invalid_offset","private artifact offset falls inside a UTF-8 character or exceeds content");let a=Math.min(e,t.length);for(;a>0&&a<t.length&&(t[a]&192)===128;)a--;if(a===0&&r<n)throw new d("window_too_small","private artifact maxBytes is too small for the next UTF-8 character");let s;try{s=new TextDecoder("utf-8",{fatal:!0,ignoreBOM:!0}).decode(t.subarray(0,a))}catch{throw new d("invalid_utf8","private artifact is not valid UTF-8 text")}return{text:s,consumedBytes:a,nextOffset:r+a<n?r+a:null}}function N(t){return A("sha256").update(JSON.stringify(t)).digest("hex")}function U(t,r){let e=t;if(!e||e.version!==1||e.artifactId!==r||r.match(g)?.[1]!==e.fingerprint||!/^[a-f0-9]{64}$/.test(e.sha256)||!Number.isSafeInteger(e.bytes)||e.bytes<0||typeof e.filename!="string"||_(e.filename)!==e.filename||typeof e.contentType!="string"||!Number.isFinite(Date.parse(e.createdAt))||!Number.isFinite(Date.parse(e.expiresAt)))return!1;let{artifactId:n,fingerprint:a,...s}=e;return N(s)===a&&JSON.stringify(e.capabilities)===JSON.stringify(P(e.contentType))&&Date.parse(e.createdAt)===S(r)}function I(t,r){return`${r}_metadata/${t.slice(r.length)}.json`}async function k(t,r){let e=t.getReader(),n=[],a=0;try{for(;;){let{done:s,value:i}=await e.read();if(s)break;if(a+=i.byteLength,a>r)throw new d("read_limit","private artifact exceeds read limit");n.push(Buffer.from(i))}return Buffer.concat(n,a)}finally{await e.cancel().catch(()=>{}),e.releaseLock()}}async function y(t,r,e){let n=r.backend?null:await import("@vercel/blob"),a=r.backend?await r.backend.get(t,e):await n.get(t,{access:"private",token:r.token,useCache:!1,...e?{headers:{Range:`bytes=${e.start}-${e.end}`}}:{}});if(!a||"statusCode"in a&&a.statusCode!==200)return null;if(a.blob?.pathname!==t)throw await a.stream.cancel().catch(()=>{}),new d("integrity_mismatch","private artifact returned a different object identity");if(e){let i=a.headers?.get("content-range")?.match(/^bytes (\d+)-(\d+)\/(\d+)$/);if(!i||i.slice(1).some(c=>!Number.isSafeInteger(Number(c)))||Number(i[1])!==e.start||Number(i[2])>e.end||Number(i[2])<e.start||Number(i[3])<=Number(i[2]))throw await a.stream.cancel().catch(()=>{}),new d("range_unavailable","private artifact backend did not acknowledge the requested bounded range");return{...a,totalBytes:Number(i[3]),rangeBytes:Number(i[2])-e.start+1}}let s=a.blob.size;if(!r.backend&&(!Number.isSafeInteger(s)||s<0||s===0&&a.headers.get("content-length")!=="0"))try{let i=await n.head(t,{token:r.token});if(i.pathname!==t||!Number.isSafeInteger(i.size)||i.size<0)throw new d("integrity_mismatch","private artifact length metadata is invalid");s=i.size}catch(i){throw await a.stream.cancel().catch(()=>{}),i}return{...a,blob:{...a.blob,size:s},totalBytes:s,rangeBytes:s}}async function F(t){let r=R(t.file);try{if((t.policy.backend?await t.policy.backend.put({id:t.id,body:r,bytes:t.bytes,sha256:t.sha256,contentType:t.contentType}):await(await import("@vercel/blob")).put(t.id,r,{access:"private",token:t.policy.token,contentType:t.contentType,addRandomSuffix:!1,allowOverwrite:!1,cacheControlMaxAge:60,multipart:t.bytes>104857600})).pathname!==t.id)throw new Error("private artifact put returned a different object identity")}catch(e){r.destroy();try{let n=await y(t.id,t.policy);if(!n)throw e;if(n.totalBytes!==t.bytes||n.blob.contentType.split(";")[0]!==t.contentType.split(";")[0])throw await n.stream.cancel().catch(()=>{}),e;let a=n.stream.getReader(),s=w("sha256"),i=0;try{for(;;){let c=await a.read();if(c.done)break;if(i+=c.value.byteLength,i>t.bytes)throw e;s.update(c.value)}}finally{await a.cancel().catch(()=>{}),a.releaseLock()}if(i!==t.bytes||s.digest("hex")!==t.sha256)throw e}catch{throw new m(t.id,"unknown",e)}}finally{r.destroy()}}async function W(t,r,e,n){try{if((e.backend?await e.backend.put({id:t,body:Buffer.from(r),bytes:Buffer.byteLength(r),sha256:w("sha256").update(r).digest("hex"),contentType:"application/json"}):await(await import("@vercel/blob")).put(t,r,{access:"private",token:e.token,contentType:"application/json",addRandomSuffix:!1,allowOverwrite:!1,cacheControlMaxAge:60})).pathname!==t)throw new Error("private artifact metadata put returned a different identity")}catch(a){try{let s=await y(t,e);if(!s||(await k(s.stream,8192)).toString()!==r)throw a}catch{throw new m(n,"bytes-stored-metadata-pending",a)}}}async function L(t,r,e){if(e.backend){let u=await e.backend.sign(t,r);if(!u.startsWith("https://"))throw Error("private artifact download URL must use HTTPS");return u}let{getDownloadUrl:n,issueSignedToken:a,presignUrl:s}=await import("@vercel/blob"),i=await a({token:e.token,pathname:t,operations:["get"],validUntil:r}),c=await s(i,{access:"private",operation:"get",pathname:t,validUntil:r});if(!c.presignedUrl.startsWith("https://"))throw new Error("private artifact download URL must use HTTPS");return n(c.presignedUrl)}async function D(t,r,e){let n=t.backend?o=>t.backend.list(o.prefix,o.cursor,o.limit):(await import("@vercel/blob")).list,a=t.backend?o=>t.backend.delete(Array.isArray(o)?o:[o]):(await import("@vercel/blob")).del,s=t.backend?.kind??"private-vercel-blob",i=`${t.prefix}_cleanup/cursor.json`,c,u=0,h=0,f=!1,v=await y(i,t);if(v)try{let o=JSON.parse((await k(v.stream,8192)).toString());o.version===1&&o.prefix===t.prefix&&typeof o.cursor=="string"&&o.cursor.length>0&&o.cursor.length<=4096&&(c=o.cursor)}catch{return{deleted:0,store:s,pending:!0}}do{let o=await n({prefix:t.prefix,token:t.token,limit:Math.min(1e3,e-u),cursor:c});u+=o.blobs.length;let p=[];for(let l of o.blobs)await r(l.pathname)&&p.push(l.pathname);if(p.length)try{await a(p,{token:t.token}),h+=p.length;let l=p.filter(b=>g.test(b)).map(b=>I(b,t.prefix));l.length&&await a(l,{token:t.token})}catch{return{deleted:h,store:s,pending:!0}}if(f=o.hasMore,!f){if(c)try{await a(i,{token:t.token})}catch{f=!0}break}if(!o.cursor||o.cursor===c){f=!0;break}if(c=o.cursor,u>=e){try{if(c.length>4096)throw Error("private artifact cleanup cursor exceeds limit");let l=JSON.stringify({version:1,prefix:t.prefix,cursor:c});if((t.backend?await t.backend.put({id:i,body:Buffer.from(l),bytes:Buffer.byteLength(l),sha256:w("sha256").update(l).digest("hex"),contentType:"application/json",overwrite:!0}):await(await import("@vercel/blob")).put(i,l,{access:"private",token:t.token,contentType:"application/json",addRandomSuffix:!1,allowOverwrite:!0,cacheControlMaxAge:0})).pathname!==i)throw Error("private artifact cleanup cursor identity mismatch")}catch{f=!0}break}}while(!0);return{deleted:h,store:s,pending:f}}export{g as a,m as b,d as c,P as d,_ as e,T as f,x as g,B as h,O as i,S as j,M as k,N as l,U as m,I as n,k as o,y as p,F as q,W as r,L as s,D as t};
@@ -1,4 +1,4 @@
1
- import{k as K}from"./chunk-OLSW4AN4.js";import{a as X}from"./chunk-T4VTJNDZ.js";import{c as J,d as H}from"./chunk-HUV2WTRW.js";import{t as f}from"./chunk-7YOXSMHG.js";import{createHash as U,createHmac as re,timingSafeEqual as he}from"crypto";import{createHash as fe,randomUUID as Y}from"crypto";var ge=1440*60*1e3,F=5e3,h=class extends Error{constructor(n,i,o=400){super(i);this.code=n;this.status=o;this.name="GmailSelectionError"}code;status},k=null,P=null;function $(e){return e===null||typeof e!="object"?JSON.stringify(e):Array.isArray(e)?`[${e.map($).join(",")}]`:`{${Object.entries(e).sort(([t],[n])=>t.localeCompare(n)).map(([t,n])=>`${JSON.stringify(t)}:${$(n)}`).join(",")}}`}function b(e){return fe("sha256").update($(e)).digest("hex")}async function x(){let e=f();return k&&P===e||(P=e,k=(async()=>{await e.execute(`
1
+ import{S as K}from"./chunk-SFUOSJ3A.js";import{a as X}from"./chunk-NALXKTUU.js";import{h as J,i as H}from"./chunk-RDHGQ2WZ.js";import{a as f}from"./chunk-WNUXMPVX.js";import{createHash as U,createHmac as re,timingSafeEqual as he}from"crypto";import{createHash as fe,randomUUID as Y}from"crypto";var ge=1440*60*1e3,F=5e3,h=class extends Error{constructor(n,i,o=400){super(i);this.code=n;this.status=o;this.name="GmailSelectionError"}code;status},k=null,P=null;function $(e){return e===null||typeof e!="object"?JSON.stringify(e):Array.isArray(e)?`[${e.map($).join(",")}]`:`{${Object.entries(e).sort(([t],[n])=>t.localeCompare(n)).map(([t,n])=>`${JSON.stringify(t)}:${$(n)}`).join(",")}}`}function b(e){return fe("sha256").update($(e)).digest("hex")}async function x(){let e=f();return k&&P===e||(P=e,k=(async()=>{await e.execute(`
2
2
  CREATE TABLE IF NOT EXISTS gmail_selections (
3
3
  selection_id TEXT PRIMARY KEY,
4
4
  owner_identity TEXT NOT NULL,
@@ -0,0 +1 @@
1
+ import{a as T,b as K,c as u,d as F,e as Z,f as q,g as J,h as G,i as h,j as Q,k as tt,l as et,m as B,n as C,o as R,p as k,q as at,r as it,s as z}from"./chunk-SDQW7IJN.js";import{c as O}from"./chunk-OILOHQNL.js";import{opendir as rt,readFile as nt,rm as X,stat as ut}from"fs/promises";import{join as b}from"path";var kt=7*864e5,Mt=15*6e4,$="9999-12-31T23:59:59.999Z";function g(e){if(e.artifactTtlMs!==null&&(!Number.isSafeInteger(e.artifactTtlMs)||e.artifactTtlMs<=0))throw new Error("private artifact TTL must be a positive integer");if(!Number.isSafeInteger(e.downloadTtlMs)||e.downloadTtlMs<=0)throw new Error("private artifact download TTL must be a positive integer");return{...e,token:e.token?.trim()||null,prefix:q(e.prefix)}}function N(e,t){let a=g(t);if(h(e,a.prefix)===null||a.artifactTtlMs===null)return null;let i=Q(e);return i===null?null:new Date(i+a.artifactTtlMs)}function D(e,t,a,i=Date.now()){let r=h(e,t.prefix);if(!r||a!==void 0&&r!==a)return!1;let n=N(e,t);return t.artifactTtlMs===null||n!==null&&n.getTime()>i}function E(e){return e.hosted??(process.env.VERCEL==="1"||process.env.NODE_ENV==="production")}function Y(e,t,a=Date.now()){let i=Math.min(a+t.downloadTtlMs,Date.parse(e));return i>a?i:null}async function Ft(e){let t=g(e.policy),a=(e.now??new Date).getTime(),i=e.maxObjects??1e3;if(!Number.isSafeInteger(i)||i<1||i>2e4||!Number.isFinite(a))throw new Error("private artifact cleanup budget/time is invalid");let r=d=>e.includeLegacy===!0&&D(d,t,void 0,a)===!1&&h(d,t.prefix)!==null,n=(d,m)=>B(d,m)&&h(m,t.prefix)===d.ownerId&&Date.parse(d.expiresAt)<=a,o=d=>T.test(d)&&h(d,t.prefix)!==null&&(N(d,t)?.getTime()??1/0)<=a;if(t.artifactTtlMs===null)return{deleted:0,store:t.backend?.kind??(t.token?"private-vercel-blob":E(t)?"none":"local"),pending:!1};if(t.backend||t.token?.trim()){let{cleanupPrivateBlobObjects:d,getPrivateBlob:m,metadataBlobId:v,consumePrivateBlob:c}=await import("./blob-store-GIH26EDO.js");return d(t,async s=>{if(s.startsWith(`${t.prefix}_metadata/`)&&s.endsWith(".json")){let y=`${t.prefix}${s.slice(`${t.prefix}_metadata/`.length,-5)}`;if(!o(y))return!1;let _=await m(s,t);if(!_)return!1;try{return n(JSON.parse((await c(_.stream,8192)).toString()),y)}catch{return!1}}if(!h(s,t.prefix))return!1;if(!T.test(s))return r(s);if(!o(s))return!1;let f=await m(v(s,t.prefix),t);if(!f)return o(s);try{return n(JSON.parse((await c(f.stream,8192)).toString()),s)}catch{return!1}},i)}if(E(t))return{deleted:0,store:"none",pending:!0};let l=O(t.localBaseDir),w=0,x=0,p=!1;async function I(d,m=""){let v=await rt(d).catch(c=>{if(c.code==="ENOENT")return null;throw c});if(v)for await(let c of v){let s=m?`${m}/${c.name}`:c.name;if(c.isDirectory())await I(b(d,c.name),s);else if(c.isFile()){let f=`${t.prefix}${s}`;if(!o(f)&&!r(f))continue;if(w>=i){p=!0;return}if(w++,T.test(f)){let y=await nt(b(l,"artifact-metadata",`${f}.json`),"utf8").catch(()=>null);if(y){let _;try{_=JSON.parse(y)}catch{p=!0;continue}if(!n(_,f)){(!B(_,f)||h(f,t.prefix)!==_.ownerId)&&(p=!0);continue}}}else if(!r(f))continue;try{await X(b(l,"blobs",f)),x++,await X(b(l,"artifact-metadata",`${f}.json`),{force:!0})}catch{p=!0}}}}await I(b(l,"blobs",t.prefix));async function P(d,m=""){let v=await rt(d).catch(c=>{if(c.code==="ENOENT")return null;throw c});if(v)for await(let c of v){let s=m?`${m}/${c.name}`:c.name;if(c.isDirectory())await P(b(d,c.name),s);else if(c.isFile()&&s.endsWith(".json")){let f=`${t.prefix}${s.slice(0,-5)}`;if(!o(f)||await ut(b(l,"blobs",f)).then(()=>!0,y=>{if(y.code==="ENOENT")return!1;throw y}))continue;if(w>=i){p=!0;return}w++;try{let y=JSON.parse(await nt(b(d,c.name),"utf8"));if(!n(y,f)){(!B(y,f)||h(f,t.prefix)!==y.ownerId)&&(p=!0);continue}await X(b(d,c.name)),x++}catch{p=!0}}}}return await P(b(l,"artifact-metadata",t.prefix)),{deleted:x,store:"local",pending:p}}import{createHash as H}from"crypto";import{constants as A,createWriteStream as mt}from"fs";import{link as ot,mkdir as V,mkdtemp as pt,open as M,readFile as wt,rm as yt,writeFile as ht}from"fs/promises";import{tmpdir as vt}from"os";import{dirname as ct,join as S}from"path";import{Readable as xt,Transform as bt}from"stream";import{pipeline as At}from"stream/promises";var L=T,Pt=1e5,Et=e=>H("sha256").update(e).digest("hex"),U=(e,t)=>S(O(e.localBaseDir),"blobs",t),st=(e,t)=>S(O(e.localBaseDir),"artifact-metadata",`${t}.json`);function It(e){let t=typeof e=="string"&&/^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}$/.test(e)?`${e.replace(" ","T")}Z`:e,a=t instanceof Date?t.getTime():typeof t=="number"?t:Date.parse(t);if(!Number.isSafeInteger(a)||a<1e12||a>9999999999999)throw new Error("private artifact createdAt is invalid");return a}function _t(e,t,a){let i=e;if(!B(i,t)||!t.startsWith(`${a.prefix}${i.ownerId}/`)||i.expiresAt!==(N(t,a)?.toISOString()??$))throw new u("integrity_mismatch","private artifact metadata does not match its identity/policy");return i}async function j(e,t){if(!L.test(e))return null;let a;if(t.backend||t.token?.trim()){let i=await k(C(e,t.prefix),t);if(!i)return null;a=await R(i.stream,8192)}else{if(E(t))return null;let i=await M(st(t,e),A.O_RDONLY|A.O_NOFOLLOW).catch(r=>{if(r.code==="ENOENT")return null;throw r});if(!i)return null;try{let r=await i.stat();if(!r.isFile()||r.size>8192)throw new u("integrity_mismatch","private artifact metadata exceeds limit");a=await i.readFile()}finally{await i.close()}}try{return _t(JSON.parse(a.toString("utf8")),e,t)}catch(i){throw i instanceof u?i:new u("integrity_mismatch","private artifact metadata is not valid JSON")}}async function ft(e,t){if(Date.parse(e.expiresAt)<=Date.now())return{downloadUrl:null,downloadUrlExpiresAt:null,downloadState:"unavailable"};if(t.backend?.localPath)return{downloadUrl:null,downloadUrlExpiresAt:null,downloadState:"local"};if(!(t.backend||t.token?.trim()))return{downloadUrl:null,downloadUrlExpiresAt:null,downloadState:E(t)?"unavailable":"local"};let a=Y(e.expiresAt,t);if(!a)return{downloadUrl:null,downloadUrlExpiresAt:null,downloadState:"unavailable"};try{return{downloadUrl:await z(e.artifactId,a,t),downloadUrlExpiresAt:new Date(a).toISOString(),downloadState:"available"}}catch{return{downloadUrl:null,downloadUrlExpiresAt:null,downloadState:"unavailable"}}}async function gt(e,t,a,i){let r=U(a,t.artifactId),n=st(a,t.artifactId),o=JSON.stringify(t);await V(ct(r),{recursive:!0}),await V(ct(n),{recursive:!0});let l=S(i,"metadata.json");await ht(l,o,{flag:"wx",mode:384});try{await ot(l,n)}catch(w){if(w.code!=="EEXIST")throw w;if(await wt(n,"utf8")!==o)throw new u("integrity_mismatch","private artifact metadata collision")}try{await ot(e,r)}catch(w){if(w.code!=="EEXIST")throw w;let x=H("sha256"),p=0,I=await M(r,A.O_RDONLY|A.O_NOFOLLOW);try{for await(let P of I.createReadStream()){if(p+=P.length,p>t.bytes)throw new u("integrity_mismatch","private artifact data collision");x.update(P)}if(p!==t.bytes||x.digest("hex")!==t.sha256)throw new u("integrity_mismatch","private artifact data collision")}finally{await I.close()}}}async function Kt(e){return St({...e,content:xt.from([Buffer.isBuffer(e.content)?e.content:Buffer.from(e.content)])})}async function St(e){let t=g(e.policy),a=J(e.ownerId,"ownerId"),i=G(e.artifactKey);if(i.length>400)throw new Error("private artifact key is too long");let r=(e.scopeSegments??[]).map(m=>J(m,"scopeSegments")),n=It(e.createdAt),o=Z(e.filename),l=e.contentType.trim().toLowerCase();if(l.length>256||!/^[a-z0-9!#$&^_.+-]+\/[a-z0-9!#$&^_.+-]+(?:;[\x20-\x7e]+)?$/.test(l))throw new Error("private artifact contentType is invalid");if(!(t.backend||t.token?.trim())&&E(t))throw new Error("private_artifact_blob_not_configured");let w=!(t.backend||t.token?.trim())||t.localBaseDir?S(O(t.localBaseDir),".artifact-staging"):S(vt(),"mcp-private-artifacts");await V(w,{recursive:!0,mode:448});let x=await pt(S(w,"write-")),p=S(x,"bytes"),I=H("sha256"),P=0,d=new bt({transform(m,v,c){P+=m.length,I.update(m),c(null,m)}});try{await At(e.content,d,mt(p,{flags:"wx",mode:384}));let m={version:1,ownerId:a,filename:o,contentType:l,bytes:P,sha256:I.digest("hex"),createdAt:new Date(n).toISOString(),expiresAt:t.artifactTtlMs===null?$:new Date(n+t.artifactTtlMs).toISOString(),capabilities:F(l)},v=o.match(/\.([a-zA-Z0-9]{1,16})$/)?.[1],c=et(m),s=`${t.prefix}${a}/${r.length?r.join("/")+"/":""}${n}-${i}--v1-${c}${v?"."+v:""}`;if(h(s,t.prefix)!==a)throw new Error("private artifact identity is invalid");let f={...m,artifactId:s,fingerprint:c};if(t.backend||t.token?.trim())await at({id:s,file:p,bytes:P,sha256:f.sha256,contentType:l,policy:t}),await it(C(s,t.prefix),JSON.stringify(f),t,s);else try{await gt(p,f,t,x)}catch(W){throw W instanceof u?W:new K(s,"unknown",W)}let{version:y,fingerprint:_,...dt}=f;return{...dt,...await ft(f,t)}}finally{await yt(x,{recursive:!0,force:!0})}}async function lt(e,t){if(t.backend||t.token?.trim()){let i=await k(e.artifactId,t);return i?(await i.stream.cancel().catch(()=>{}),i.totalBytes===e.bytes):!1}if(E(t))return!1;let a=await M(U(t,e.artifactId),A.O_RDONLY|A.O_NOFOLLOW).catch(i=>{if(i.code==="ENOENT")return null;throw i});if(!a)return!1;try{let i=await a.stat();return i.isFile()&&i.size===e.bytes}finally{await a.close()}}async function Zt(e){let t=g(e.policy);if(!D(e.artifactId,t,e.ownerId))return null;let a=await j(e.artifactId,t);if(!a||!await lt(a,t))return null;let{version:i,fingerprint:r,...n}=a;return{...n,...await ft(a,t)}}async function qt(e){let t=g(e.policy);if(!D(e.artifactId,t,e.ownerId)||!(t.backend||t.token?.trim()))return null;let a=await j(e.artifactId,t);if(L.test(e.artifactId)&&(!a||!await lt(a,t)))return null;let i=a?.expiresAt??N(e.artifactId,t)?.toISOString()??$,r=Y(i,t);return r?{downloadUrl:await z(e.artifactId,r,t),downloadUrlExpiresAt:new Date(r).toISOString(),expiresAt:i}:null}function Ot(e){let t=e.split(".").at(-1)?.toLowerCase();return{txt:"text/plain",md:"text/markdown",html:"text/html",csv:"text/csv",json:"application/json",jsonl:"application/x-ndjson",xml:"application/xml",eml:"message/rfc822"}[t??""]??"application/octet-stream"}async function Gt(e){let t=g(e.policy);if(!D(e.artifactId,t,e.ownerId))return null;if(!Number.isSafeInteger(e.offset)||e.offset<0)throw new u("invalid_offset","private artifact offset is invalid");if(!Number.isSafeInteger(e.maxBytes)||e.maxBytes<1||e.maxBytes>Pt||!Number.isSafeInteger(e.offset+e.maxBytes+1))throw new Error("private artifact maxBytes is invalid");let a=await j(e.artifactId,t);if(L.test(e.artifactId)&&!a)return null;let i=a?.contentType??Ot(e.artifactId),r,n;if(a&&!a.capabilities.includes("text"))throw new u("unsupported_text","private artifact does not support text reads; use its download/archive/media capability");if(t.backend||t.token?.trim()){if(a&&e.offset>a.bytes)throw new u("invalid_offset","private artifact offset exceeds content");if(a&&e.offset===a.bytes)return{text:"",totalBytes:a.bytes,offset:e.offset,consumedBytes:0,nextOffset:null,contentType:i,sha256:a.sha256};let o=await k(e.artifactId,t,{start:e.offset,end:e.offset+e.maxBytes});if(!o)return null;if(i=o.blob.contentType,n=o.totalBytes,!F(i).includes("text")||a&&n!==a.bytes)throw await o.stream.cancel().catch(()=>{}),new u(a&&n!==a.bytes?"integrity_mismatch":"unsupported_text","private artifact range metadata/capability is invalid");if(r=await R(o.stream,e.maxBytes+1),r.length!==o.rangeBytes)throw new u("integrity_mismatch","private artifact range body is incomplete")}else{if(E(t))return null;if(!F(i).includes("text"))throw new u("unsupported_text","private artifact does not support text reads; use its download/archive/media capability");let o=await M(U(t,e.artifactId),A.O_RDONLY|A.O_NOFOLLOW).catch(l=>{if(l.code==="ENOENT")return null;throw l});if(!o)return null;try{let l=await o.stat();if(n=l.size,!l.isFile()||a&&a.bytes!==n)throw new u("integrity_mismatch","private artifact bytes do not match metadata");if(e.offset>n)throw new u("invalid_offset","private artifact offset exceeds content");r=Buffer.alloc(Math.min(e.maxBytes+1,n-e.offset));let{bytesRead:w}=await o.read(r,0,r.length,e.offset);r=r.subarray(0,w)}finally{await o.close()}}return{...tt(r,e.offset,e.maxBytes,n),totalBytes:n,offset:e.offset,contentType:i,sha256:a?.sha256??null}}async function Qt(e){let t=g(e.policy);if(!D(e.artifactId,t,e.ownerId))return null;if(!Number.isSafeInteger(e.maxBytes)||e.maxBytes<1)throw new Error("private artifact maxBytes is invalid");let a=await j(e.artifactId,t);if(L.test(e.artifactId)&&!a)return null;let i;if(t.backend||t.token?.trim()){let r=await k(e.artifactId,t);if(!r)return null;if(a&&r.totalBytes!==a.bytes||r.totalBytes>e.maxBytes)throw await r.stream.cancel().catch(()=>{}),new u("read_limit","private artifact exceeds read limit or metadata size");i=await R(r.stream,e.maxBytes)}else{if(E(t))return null;let r=await M(U(t,e.artifactId),A.O_RDONLY|A.O_NOFOLLOW).catch(n=>{if(n.code==="ENOENT")return null;throw n});if(!r)return null;try{let n=await r.stat();if(!n.isFile()||a&&n.size!==a.bytes)throw new u("integrity_mismatch","private artifact bytes do not match metadata");if(n.size>e.maxBytes)throw new u("read_limit","private artifact exceeds read limit");i=Buffer.alloc(n.size);let o=0;for(;o<i.length;){let{bytesRead:l}=await r.read(i,o,i.length-o,o);if(!l)break;o+=l}if(o!==i.length)throw new u("integrity_mismatch","private artifact bytes changed during read")}finally{await r.close()}}if(a&&(i.length!==a.bytes||Et(i)!==a.sha256))throw new u("integrity_mismatch","private artifact digest mismatch");return i}export{kt as a,Mt as b,N as c,Ft as d,Kt as e,St as f,Zt as g,qt as h,Gt as i,Qt as j};
@@ -0,0 +1,159 @@
1
+ import{a as M,b as q,f as L}from"./chunk-6BD75VKS.js";import{o as b,r as J,s as pe,t as _e,u as H,w as ge}from"./chunk-CORWWDHL.js";import{f as I,h as F}from"./chunk-5LYINW7Z.js";import{g as j}from"./chunk-VVSHZV5S.js";import{b as $}from"./chunk-4ZVO6GX4.js";import{a as l}from"./chunk-WNUXMPVX.js";import{createHash as O,randomUUID as Oe}from"crypto";import{Client as tt,StreamableHTTPClientTransport as nt}from"@modelcontextprotocol/client";import{randomUUID as Q}from"crypto";import{createHash as Y,randomBytes as W,scryptSync as fe,timingSafeEqual as We}from"crypto";function Ee(){return"sk_"+W(24).toString("hex")}function ye(e){let t=W(16).toString("hex"),n=fe(e,t,64);return`${t}:${n.toString("hex")}`}function Ct(e,t){let[n,i]=t.split(":"),r=Buffer.from(i,"hex"),o=fe(e,n,64);return We(r,o)}function K(e){return{id:Number(e.id),email:String(e.email),name:e.name!=null?String(e.name):null,api_key:String(e.api_key),key_active:Number(e.key_active??1),password_hash:e.password_hash!=null?String(e.password_hash):null,created_at:String(e.created_at),active:Number(e.active),stripe_customer_id:e.stripe_customer_id!=null?String(e.stripe_customer_id):null,balance_mc:Number(e.balance_mc??0),extra_concurrency_slots:Number(e.extra_concurrency_slots??0),concurrency_stripe_sub_id:e.concurrency_stripe_sub_id!=null?String(e.concurrency_stripe_sub_id):null,concurrency_pack_quantity:Number(e.concurrency_pack_quantity??0),subscription_concurrency:Number(e.subscription_concurrency??0),subscription_tier:e.subscription_tier!=null?String(e.subscription_tier):null,subscription_id:e.subscription_id!=null?String(e.subscription_id):null,memory_plan:e.memory_plan!=null?String(e.memory_plan):"free",memory_subscription_id:e.memory_subscription_id!=null?String(e.memory_subscription_id):null,memory_provisioned:Number(e.memory_provisioned??0)}}async function X(e){let t=await l().execute({sql:"SELECT * FROM users WHERE email = ? AND active = 1",args:[e]});return t.rows[0]?K(t.rows[0]):void 0}async function St(e){let t=await l().execute({sql:"SELECT * FROM users WHERE api_key = ? AND active = 1 AND key_active = 1",args:[e]});return t.rows[0]?K(t.rows[0]):void 0}async function Nt(e){let t=await l().execute({sql:"SELECT * FROM users WHERE id = ? AND active = 1",args:[e]});return t.rows[0]?K(t.rows[0]):void 0}async function ht(e,t){await l().execute({sql:"UPDATE users SET password_hash = ? WHERE id = ?",args:[ye(t),e]})}async function Rt(e){let t=l(),[n,i,r,o,s]=await Promise.all([t.execute({sql:"SELECT COUNT(*) as n FROM jobs WHERE user_id = ?",args:[e]}),t.execute({sql:"SELECT COUNT(*) as n FROM jobs WHERE user_id = ? AND status = 'done'",args:[e]}),t.execute({sql:"SELECT COUNT(*) as n FROM jobs WHERE user_id = ? AND status = 'failed'",args:[e]}),t.execute({sql:"SELECT COALESCE(SUM(json_extract(result, '$.totalQuestions')), 0) as n FROM jobs WHERE user_id = ? AND status = 'done'",args:[e]}),t.execute({sql:"SELECT MAX(created_at) as t FROM jobs WHERE user_id = ?",args:[e]})]);return{total:Number(n.rows[0]?.n??0),done:Number(i.rows[0]?.n??0),failed:Number(r.rows[0]?.n??0),totalQuestions:Number(o.rows[0]?.n??0),lastUsed:s.rows[0]?.t!=null?String(s.rows[0].t):null}}async function At(e,t,n,i){let r=l(),o=Ee(),s=n??W(6).toString("hex"),a=ye(s);return{id:(await r.execute({sql:"INSERT INTO users (email, name, api_key, password_hash, stripe_customer_id) VALUES (?, ?, ?, ?, ?)",args:[e,t??null,o,a,i??null]})).lastInsertRowid,email:e,name:t,api_key:o,password:s}}async function xt(e,t,n,i){let r=Math.floor(Date.now()/1e3),o=Math.floor(r/i)*i,s=Y("sha256").update(t).digest("hex"),d=await l().execute({sql:`
2
+ INSERT INTO rate_limits (scope, key_hash, window_start, count)
3
+ VALUES (?, ?, ?, 1)
4
+ ON CONFLICT(scope, key_hash, window_start)
5
+ DO UPDATE SET count = count + 1, updated_at = datetime('now')
6
+ RETURNING count
7
+ `,args:[e,s,o]}),c=Number(d.rows[0]?.count);if(!Number.isSafeInteger(c)||c<1)throw new Error("Rate-limit bucket mutation did not return a valid count");return{allowed:c<=n,count:c,remaining:Math.max(0,n-c),resetSeconds:Math.max(1,o+i-r)}}async function It(e){let t=W(32).toString("hex"),n=Y("sha256").update(t).digest("hex"),i=new Date(Date.now()+3600*1e3).toISOString();return await l().execute({sql:"INSERT INTO password_reset_tokens (token, user_id, expires_at) VALUES (?, ?, ?)",args:[n,e,i]}),t}async function Ot(e){let t=l(),n=Y("sha256").update(e).digest("hex"),r=(await t.execute({sql:"SELECT user_id, expires_at, used FROM password_reset_tokens WHERE token = ?",args:[n]})).rows[0];return!r||Number(r.used)||new Date(String(r.expires_at))<new Date?null:(await t.execute({sql:"UPDATE password_reset_tokens SET used = 1 WHERE token = ?",args:[n]}),Number(r.user_id))}async function Lt(e){let t=Ee();return await l().execute({sql:"UPDATE users SET api_key = ?, key_active = 1 WHERE id = ?",args:[t,e]}),t}async function Ut(e){await l().execute({sql:"UPDATE users SET key_active = 0 WHERE id = ?",args:[e]})}async function Dt(){return(await l().execute("SELECT id, email, name, created_at, active FROM users ORDER BY created_at DESC")).rows.map(t=>K({...t,api_key:"",key_active:1}))}async function Pt(e){await l().execute({sql:"UPDATE users SET active = 0 WHERE id = ?",args:[e]})}async function kt(){let e=await l().execute("SELECT COUNT(*) as n FROM users WHERE active = 1");return Number(e.rows[0]?.n??0)}async function Mt(){return(await l().execute("SELECT id FROM users WHERE active = 1")).rows.map(t=>Number(t.id))}function Kt(e,t,n){return e.lifecycleStatus==="connected"&&e.actionsEnabled&&t.includes(e.providerConfigKey)&&e.actionTools.includes(n)}var U=null,z=null;function C(){let e=l();return U&&z===e||(z=e,U=(async()=>{let t=e;await t.execute(`
8
+ CREATE TABLE IF NOT EXISTS service_connections (
9
+ id TEXT PRIMARY KEY,
10
+ user_id INTEGER NOT NULL REFERENCES users(id),
11
+ provider_config_key TEXT NOT NULL,
12
+ provider TEXT,
13
+ transport TEXT NOT NULL,
14
+ upstream_connection_id TEXT,
15
+ label TEXT,
16
+ user_label TEXT,
17
+ provider_account_id TEXT,
18
+ provider_account_email TEXT,
19
+ provider_account_name TEXT,
20
+ provider_identity_checked_at TEXT,
21
+ provider_identity_source_updated_at TEXT,
22
+ lifecycle_status TEXT NOT NULL DEFAULT 'pending',
23
+ operational_status TEXT NOT NULL DEFAULT 'unknown',
24
+ reconnect_required INTEGER NOT NULL DEFAULT 0,
25
+ actions_enabled INTEGER NOT NULL DEFAULT 0,
26
+ read_tools_json TEXT NOT NULL DEFAULT '[]',
27
+ action_tools_json TEXT NOT NULL DEFAULT '[]',
28
+ tool_revision TEXT,
29
+ last_checked_at TEXT,
30
+ last_successful_call_at TEXT,
31
+ last_failure_at TEXT,
32
+ last_failure_code TEXT,
33
+ last_failure_retryable INTEGER,
34
+ consecutive_failures INTEGER NOT NULL DEFAULT 0,
35
+ vault_name TEXT,
36
+ table_name TEXT,
37
+ legacy_owner_identity TEXT,
38
+ created_at TEXT NOT NULL DEFAULT (datetime('now')),
39
+ updated_at TEXT NOT NULL DEFAULT (datetime('now')),
40
+ UNIQUE(user_id, provider_config_key, upstream_connection_id)
41
+ )
42
+ `);try{await t.execute("ALTER TABLE service_connections ADD COLUMN user_label TEXT")}catch{}try{await t.execute("ALTER TABLE service_connections ADD COLUMN provider_account_id TEXT")}catch{}try{await t.execute("ALTER TABLE service_connections ADD COLUMN provider_account_email TEXT")}catch{}try{await t.execute("ALTER TABLE service_connections ADD COLUMN provider_account_name TEXT")}catch{}try{await t.execute("ALTER TABLE service_connections ADD COLUMN provider_identity_checked_at TEXT")}catch{}try{await t.execute("ALTER TABLE service_connections ADD COLUMN provider_identity_source_updated_at TEXT")}catch{}await t.execute("CREATE INDEX IF NOT EXISTS service_connections_user_updated ON service_connections(user_id, updated_at DESC)"),await t.execute("CREATE INDEX IF NOT EXISTS service_connections_upstream ON service_connections(provider_config_key, upstream_connection_id)"),await t.execute(`
43
+ CREATE TABLE IF NOT EXISTS service_connection_health_events (
44
+ id TEXT PRIMARY KEY,
45
+ connection_id TEXT NOT NULL REFERENCES service_connections(id) ON DELETE CASCADE,
46
+ operational_status TEXT NOT NULL,
47
+ failure_code TEXT,
48
+ retryable INTEGER,
49
+ evidence_source TEXT NOT NULL,
50
+ created_at TEXT NOT NULL DEFAULT (datetime('now'))
51
+ )
52
+ `),await t.execute("CREATE INDEX IF NOT EXISTS service_connection_health_events_connection ON service_connection_health_events(connection_id, created_at DESC)"),await t.execute(`
53
+ CREATE TABLE IF NOT EXISTS service_connection_action_audit (
54
+ id TEXT PRIMARY KEY,
55
+ connection_id TEXT NOT NULL REFERENCES service_connections(id) ON DELETE CASCADE,
56
+ user_id INTEGER NOT NULL REFERENCES users(id),
57
+ tool TEXT NOT NULL,
58
+ request_id TEXT NOT NULL,
59
+ status TEXT NOT NULL,
60
+ error_code TEXT,
61
+ created_at TEXT NOT NULL DEFAULT (datetime('now')),
62
+ UNIQUE(user_id, request_id)
63
+ )
64
+ `);try{await t.execute("ALTER TABLE service_connection_action_audit ADD COLUMN request_digest TEXT")}catch{}try{await t.execute("ALTER TABLE service_connection_action_audit ADD COLUMN result_json TEXT")}catch{}})().catch(t=>{throw U=null,z=null,t})),U}function be(e){if(typeof e!="string")return[];try{let t=JSON.parse(e);return Array.isArray(t)?t.filter(n=>typeof n=="string"):[]}catch{return[]}}function Te(e){return{id:String(e.id),userId:Number(e.user_id),providerConfigKey:String(e.provider_config_key),provider:typeof e.provider=="string"?e.provider:null,transport:e.transport==="remote_mcp"?"remote_mcp":e.transport==="credential_reference"?"credential_reference":"nango",upstreamConnectionId:typeof e.upstream_connection_id=="string"?e.upstream_connection_id:null,label:typeof e.label=="string"?e.label:null,userLabel:typeof e.user_label=="string"?e.user_label:null,providerAccountId:typeof e.provider_account_id=="string"?e.provider_account_id:null,providerAccountEmail:typeof e.provider_account_email=="string"?e.provider_account_email:null,providerAccountName:typeof e.provider_account_name=="string"?e.provider_account_name:null,providerIdentityCheckedAt:typeof e.provider_identity_checked_at=="string"?e.provider_identity_checked_at:null,providerIdentitySourceUpdatedAt:typeof e.provider_identity_source_updated_at=="string"?e.provider_identity_source_updated_at:null,lifecycleStatus:String(e.lifecycle_status),operationalStatus:String(e.operational_status),reconnectRequired:Number(e.reconnect_required)===1,actionsEnabled:Number(e.actions_enabled)===1,readTools:be(e.read_tools_json),actionTools:be(e.action_tools_json),toolRevision:typeof e.tool_revision=="string"?e.tool_revision:null,lastCheckedAt:typeof e.last_checked_at=="string"?e.last_checked_at:null,lastSuccessfulCallAt:typeof e.last_successful_call_at=="string"?e.last_successful_call_at:null,lastFailureAt:typeof e.last_failure_at=="string"?e.last_failure_at:null,lastFailureCode:typeof e.last_failure_code=="string"?e.last_failure_code:null,lastFailureRetryable:e.last_failure_retryable===null||e.last_failure_retryable===void 0?null:Number(e.last_failure_retryable)===1,consecutiveFailures:Number(e.consecutive_failures??0),vaultName:typeof e.vault_name=="string"?e.vault_name:null,tableName:typeof e.table_name=="string"?e.table_name:null,createdAt:String(e.created_at),updatedAt:String(e.updated_at)}}async function Z(e){let t=await X(e.normalize("NFKC").trim().toLowerCase());if(!t)throw new Error("service_connection_user_not_found");return Number(t.id)}async function ee(e,t){await C();let n=l(),i=await Z(e);for(let r of t)await n.execute({sql:`
65
+ INSERT INTO service_connections (
66
+ id, user_id, provider_config_key, provider, transport, upstream_connection_id,
67
+ label, lifecycle_status, reconnect_required, actions_enabled, legacy_owner_identity, created_at, updated_at
68
+ ) VALUES (?, ?, ?, ?, 'nango', ?, ?, ?, ?, 1, ?, COALESCE(?, datetime('now')), COALESCE(?, datetime('now')))
69
+ ON CONFLICT(user_id, provider_config_key, upstream_connection_id) DO UPDATE SET
70
+ provider = excluded.provider,
71
+ label = COALESCE(excluded.label, service_connections.label),
72
+ lifecycle_status = excluded.lifecycle_status,
73
+ reconnect_required = excluded.reconnect_required,
74
+ updated_at = excluded.updated_at
75
+ `,args:[Q(),i,r.providerConfigKey,r.provider,r.upstreamConnectionId,r.label,r.lifecycleStatus,r.reconnectRequired?1:0,e,r.createdAt,r.updatedAt]});return Ke(e,"nango")}async function Ke(e,t){await C();let n=await Z(e);return(await l().execute({sql:`SELECT * FROM service_connections WHERE user_id = ?${t?" AND transport = ?":""} AND lifecycle_status <> 'disconnected' ORDER BY updated_at DESC`,args:t?[n,t]:[n]})).rows.map(r=>Te(r))}async function S(e,t){await C();let n=await Z(e),r=(await l().execute({sql:"SELECT * FROM service_connections WHERE id = ? AND user_id = ? LIMIT 1",args:[t,n]})).rows[0];return r?Te(r):null}async function ve(e,t,n,i){await C(),await l().execute({sql:"UPDATE service_connections SET read_tools_json = ?, action_tools_json = ?, tool_revision = ?, updated_at = datetime('now') WHERE id = ?",args:[JSON.stringify(t),JSON.stringify(n),i,e]})}async function we(e){await C(),await l().execute({sql:`
76
+ UPDATE service_connections SET
77
+ provider_account_id = ?, provider_account_email = ?, provider_account_name = ?,
78
+ provider_identity_checked_at = datetime('now'), provider_identity_source_updated_at = ?,
79
+ updated_at = datetime('now')
80
+ WHERE id = ?
81
+ `,args:[e.providerAccountId??null,e.providerAccountEmail?.toLowerCase()??null,e.providerAccountName??null,e.sourceUpdatedAt,e.connectionId]})}async function Xt(e,t,n){let i=await S(e,t);if(!i||i.lifecycleStatus==="disconnected")throw new Error("service_connection_not_found");return await l().execute({sql:"UPDATE service_connections SET user_label = ?, updated_at = datetime('now') WHERE id = ? AND user_id = ?",args:[n,t,i.userId]}),n}async function te(e){await C();let t=new Date().toISOString();await l().execute({sql:`
82
+ UPDATE service_connections SET
83
+ operational_status = ?, last_checked_at = ?,
84
+ last_successful_call_at = CASE WHEN ? = 'available' THEN ? ELSE last_successful_call_at END,
85
+ last_failure_at = CASE WHEN ? IN ('degraded', 'unavailable') THEN ? ELSE NULL END,
86
+ last_failure_code = ?, last_failure_retryable = ?,
87
+ consecutive_failures = CASE WHEN ? = 'available' THEN 0 ELSE consecutive_failures + 1 END,
88
+ updated_at = datetime('now')
89
+ WHERE id = ?
90
+ `,args:[e.operationalStatus,t,e.operationalStatus,t,e.operationalStatus,t,e.failureCode??null,e.retryable==null?null:e.retryable?1:0,e.operationalStatus,e.connectionId]}),await l().execute({sql:"INSERT INTO service_connection_health_events (id, connection_id, operational_status, failure_code, retryable, evidence_source) VALUES (?, ?, ?, ?, ?, ?)",args:[Q(),e.connectionId,e.operationalStatus,e.failureCode??null,e.retryable==null?null:e.retryable?1:0,e.evidenceSource]})}async function Bt(e,t,n){let i=await S(e,t);if(!i||i.lifecycleStatus==="disconnected")throw new Error("service_connection_not_found");return await l().execute({sql:"UPDATE service_connections SET actions_enabled = ?, updated_at = datetime('now') WHERE id = ? AND user_id = ?",args:[n?1:0,t,i.userId]}),n}async function Gt(e,t){let n=await S(e,t);if(!n)throw new Error("service_connection_not_found");await l().execute({sql:"UPDATE service_connections SET lifecycle_status = 'disconnected', operational_status = 'unknown', reconnect_required = 0, updated_at = datetime('now') WHERE id = ? AND user_id = ?",args:[t,n.userId]});let i=await l().execute({sql:"SELECT COUNT(*) AS count FROM service_connections WHERE user_id = ? AND transport = 'nango' AND lifecycle_status = 'connected'",args:[n.userId]});return Number(i.rows[0]?.count??0)}async function Vt(e){await C();let t=await S(e.identity,e.connectionId);if(!t)throw new Error("service_connection_not_found");await l().execute({sql:"UPDATE service_connection_action_audit SET status = ?, error_code = ?, result_json = ? WHERE user_id = ? AND request_id = ? AND connection_id = ?",args:[e.status,e.errorCode??null,e.result===void 0?null:JSON.stringify(e.result),t.userId,e.requestId,t.id]})}async function $t(e){await C();let t=await S(e.identity,e.connectionId);if(!t)throw new Error("service_connection_not_found");let n=await l().execute({sql:"INSERT OR IGNORE INTO service_connection_action_audit (id, connection_id, user_id, tool, request_id, status, request_digest) VALUES (?, ?, ?, ?, ?, 'started', ?)",args:[Q(),t.id,t.userId,e.tool,e.requestId,e.requestDigest]});if(Number(n.rowsAffected??0)===1)return{claimed:!0};let r=(await l().execute({sql:"SELECT connection_id, tool, status, error_code, request_digest, result_json FROM service_connection_action_audit WHERE user_id = ? AND request_id = ? LIMIT 1",args:[t.userId,e.requestId]})).rows[0],o=String(r?.connection_id??"")!==t.id||String(r?.tool??"")!==e.tool||String(r?.request_digest??"")!==e.requestDigest,s;if(!o&&typeof r?.result_json=="string")try{s=JSON.parse(r.result_json)}catch{s=void 0}return{claimed:!1,status:String(r?.status??"unknown"),errorCode:typeof r?.error_code=="string"?r.error_code:null,conflict:o,...s!==void 0?{result:s}:{}}}import{createHash as Xe,randomUUID as Be}from"crypto";import{z as E}from"zod";async function Qt(e,t){!Number.isFinite(t)||t<=0||await $({op:I.CONNECTED_ACCOUNT_FEE,userId:Number(e)},()=>j({vendor:"nango_connection",units:t,unitType:"connection_month"}))}async function Ce(e,t){let n=[{vendor:"nango_function_run",units:t.functionRuns,unitType:"function_run"},{vendor:"nango_proxy_request",units:t.proxyRequests,unitType:"proxy_request"},{vendor:"nango_compute",units:t.computeMilliseconds/1e3,unitType:"compute_second"}];await $({op:I.CONNECTED_USAGE,userId:Number(e)},async()=>{for(let i of n)!Number.isFinite(i.units)||i.units<=0||await j(i)})}import{randomUUID as Se}from"crypto";async function an(){let e=l(),t=await e.execute({sql:`SELECT id
91
+ FROM credit_lots
92
+ WHERE remaining_mc > 0
93
+ AND never_expires = 0
94
+ AND expires_at <= datetime('now')
95
+ LIMIT 500`});if(t.rows.length===0)return{expired_lots:0,expired_mc:0};let n=[],i=[];for(let c of t.rows){let u=Number(c.id),p=Se();n.push({token:p,insertResultIndex:i.length}),i.push({sql:`INSERT OR IGNORE INTO credit_lot_expirations (lot_id, user_id, amount_mc, claim_token)
96
+ SELECT id, user_id, remaining_mc, ?
97
+ FROM credit_lots
98
+ WHERE id = ?
99
+ AND remaining_mc > 0
100
+ AND never_expires = 0
101
+ AND expires_at <= datetime('now')`,args:[p,u]}),i.push({sql:`UPDATE credit_lots
102
+ SET remaining_mc = 0
103
+ WHERE id = ?
104
+ AND EXISTS (
105
+ SELECT 1 FROM credit_lot_expirations
106
+ WHERE lot_id = ? AND claim_token = ?
107
+ )`,args:[u,u,p]}),i.push({sql:`INSERT INTO ledger (user_id, amount_mc, operation, description)
108
+ SELECT user_id, -amount_mc, 'credit_expired', 'credits expired'
109
+ FROM credit_lot_expirations
110
+ WHERE lot_id = ? AND claim_token = ?`,args:[u,p]})}let r=await e.batch(i,"write"),o=n.filter(c=>r[c.insertResultIndex]?.rowsAffected===1).map(c=>c.token);if(o.length===0)return{expired_lots:0,expired_mc:0};let s=o.map(()=>"?").join(", "),a=await e.execute({sql:`SELECT user_id, amount_mc
111
+ FROM credit_lot_expirations
112
+ WHERE claim_token IN (${s})`,args:o}),d=new Set(a.rows.map(c=>Number(c.user_id)));for(let c of d)await D(c);return{expired_lots:a.rows.length,expired_mc:a.rows.reduce((c,u)=>c+Number(u.amount_mc),0)}}async function cn(e,t,n,i,r,o){let s=l();await q(e);let a=o?.neverExpires;if(a===void 0&&t>0){let p=await s.execute({sql:"SELECT subscription_tier FROM users WHERE id = ? LIMIT 1",args:[e]});a=String(p.rows[0]?.subscription_tier??"").startsWith("sonic")}let d=a?"9999-12-31 23:59:59":null;if(r){let p=[{sql:"INSERT OR IGNORE INTO ledger (user_id, amount_mc, operation, description, stripe_pi) VALUES (?, ?, ?, ?, ?)",args:[e,t,n,i??null,r]}];t>0&&p.push({sql:`INSERT INTO credit_lots (user_id, amount_mc, remaining_mc, source, stripe_pi, expires_at, never_expires)
113
+ SELECT ?, ?, ?, ?, ?, COALESCE(?, datetime('now', ?)), ?
114
+ WHERE changes() = 1`,args:[e,t,t,n,r,d,M,a?1:0]}),p.push({sql:"UPDATE users SET balance_mc = balance_mc + ? WHERE id = ? AND changes() = 1",args:[t,e]}),await s.batch(p,"write");let f=await s.execute({sql:"SELECT balance_mc FROM users WHERE id = ?",args:[e]});return Number(f.rows[0]?.balance_mc??0)}let c=[];t>0&&c.push({sql:"INSERT INTO credit_lots (user_id, amount_mc, remaining_mc, source, stripe_pi, expires_at, never_expires) VALUES (?, ?, ?, ?, ?, COALESCE(?, datetime('now', ?)), ?)",args:[e,t,t,n,null,d,M,a?1:0]}),c.push({sql:"UPDATE users SET balance_mc = balance_mc + ? WHERE id = ?",args:[t,e]}),c.push({sql:"INSERT INTO ledger (user_id, amount_mc, operation, description, stripe_pi) VALUES (?, ?, ?, ?, ?)",args:[e,t,n,i??null,null]}),await s.batch(c,"write");let u=await s.execute({sql:"SELECT balance_mc FROM users WHERE id = ?",args:[e]});return Number(u.rows[0]?.balance_mc??0)}async function un(e,t,n,i,r,o){if(!Number.isSafeInteger(t)||t<=0)throw new Error("idempotent credit amount must be a positive integer");if(!r||r.length>500)throw new Error("idempotent credit key is required and must be bounded");let s=l();await q(e);let a=o?.neverExpires;if(a===void 0){let y=await s.execute({sql:"SELECT subscription_tier FROM users WHERE id = ? LIMIT 1",args:[e]});a=String(y.rows[0]?.subscription_tier??"").startsWith("sonic")}let d=a?"9999-12-31 23:59:59":null,c=async()=>{let y=await s.execute({sql:"SELECT balance_mc FROM users WHERE id = ?",args:[e]});return Number(y.rows[0]?.balance_mc??0)},u;try{u=await s.batch([{sql:"INSERT OR IGNORE INTO billing_credits (idempotency_key, user_id, amount_mc, operation, description, status) VALUES (?, ?, ?, ?, ?, 'claimed')",args:[r,e,t,n,i]},{sql:"UPDATE billing_credits SET status = 'applying' WHERE idempotency_key = ? AND user_id = ? AND amount_mc = ? AND operation = ? AND description = ? AND status = 'claimed'",args:[r,e,t,n,i]},{sql:`INSERT INTO credit_lots (user_id, amount_mc, remaining_mc, source, stripe_pi, expires_at, never_expires)
115
+ SELECT user_id, amount_mc, amount_mc, operation, NULL, COALESCE(?, datetime('now', ?)), ?
116
+ FROM billing_credits
117
+ WHERE idempotency_key = ? AND status = 'applying'`,args:[d,M,a?1:0,r]},{sql:`UPDATE users
118
+ SET balance_mc = balance_mc + COALESCE((
119
+ SELECT amount_mc FROM billing_credits WHERE idempotency_key = ? AND status = 'applying'
120
+ ), 0)
121
+ WHERE id = ?`,args:[r,e]},{sql:"INSERT INTO ledger (user_id, amount_mc, operation, description) SELECT user_id, amount_mc, operation, description FROM billing_credits WHERE idempotency_key = ? AND status = 'applying'",args:[r]},{sql:"UPDATE billing_credits SET status = 'applied', applied_at = datetime('now') WHERE idempotency_key = ? AND status = 'applying'",args:[r]}],"write")}catch(y){try{let x=(await s.execute({sql:"SELECT user_id, amount_mc, operation, description FROM billing_credits WHERE idempotency_key = ? AND status = 'applied' LIMIT 1",args:[r]})).rows[0];if(x&&Number(x.user_id)===e&&Number(x.amount_mc)===t&&String(x.operation)===n&&String(x.description)===i)return{ok:!0,balance_mc:await c(),duplicate:!0}}catch{}throw y}let f=(await s.execute({sql:"SELECT user_id, amount_mc, operation, description, status FROM billing_credits WHERE idempotency_key = ? LIMIT 1",args:[r]})).rows[0];if(!f||Number(f.user_id)!==e||Number(f.amount_mc)!==t||String(f.operation)!==n||String(f.description)!==i)throw new Error("idempotent credit key conflicts with another credit");return{ok:String(f.status)==="applied",balance_mc:await c(),duplicate:u[1]?.rowsAffected===0&&String(f.status)==="applied"}}async function dn(e,t){return(await l().execute({sql:"SELECT 1 FROM ledger WHERE user_id = ? AND operation = ? LIMIT 1",args:[e,t]})).rows.length>0}async function ln(e,t,n,i){let r=`debit:${Se()}`,o=await L(e,t,n,i??"",r);return{ok:o.ok,balance_mc:o.balance_mc,billingKey:r}}async function mn(e,t=50){return(await l().execute({sql:"SELECT * FROM ledger WHERE user_id = ? ORDER BY created_at DESC LIMIT ?",args:[e,t]})).rows.map(i=>({id:Number(i.id),user_id:Number(i.user_id),amount_mc:Number(i.amount_mc),operation:String(i.operation),description:i.description!=null?String(i.description):null,stripe_pi:i.stripe_pi!=null?String(i.stripe_pi):null,created_at:String(i.created_at)}))}async function pn(e,t,n){let i=l(),r=n.refund.map(()=>"?").join(", "),o=n.grant.map(()=>"?").join(", "),s=n.purchase.map(()=>"?").join(", "),a=await i.execute({sql:`SELECT
122
+ COALESCE(SUM(CASE WHEN amount_mc < 0 AND operation NOT IN (${r}) THEN -amount_mc ELSE 0 END), 0) AS spent_mc,
123
+ COALESCE(SUM(CASE WHEN amount_mc > 0 AND operation IN (${r}) THEN amount_mc ELSE 0 END), 0) AS refunded_mc,
124
+ COALESCE(SUM(CASE WHEN amount_mc > 0 AND operation IN (${o}) THEN amount_mc ELSE 0 END), 0) AS granted_mc,
125
+ COALESCE(SUM(CASE WHEN amount_mc > 0 AND operation IN (${s}) THEN amount_mc ELSE 0 END), 0) AS purchased_mc,
126
+ COALESCE(SUM(amount_mc), 0) AS net_mc
127
+ FROM ledger WHERE user_id = ? AND created_at >= ?`,args:[...n.refund,...n.refund,...n.grant,...n.purchase,e,t]}),d=await i.execute({sql:`SELECT operation, -SUM(amount_mc) AS mc, COUNT(*) AS count
128
+ FROM ledger
129
+ WHERE user_id = ? AND created_at >= ? AND amount_mc < 0 AND operation NOT IN (${r})
130
+ GROUP BY operation
131
+ ORDER BY mc DESC, operation ASC`,args:[e,t,...n.refund]}),c=a.rows[0];return{spent_mc:Number(c?.spent_mc??0),refunded_mc:Number(c?.refunded_mc??0),granted_mc:Number(c?.granted_mc??0),purchased_mc:Number(c?.purchased_mc??0),net_mc:Number(c?.net_mc??0),by_operation:d.rows.map(u=>({operation:String(u.operation),mc:Number(u.mc),count:Number(u.count)}))}}async function D(e,t){let n=l();for(let r=0;r<8;r+=1){let s=(await n.execute({sql:`SELECT
132
+ u.balance_mc AS cached_balance_mc,
133
+ COUNT(l.id) AS lot_count,
134
+ COALESCE(SUM(CASE
135
+ WHEN l.remaining_mc > 0
136
+ AND (l.never_expires = 1 OR l.expires_at > datetime('now'))
137
+ THEN l.remaining_mc ELSE 0 END), 0) AS projected_balance_mc
138
+ FROM users u
139
+ LEFT JOIN credit_lots l ON l.user_id = u.id
140
+ WHERE u.id = ?
141
+ GROUP BY u.id, u.balance_mc`,args:[e]})).rows[0];if(!s)return 0;if(Number(s.lot_count??0)===0&&(await q(Number(e)),(await n.execute({sql:"SELECT 1 FROM credit_lots WHERE user_id = ? LIMIT 1",args:[e]})).rows.length>0))continue;let a=Number(s.cached_balance_mc??0),d=Number(s.projected_balance_mc??0);if(a===d||(await n.execute({sql:"UPDATE users SET balance_mc = ? WHERE id = ? AND balance_mc = ?",args:[d,e,a]})).rowsAffected===1)return d}let i=await n.execute({sql:"SELECT balance_mc FROM users WHERE id = ? LIMIT 1",args:[e]});return Number(i.rows[0]?.balance_mc??0)}var N="connected_usage",Ge="mastra_scheduler",Ve=E.object({toolName:E.string().trim().min(1).max(200).optional(),operationKind:E.enum(["read","action","sync","export","proxy","other"]).optional(),outcome:E.enum(["success","error","partial"]).optional(),requestId:E.string().trim().min(1).max(200).optional(),occurrenceId:E.string().trim().min(1).max(200).optional(),scheduleId:E.string().trim().min(1).max(200).optional(),nangoOperationId:E.string().trim().min(1).max(200).optional(),startedAt:E.string().datetime({offset:!0}).optional(),completedAt:E.string().datetime({offset:!0}).optional()}).strict(),$e=E.object({identity:E.string().trim().min(1).max(320),idempotencyKey:E.string().trim().min(1).max(500),ratePolicyVersion:E.string().trim().min(1).max(100),connectionId:E.string().trim().min(1).max(500),providerConfigKey:E.string().trim().min(1).max(200),functionRuns:E.number().int().safe().nonnegative(),proxyRequests:E.number().int().safe().nonnegative(),computeMilliseconds:E.number().int().safe().nonnegative(),sourceSurface:E.enum(["main_mcp","mastra_scheduler","nango_reconciliation"]).default(Ge),metadata:Ve.optional()}).strict(),je=E.object({identity:E.string().trim().min(1).max(320),ratePolicyVersion:E.string().trim().min(1).max(100)}).strict(),T=class extends Error{constructor(n,i,r,o={}){super(i);this.code=n;this.httpStatus=r;this.details=o;this.name="ConnectedUsageBillingError"}code;httpStatus;details};function oe(e){return Xe("sha256").update(e).digest("hex")}function Je(e){return`connected-usage:${oe(e)}`}function Ye(e){return`connected-usage-debit:${oe(e)}`}function ze(e){return e.trim().toLowerCase()}async function Ne(e){let t=await X(ze(e));if(!t)throw new T("user_not_found","billing identity was not found",404);return t}function Qe(e){let t={toolName:e.metadata.toolName??null,operationKind:e.metadata.operationKind??null,outcome:e.metadata.outcome??null,requestId:e.metadata.requestId??null,occurrenceId:e.metadata.occurrenceId??null,scheduleId:e.metadata.scheduleId??null,nangoOperationId:e.metadata.nangoOperationId??null,startedAt:e.metadata.startedAt??null,completedAt:e.metadata.completedAt??null};return oe(JSON.stringify({ratePolicyVersion:b,connectionId:e.connectionId,providerConfigKey:e.providerConfigKey,usage:e.usage,sourceSurface:e.sourceSurface,metadata:t}))}function P(e){let t=JSON.stringify(e);if(t.length>4e3)throw new T("invalid_request","connected usage metadata is too large",400);return t}function se(e){try{let t=JSON.parse(e.metadata??"");if(t.contract!=="connected_usage_receipt"||t.ratePolicyVersion!==b||typeof t.fingerprint!="string"||typeof t.connectionId!="string"||typeof t.providerConfigKey!="string"||!t.usage||!t.charge)throw new Error("invalid connected usage receipt metadata");return t}catch{throw new T("idempotency_key_conflict","the idempotency key is already bound to an incompatible billing receipt",409)}}async function ne(e){let t=await l().execute({sql:"SELECT id, user_id, billing_class, source_surface, status, amount_mc, metadata FROM billing_events WHERE idempotency_key = ? LIMIT 1",args:[e]});return t.rows[0]?t.rows[0]:null}async function he(e,t){return(await l().execute({sql:`SELECT 1
142
+ FROM billing_events
143
+ WHERE user_id = ?
144
+ AND billing_class = ?
145
+ AND status = 'cost_pending'
146
+ ${t?"AND idempotency_key <> ?":""}
147
+ LIMIT 1`,args:t?[e,N,t]:[e,N]})).rows.length>0}function Ze(e){let t="connected-usage:",n=e.startsWith(t)?e.slice(t.length):"";return/^[a-f0-9]{64}$/.test(n)?`connected-usage-debit:${n}`:null}async function et(e){let t=await l().execute({sql:`SELECT id, user_id, idempotency_key, billing_class, source_surface, status, amount_mc, metadata
148
+ FROM billing_events
149
+ WHERE user_id = ? AND billing_class = ? AND status = 'cost_pending'
150
+ ORDER BY created_at ASC
151
+ LIMIT 10`,args:[e.id,N]});for(let n of t.rows){let i=n,r=String(i.idempotency_key??""),o=Ze(r),s;try{s=se(i)}catch{return}if(!o||Number(i.user_id)!==e.id||i.billing_class!==N||Number(i.amount_mc)!==s.charge.amountMc||s.charge.amountMc>0&&!(await L(e.id,s.charge.amountMc,I.CONNECTED_USAGE,`connected-usage:${s.providerConfigKey}`,o)).ok)return;let a={...s};delete a.reason,await l().execute({sql:`UPDATE billing_events
152
+ SET status = 'settled', metadata = ?, settled_at = datetime('now')
153
+ WHERE idempotency_key = ? AND user_id = ? AND billing_class = ? AND status = 'cost_pending'`,args:[P(a),r,e.id,N]})}}function Re(e){if(e!==b)throw new T("rate_policy_mismatch","connected usage receipt rate policy does not match the active policy",409,{expectedRatePolicyVersion:b})}async function ae(e){let t=je.safeParse(e);if(!t.success)throw new T("invalid_request","invalid connected usage preflight request",400);Re(t.data.ratePolicyVersion);let n=await Ne(t.data.identity);if(await et(n),await he(n.id))throw new T("pending_cost","a previous connected usage receipt has unresolved cost",409);let i=await D(n.id,n.balance_mc);if(i<H)throw new T("insufficient_credits","the wallet cannot cover the minimum connected function charge",402,{balanceMc:i,requiredMc:H});return{allowed:!0,ratePolicyVersion:b,minimumMc:H,minimumCredits:J,balanceMc:i}}function ie(e,t,n,i,r){let o=se(e);if(Number(e.user_id)!==t||e.billing_class!==N||e.source_surface!==n||Number(e.amount_mc)!==r||o.fingerprint!==i)throw new T("idempotency_key_conflict","the idempotency key is already bound to different connected usage",409);return o}function Ae(e,t){return[{key:"function_runs",label:"Connected function runs",quantity:e.functionRuns,quantityUnit:"function_run",rateCredits:J,rateUnit:"function_run",amountMc:t.functionRunMc,credits:t.functionRunMc/F},{key:"proxy_requests",label:"Connected proxy requests",quantity:e.proxyRequests,quantityUnit:"proxy_request",rateCredits:pe,rateUnit:"proxy_request",amountMc:t.proxyRequestMc,credits:t.proxyRequestMc/F},{key:"compute",label:"Connected function compute",quantity:e.computeMilliseconds,quantityUnit:"millisecond",rateCredits:_e,rateUnit:"compute_second",amountMc:t.computeMc,credits:t.computeMc/F}]}function re(e,t,n,i){let r=e.status==="cost_pending"?t.reason:void 0;return{id:e.id,status:e.status==="settled"?"settled":"cost_pending",ratePolicyVersion:b,connectionId:t.connectionId,providerConfigKey:t.providerConfigKey,amountMc:t.charge.amountMc,credits:t.charge.credits,functionRunMc:t.charge.functionRunMc,proxyRequestMc:t.charge.proxyRequestMc,computeMc:t.charge.computeMc,usage:t.usage,costBreakdown:Ae(t.usage,t.charge),balanceMc:n,...r?{reason:r}:{},duplicate:i}}async function ce(e){let t=$e.safeParse(e);if(!t.success)throw new T("invalid_request","invalid connected usage settlement request",400,{fields:[...new Set(t.error.issues.map(w=>w.path.join(".")).filter(Boolean))]});let n=t.data;Re(n.ratePolicyVersion);let i=await Ne(n.identity),r={functionRuns:n.functionRuns,proxyRequests:n.proxyRequests,computeMilliseconds:n.computeMilliseconds},o=ge(r),s=n.metadata??{},a=Qe({connectionId:n.connectionId,providerConfigKey:n.providerConfigKey,usage:r,sourceSurface:n.sourceSurface,metadata:s}),d={contract:"connected_usage_receipt",ratePolicyVersion:b,fingerprint:a,connectionId:n.connectionId,providerConfigKey:n.providerConfigKey,usage:r,charge:o,safeMetadata:s},c=Je(n.idempotencyKey);if(await he(i.id,c))throw new T("pending_cost","a previous connected usage receipt has unresolved cost",409);let u=await l().execute({sql:`INSERT OR IGNORE INTO billing_events
154
+ (id, user_id, idempotency_key, billing_class, source_surface, status, amount_mc, metadata)
155
+ VALUES (?, ?, ?, ?, ?, 'settling', ?, ?)`,args:[Be(),i.id,c,N,n.sourceSurface,o.amountMc,P(d)]}),p=await ne(c);if(!p)throw new Error("connected usage receipt insert completed without a readable event");let f=ie(p,i.id,n.sourceSurface,a,o.amountMc),y=u.rowsAffected===0;if(p.status==="settled")return re(p,f,await D(i.id,i.balance_mc),!0);if(!["settling","cost_pending"].includes(p.status))throw new T("idempotency_key_conflict","the connected usage receipt has an incompatible status",409);if(p.status==="cost_pending"&&await l().execute({sql:"UPDATE billing_events SET status = 'settling', metadata = ? WHERE idempotency_key = ? AND status = 'cost_pending'",args:[P(d),c]}),o.amountMc===0)await l().execute({sql:"UPDATE billing_events SET status = 'settled', settled_at = datetime('now') WHERE idempotency_key = ? AND status = 'settling'",args:[c]});else{let w=await L(i.id,o.amountMc,I.CONNECTED_USAGE,`connected-usage:${n.providerConfigKey}`,Ye(n.idempotencyKey));if(!w.ok){let x={...d,reason:"insufficient_credits"};if(await l().execute({sql:"UPDATE billing_events SET status = 'cost_pending', metadata = ? WHERE idempotency_key = ? AND status = 'settling'",args:[P(x),c]}),p=await ne(c),!p)throw new Error("connected usage pending receipt was lost");return f=ie(p,i.id,n.sourceSurface,a,o.amountMc),re(p,f,w.balance_mc,y||w.duplicate)}await l().execute({sql:"UPDATE billing_events SET status = 'settled', metadata = ?, settled_at = datetime('now') WHERE idempotency_key = ? AND status IN ('settling', 'cost_pending')",args:[P(d),c]}),w.duplicate||await Ce(i.id,r)}if(p=await ne(c),!p)throw new Error("connected usage settlement completed without an event receipt");return f=ie(p,i.id,n.sourceSurface,a,o.amountMc),re(p,f,await D(i.id,i.balance_mc),y)}async function Cn(e,t=100){let n=await l().execute({sql:`SELECT id, user_id, billing_class, source_surface, status, amount_mc, metadata, created_at
156
+ FROM billing_events
157
+ WHERE user_id = ? AND billing_class = ? AND status IN ('settled', 'cost_pending')
158
+ ORDER BY created_at DESC
159
+ LIMIT ?`,args:[e,N,Math.max(1,Math.min(250,Math.round(t)))]}),i=[];for(let r of n.rows){let o=r;try{let s=se(o);i.push({id:o.id,createdAt:String(o.created_at??""),status:o.status==="settled"?"settled":"cost_pending",connectionId:s.connectionId,providerConfigKey:s.providerConfigKey,amountMc:s.charge.amountMc,credits:s.charge.credits,usage:s.usage,costBreakdown:Ae(s.usage,s.charge),metadata:s.safeMetadata})}catch{}}return i}function ue(e){return e.annotations?.readOnlyHint===!0?"read":e.annotations?.readOnlyHint===!1?"action":/^(get|list|search|query|read|download|fetch|find|lookup|inspect|describe|check)-/i.test(e.name)?"read":"action"}function xe(e){return new Map(Object.entries(e??{}).map(([t,n])=>[t,[...new Set(n.map(i=>i.trim()).filter(Boolean))].sort()]))}function B(e){let t=xe(e.requiredPermissionsByTool),n=xe(e.requiredFeaturesByTool),i=new Set(e.grantedPermissions??[]),r=new Set(e.enabledFeatures??[]),o=new Set(e.adminBlockedTools??[]),s=new Map;for(let a of e.tools){let d=ue(a),c=t.get(a.name)??[],u=n.get(a.name)??[],p=c.filter(w=>!i.has(w)),f=u.filter(w=>!r.has(w)),y=e.connectionActive?o.has(a.name)?"admin_blocked":d==="action"&&!e.actionsEnabled?"actions_disabled":c.length>0&&e.permissionVerification==="unavailable"?"permission_verification_unavailable":p.length>0?"missing_permission":f.length>0?"missing_app_feature":null:"inactive_connection";s.set(a.name,{name:a.name,classification:d,requiredPermissions:c,requiredFeatures:u,available:y===null,blockedReason:y,missingPermissions:p,missingFeatures:f})}return s}function de(e,t){let n=e.get(t);if(!n)throw new Error("connected_tool_policy_missing");return n}var it="https://api.nango.dev/mcp",rt=2e4,ot=24e4,Ie=100,st=20,at=360*60*1e3,ct=new Set(["stripe_revenue","salesforce","pipedrive"]),ut="2026-07-16.1",dt="f037859ec80c2ea2fac6e4a67c1a59f3200dd22d3642c97789b9bb3236723d3e",g=class extends Error{status;code;retryable;retryAfterMs;constructor(t,n,i,r=n===429||n>=500,o=null){super(t),this.name="MainNangoTransportError",this.status=n,this.code=i,this.retryable=r,this.retryAfterMs=o}};function G(e){return typeof e=="string"&&ct.has(e.normalize("NFKC").trim().toLowerCase())}function Le(e){if(G(e))throw new g("This provider integration is not currently available.",409,"provider_unavailable",!1)}function lt(e){if(e instanceof Error)return e.message;if(typeof e=="string")return e;try{return JSON.stringify(e)}catch{return""}}function Ue(e){let t=e.match(/retry[_ -]?after[_ -]?ms[^0-9]{0,20}(\d{1,7})/i);if(t)return Math.min(Math.max(Number(t[1]),1e3),6e4);let n=e.match(/retry[_ -]?after[^0-9]{0,20}(\d{1,4})/i);return n?Math.min(Math.max(Number(n[1]),1)*1e3,6e4):null}function De(e){if(e instanceof g)return e;let t=lt(e),n=e&&typeof e=="object"?e:null;return n?.code===-32001||n?.name==="RequestTimeout"||/Request timed out|RequestTimeout|Maximum total timeout exceeded/i.test(t)?new g("The connected service operation timed out before returning a result. Retry failed items or use a smaller batch.",503,"mcp_request_timeout",!0):/SERVICE_DISABLED|accessNotConfigured/i.test(t)?new g("The provider API required by this connection is disabled. Enable it in the provider project, wait for propagation, then retry.",409,"provider_api_disabled",!1):/PERMISSION_DENIED|insufficientPermissions|insufficient permission/i.test(t)?new g("The connected account does not have permission to run this provider operation.",403,"missing_provider_permission",!1):/RESOURCE_EXHAUSTED|rate.?limit|status["']?\s*:\s*429/i.test(t)?new g("The connected provider is temporarily rate limited.",429,"upstream_rate_limited",!0,Ue(t)):/UNAUTHENTICATED|invalid_grant|status["']?\s*:\s*401/i.test(t)?new g("The service connection requires reconnection.",409,"connection_inactive",!1):new g("The service connection is temporarily unavailable.",503,"connection_transport_unavailable")}async function mt(e,t,n){return e.callTool({name:t,arguments:n},{timeout:ot})}function _(e){return e&&typeof e=="object"&&!Array.isArray(e)?e:null}function m(e){return typeof e=="string"&&e.trim()?e.trim():null}function le(e,t){if(Array.isArray(e))return e;let n=_(e);if(Array.isArray(n?.[t]))return n[t];if(Array.isArray(n?.data))return n.data;let i=_(n?.data);return Array.isArray(i?.[t])?i[t]:[]}function Pe(){let e=process.env.NANGO_SECRET_KEY?.trim();if(!e)throw new g("Nango is not configured.",503,"nango_not_configured");return e}function ke(){try{return new URL(process.env.NANGO_MCP_URL?.trim()||it)}catch{throw new g("Nango MCP URL is invalid.",503,"nango_invalid_url")}}async function A(e,t={}){let n=new URL(e,`${ke().origin}/`);for(let[s,a]of Object.entries(t.query??{}))a!==void 0&&n.searchParams.set(s,String(a));let i;try{i=await fetch(n,{method:t.method??"GET",headers:{authorization:`Bearer ${Pe()}`,accept:"application/json",...t.body?{"content-type":"application/json"}:{},...t.headers},body:t.body?JSON.stringify(t.body):void 0,signal:AbortSignal.timeout(rt)})}catch{throw new g("Nango is temporarily unavailable.",503,"connection_transport_unavailable")}let r=await i.text(),o={};try{o=r?JSON.parse(r):{}}catch{throw new g("Nango returned an invalid response.",502,"nango_invalid_response")}if(!i.ok){let s=i.status===400||i.status===403||i.status===404||i.status===409||i.status===429||i.status===503?i.status:502;throw new g(s===429?"The connected provider is temporarily rate limited.":"Nango request failed.",s,s===429?"upstream_rate_limited":s===404?"connection_not_found":"connection_transport_unavailable",s===429||s>=500,s===429?Ue(`retry-after: ${i.headers.get("retry-after")??""}`):null)}return o}function k(e){let t=m(e);return t?t.normalize("NFKC").toLowerCase():null}function pt(e,t){let n=_(e),i=_(n?.tags),r=_(n?.end_user),o=k(t);if(!o)return!1;let s=[k(i?.end_user_email),k(r?.email)].filter(d=>!!d);if(s.some(d=>d!==o))return!1;let a=[k(i?.end_user_id),k(r?.id)].filter(d=>!!d&&d.includes("@"));return a.some(d=>d!==o)?!1:s.length>0?s.includes(o):a.includes(o)}function _t(e){let t=_(e),n=m(t?.connection_id),i=m(t?.provider_config_key);if(!n||!i)return null;let o=(Array.isArray(t?.errors)?t.errors:[]).some(s=>m(_(s)?.type)==="auth");return{upstreamConnectionId:n,providerConfigKey:i,provider:m(t?.provider)??i,label:null,lifecycleStatus:o?"needs_reauth":"connected",reconnectRequired:o,createdAt:m(t?.created_at)??m(t?.created),updatedAt:m(t?.updated_at)}}var gt=new Set(["facebook","github-getting-started","google-analytics","google-calendar","google-drive","google-mail","google-search-console","linkedin","meta-marketing-api","slack","twitter-v2","xero","youtube","zoom"]);function ft(e){let t=m(e);return t||(typeof e=="number"&&Number.isFinite(e)?String(e):null)}function R(e){let t=m(e)?.toLowerCase()??null;return t&&/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(t)?t:null}function v(e){return e.id||e.email||e.name?e:null}async function h(e){return A(`/proxy${e.path}`,{query:e.query,headers:{"connection-id":e.upstreamConnectionId,"provider-config-key":e.providerConfigKey,...e.baseUrlOverride?{"base-url-override":e.baseUrlOverride}:{}}})}var Et=[{method:"GET",pattern:/^\/gmail\/v1\/users\/me\/messages$/},{method:"GET",pattern:/^\/gmail\/v1\/users\/me\/messages\/[A-Za-z0-9_-]+$/},{method:"GET",pattern:/^\/gmail\/v1\/users\/me\/messages\/[A-Za-z0-9_-]+\/attachments\/[A-Za-z0-9_-]+$/},{method:"GET",pattern:/^\/gmail\/v1\/users\/me\/labels$/},{method:"POST",pattern:/^\/gmail\/v1\/users\/me\/messages\/batchModify$/},{method:"POST",pattern:/^\/gmail\/v1\/users\/me\/messages\/batchDelete$/},{method:"POST",pattern:/^\/gmail\/v1\/users\/me\/messages\/send$/},{method:"POST",pattern:/^\/gmail\/v1\/users\/me\/messages\/[A-Za-z0-9_-]+\/(?:trash|untrash)$/}],yt=new Set(["q","maxResults","pageToken","format","metadataHeaders","fields"]);async function Ln(e){let t=await V(e.identity,e.connectionId);if(t.providerConfigKey!=="google-mail")throw new g("Service connection not found.",404,"connection_not_found",!1);if(!Et.some(d=>d.method===e.method&&d.pattern.test(e.path)))throw new g("The Gmail provider operation is not allowed.",403,"tool_not_allowed",!1);if(Object.keys(e.query??{}).some(d=>!yt.has(d)))throw new g("The Gmail provider query is not allowed.",400,"invalid_request",!1);let n=e.method==="POST";if(n&&!t.actionsEnabled)throw new g("Actions are disabled for this service connection.",403,"actions_disabled",!1);await ae({identity:e.identity,ratePolicyVersion:b});let i=e.requestId?.trim()||Oe(),r=`main-gmail-proxy:${O("sha256").update(e.identity.toLowerCase()).update("\0").update(t.id).update("\0").update(e.method).update("\0").update(e.path).update("\0").update(i).digest("hex")}`,o=performance.now(),s,a;try{s=await A(`/proxy${e.path}`,{method:e.method,query:e.query,body:e.body,headers:{"connection-id":t.upstreamConnectionId,"provider-config-key":"google-mail","base-url-override":"https://gmail.googleapis.com"}})}catch(d){a=d}if(await ce({identity:e.identity,idempotencyKey:r,ratePolicyVersion:b,connectionId:t.id,providerConfigKey:t.providerConfigKey,functionRuns:0,proxyRequests:1,computeMilliseconds:Math.max(0,Math.round(performance.now()-o)),sourceSurface:"main_mcp",metadata:{operationKind:n?"action":"read",outcome:a?"error":"success",requestId:i.length<=200?i:O("sha256").update(i).digest("hex")}}),a)throw De(a);return s}async function bt(e){let t=(n,i,r)=>h({...e,path:n,query:i,baseUrlOverride:r});try{if(e.providerConfigKey==="google-mail"){let n=_(await t("/gmail/v1/users/me/profile",void 0,"https://gmail.googleapis.com")),i=R(n?.emailAddress);return v({id:i,email:i,name:null})}if(e.providerConfigKey==="google-drive"){let n=_(await t("/drive/v3/about",{fields:"user(permissionId,displayName,emailAddress)"},"https://www.googleapis.com")),i=_(n?.user);return v({id:m(i?.permissionId),email:R(i?.emailAddress),name:m(i?.displayName)})}if(e.providerConfigKey==="google-calendar"){let n=_(await t("/calendar/v3/calendars/primary",void 0,"https://www.googleapis.com")),i=m(n?.id);return v({id:i,email:R(i),name:m(n?.summary)})}if(e.providerConfigKey==="youtube"){let n=_(await t("/youtube/v3/channels",{part:"snippet",mine:"true",maxResults:1},"https://www.googleapis.com")),i=Array.isArray(n?.items)?_(n.items[0]):null;return v({id:m(i?.id),email:null,name:m(_(i?.snippet)?.title)})}}catch{}try{let n=_(await t("/v1/userinfo",void 0,"https://openidconnect.googleapis.com"));return v({id:m(n?.sub),email:n?.email_verified===!1?null:R(n?.email),name:m(n?.name)})}catch{return null}}async function Tt(e){if(!gt.has(e.providerConfigKey))return null;if(e.providerConfigKey.startsWith("google-")||e.providerConfigKey==="youtube")return bt(e);try{if(e.providerConfigKey==="github-getting-started"){let t=_(await h({...e,path:"/user"}));return v({id:ft(t?.id),email:R(t?.email),name:m(t?.name)??m(t?.login)})}if(e.providerConfigKey==="slack"){let t=_(await h({...e,path:"/api/auth.test"}));return v({id:m(t?.user_id),email:null,name:[m(t?.user),m(t?.team)].filter(Boolean).join(" \xB7 ")||null})}if(e.providerConfigKey==="zoom"){let t=_(await h({...e,path:"/v2/users/me"})),n=[m(t?.first_name),m(t?.last_name)].filter(Boolean).join(" ");return v({id:m(t?.id),email:R(t?.email),name:m(t?.display_name)??(n||null)})}if(e.providerConfigKey==="linkedin"){let t=_(await h({...e,path:"/v2/userinfo"}));return v({id:m(t?.sub),email:t?.email_verified===!1?null:R(t?.email),name:m(t?.name)})}if(e.providerConfigKey==="meta-marketing-api"||e.providerConfigKey==="facebook"){let t=_(await h({...e,path:"/me",query:{fields:"id,name,email"}}));return v({id:m(t?.id),email:R(t?.email),name:m(t?.name)})}if(e.providerConfigKey==="twitter-v2"){let t=_(await h({...e,path:"/2/users/me",query:{"user.fields":"id,name,username"}})),n=_(t?.data);return v({id:m(n?.id),email:null,name:m(n?.username)??m(n?.name)})}if(e.providerConfigKey==="xero"){let t=await h({...e,path:"/connections"}),n=Array.isArray(t)?_(t[0]):null;return v({id:m(n?.tenantId),email:null,name:m(n?.tenantName)})}}catch{return null}return null}async function Un(e,t={}){let n=[];for(let a=0;a<st;a+=1){let d=await A("/connections",{query:{limit:Ie,page:a}}),c=le(d,"connections");if(n.push(...c),c.length<Ie)break}let i=n.filter(a=>pt(a,e)).map(_t).filter(a=>a!==null),o=(await ee(e,i)).filter(a=>!G(a.providerConfigKey));if(t.resolveProviderIdentity===!1)return o;let s=new Map(i.map(a=>[`${a.providerConfigKey}\0${a.upstreamConnectionId}`,a]));return await Promise.all(o.map(async a=>{if(a.lifecycleStatus!=="connected"||!a.upstreamConnectionId)return;let d=s.get(`${a.providerConfigKey}\0${a.upstreamConnectionId}`);if(!d)return;let c=d.updatedAt??d.createdAt??a.lifecycleStatus,u=!!(a.providerAccountId||a.providerAccountEmail||a.providerAccountName),p=a.providerIdentityCheckedAt?Date.parse(`${a.providerIdentityCheckedAt.replace(" ","T")}Z`):Number.NaN,f=!u&&Number.isFinite(p)&&Date.now()-p<at;if(a.providerIdentitySourceUpdatedAt===c&&(u||f))return;let y=await Tt({upstreamConnectionId:a.upstreamConnectionId,providerConfigKey:a.providerConfigKey});await we({connectionId:a.id,providerAccountId:y?.id,providerAccountEmail:y?.email,providerAccountName:y?.name,sourceUpdatedAt:c})})),(await ee(e,i)).filter(a=>!G(a.providerConfigKey))}async function Dn(){let[e,t]=await Promise.all([A("/integrations"),A("/providers")]),n=new Map;for(let i of le(t,"providers")){let r=_(i),o=m(r?.name);r&&o&&n.set(o,r)}return le(e,"integrations").flatMap(i=>{let r=_(i),o=m(r?.unique_key)??m(r?.id),s=m(r?.provider);if(!o||!s||G(o))return[];let a=n.get(s);return[{id:o,provider:s,displayName:m(r?.display_name)??m(a?.display_name)??o,authMode:m(a?.auth_mode),categories:Array.isArray(a?.categories)?a.categories:[],docsUrl:m(a?.docs),logoUrl:m(r?.logo),safeDefaultAllowedTools:[],actionTools:[],setupStatus:"ready"}]})}function Me(e){let n={linkedin:"openid profile email w_member_social","github-getting-started":"repo workflow read:org read:user user:email","google-drive":"openid profile email https://www.googleapis.com/auth/drive","google-search-console":"openid profile email https://www.googleapis.com/auth/webmasters.readonly https://www.googleapis.com/auth/webmasters"}[e];return n?{[e]:{connection_config:{oauth_scopes_override:n}}}:void 0}function qe(e){let t=_(e),n=_(t?.data)??t,i=m(n?.connect_link);if(!i)throw new g("Nango did not return a connect link.",502,"nango_missing_connect_link");return{connectLink:i,expiresAt:m(n?.expires_at)}}async function Pn(e,t){Le(t);let n=Me(t);return qe(await A("/connect/sessions",{method:"POST",body:{tags:{end_user_id:e,end_user_email:e},allowed_integrations:[t],...n?{integrations_config_defaults:n}:{}}}))}async function kn(e,t){let n=await V(e,t,!0),i=Me(n.providerConfigKey);return qe(await A("/connect/sessions/reconnect",{method:"POST",body:{connection_id:n.upstreamConnectionId,integration_id:n.providerConfigKey,tags:{end_user_id:e,end_user_email:e},...i?{integrations_config_defaults:i}:{}}}))}async function Mn(e,t){let n=await Fe(e,t);try{await A(`/connections/${encodeURIComponent(n.upstreamConnectionId)}`,{method:"DELETE",query:{provider_config_key:n.providerConfigKey}})}catch(i){if(!(i instanceof g)||i.status!==404)throw i}}async function Fe(e,t){let n=await S(e,t);if(!n||n.transport!=="nango"||!n.upstreamConnectionId)throw new g("Service connection not found.",404,"connection_not_found",!1);return n}async function V(e,t,n=!1){let i=await Fe(e,t);if(Le(i.providerConfigKey),i.lifecycleStatus!=="connected"&&!(n&&i.lifecycleStatus==="needs_reauth"))throw new g("Service connection requires reconnection.",409,"connection_inactive",!1);return i}async function me(e,t){let n=new nt(ke(),{requestInit:{headers:{Authorization:`Bearer ${Pe()}`,"connection-id":e.upstreamConnectionId,"provider-config-key":e.providerConfigKey}}}),i=new tt({name:"mcp-scraper-integrations",version:"1.0.0"},{capabilities:{}});try{await i.connect(n);let r=await t(i);return await te({connectionId:e.id,operationalStatus:"available",evidenceSource:"nango_mcp"}),r}catch(r){let o=De(r);throw await te({connectionId:e.id,operationalStatus:o.code==="connection_transport_unavailable"?"unavailable":"degraded",failureCode:o.code,retryable:o.retryable,evidenceSource:"nango_mcp"}).catch(()=>{}),o}finally{await i.close().catch(()=>{})}}async function qn(e,t){let n=await V(e,t);(n.provider??n.providerConfigKey)==="google-search-console"&&await me(n,async r=>{if(!(await r.listTools()).tools.some(s=>s.name==="list-sites"))throw new g("The Search Console health-check tool is unavailable.",404,"live_tool_missing",!1);await r.callTool({name:"list-sites",arguments:{}})})}async function He(e,t){let n=await V(e,t),r=(await me(n,u=>u.listTools())).tools.flatMap(u=>{let p=_(u.inputSchema);return!u.name||!p?[]:[{name:u.name,...u.title?{title:u.title}:{},...u.description?{description:u.description}:{},inputSchema:p,..._(u.outputSchema)?{outputSchema:_(u.outputSchema)}:{},..._(u.annotations)?{annotations:_(u.annotations)}:{}}]}),o=B({tools:r,connectionActive:n.lifecycleStatus==="connected",actionsEnabled:n.actionsEnabled}),s=[...o.values()].filter(u=>u.classification==="read").map(u=>u.name),a=[...o.values()].filter(u=>u.classification==="action").map(u=>u.name),d=O("sha256").update(JSON.stringify(r.map(u=>({name:u.name,inputSchema:u.inputSchema})))).digest("hex");return await ve(n.id,s,a,d),{connection:await S(e,n.id)??{...n,readTools:s,actionTools:a,toolRevision:d},tools:r}}async function Fn(e){let{connection:t,tools:n}=await He(e.identity,e.connectionId),i=n.find(f=>f.name===e.tool);if(!i)throw new g("The requested provider tool is unavailable.",404,"live_tool_missing",!1);let r=de(B({tools:n,connectionActive:t.lifecycleStatus==="connected",actionsEnabled:t.actionsEnabled}),i.name);if(r.classification!==e.classification)throw new g("The provider tool classification does not match this operation.",403,"tool_not_allowed",!1);if(!r.available&&r.blockedReason==="actions_disabled")throw new g("Actions are disabled for this service connection.",403,"actions_disabled",!1);if(!r.available)throw new g("The provider tool is not authorized for this connection.",403,"tool_not_allowed",!1);await ae({identity:e.identity,ratePolicyVersion:b});let o=e.requestId?.trim()||Oe(),s=`main-nango:${O("sha256").update(e.identity.toLowerCase()).update("\0").update(t.id).update("\0").update(e.tool).update("\0").update(o).digest("hex")}`,a=new Date,d=performance.now(),c,u;try{c=await me(t,f=>mt(f,e.tool,e.input))}catch(f){u=f}let p=new Date;if(await ce({identity:e.identity,idempotencyKey:s,ratePolicyVersion:b,connectionId:t.id,providerConfigKey:t.providerConfigKey,functionRuns:1,proxyRequests:0,computeMilliseconds:Math.max(0,Math.round(performance.now()-d)),sourceSurface:"main_mcp",metadata:{toolName:e.tool,operationKind:e.operationKind??e.classification,outcome:u?"error":"partial",requestId:o.length<=200?o:O("sha256").update(o).digest("hex"),startedAt:a.toISOString(),completedAt:p.toISOString()}}),u)throw u;return c}async function Hn(e,t,n){let{connection:i,tools:r}=await He(e,t),o=r.find(u=>u.name===n);if(!o)throw new g("The requested provider tool is unavailable.",404,"live_tool_missing",!1);let s=de(B({tools:r,connectionActive:i.lifecycleStatus==="connected",actionsEnabled:i.actionsEnabled}),o.name),a=ue(o),d=s.available,c={name:o.name,...o.title?{title:o.title}:{},...o.description?{description:o.description}:{},inputSchema:o.inputSchema,...o.outputSchema?{outputSchema:o.outputSchema}:{},...o.annotations?{annotations:o.annotations}:{}};return{...c,classification:a,callable:d,blockedReason:s.blockedReason,requiredPermissions:s.requiredPermissions,missingPermissions:s.missingPermissions,requiredFeatures:s.requiredFeatures,missingFeatures:s.missingFeatures,transport:"nango",providerConfigKey:i.providerConfigKey,providerContractVersion:ut,providerContractHash:dt,protocolVersion:null,schemaSource:"live_tools_list",schemaHash:O("sha256").update(JSON.stringify(c)).digest("hex"),fetchedAt:new Date().toISOString()}}export{an as a,cn as b,un as c,dn as d,ln as e,mn as f,pn as g,D as h,Ct as i,K as j,X as k,St as l,Nt as m,ht as n,Rt as o,At as p,xt as q,It as r,Ot as s,Lt as t,Ut as u,Dt as v,Pt as w,kt as x,Mt as y,Qt as z,$e as A,je as B,T as C,ae as D,ce as E,Cn as F,Kt as G,C as H,Ke as I,S as J,Xt as K,Bt as L,Gt as M,Vt as N,$t as O,g as P,G as Q,Le as R,Ln as S,Un as T,Dn as U,Pn as V,kn as W,Mn as X,qn as Y,He as Z,Fn as _,Hn as $};