mcp-scraper 0.96.0 → 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 (41) hide show
  1. package/CHANGELOG.md +20 -1
  2. package/README.md +3 -1
  3. package/dist/{actions-YCMJY3PF.js → actions-R4EJDLRO.js} +1 -1
  4. package/dist/bin/api-server.js +1 -1
  5. package/dist/bin/mcp-scraper-cli.js +1 -1
  6. package/dist/bin/mcp-scraper-core.js +1 -1
  7. package/dist/bin/mcp-scraper-install.js +1 -1
  8. package/dist/bin/mcp-stdio-server.js +1 -1
  9. package/dist/bin/paa-harvest.js +1 -1
  10. package/dist/{bundle-TTJP6DHU.js → bundle-FCXZMIRB.js} +1 -1
  11. package/dist/{chunk-ZPQNY5TI.js → chunk-5LYINW7Z.js} +8 -1
  12. package/dist/{chunk-R5LJL6IR.js → chunk-6BD75VKS.js} +30 -37
  13. package/dist/{chunk-6SNOUSSZ.js → chunk-7WPCGRD7.js} +1 -1
  14. package/dist/{chunk-DGAW7FD7.js → chunk-BPKTUCV7.js} +1 -1
  15. package/dist/{chunk-QWE7VKIX.js → chunk-CORWWDHL.js} +1 -1
  16. package/dist/chunk-CVQUHVHX.js +1 -0
  17. package/dist/{chunk-VAC3SQ5T.js → chunk-FB4KBB5W.js} +1 -1
  18. package/dist/{chunk-HJIOH7HF.js → chunk-H6MODA7W.js} +2 -2
  19. package/dist/{chunk-JAV5V3JT.js → chunk-HVQZRQRJ.js} +19 -19
  20. package/dist/{chunk-2PRH4Z3N.js → chunk-IY6ZUUY7.js} +29 -37
  21. package/dist/chunk-JHT6A4U6.js +11 -0
  22. package/dist/{chunk-ARSQZCTJ.js → chunk-RIHI3KH7.js} +255 -245
  23. package/dist/{chunk-LFRAA3MY.js → chunk-RN4VG3VH.js} +1 -1
  24. package/dist/{chunk-SNJR5N36.js → chunk-RYX4FJVH.js} +1 -1
  25. package/dist/{chunk-JW4GDY7S.js → chunk-SE4VKLEC.js} +1 -1
  26. package/dist/{chunk-TPN25AFZ.js → chunk-SFUOSJ3A.js} +1 -1
  27. package/dist/{chunk-GVYGAZV7.js → chunk-UXNR3K6I.js} +1 -1
  28. package/dist/{chunk-FRXKMOXI.js → chunk-ZTMQEDIB.js} +1 -1
  29. package/dist/{dispatch-3HY4735M.js → dispatch-P7IY75LH.js} +1 -1
  30. package/dist/index.cjs +36 -36
  31. package/dist/index.d.cts +3 -0
  32. package/dist/index.d.ts +3 -0
  33. package/dist/index.js +1 -1
  34. package/dist/{queue-HUP2GNXF.js → queue-AC4XKD6Z.js} +1 -1
  35. package/dist/{reconciliation-ANXNJWME.js → reconciliation-UZUZ6B74.js} +1 -1
  36. package/dist/{server-VQU6S24A.js → server-DXZ27KQO.js} +488 -488
  37. package/dist/{settlement-6CCE2PDH.js → settlement-6CS4JZTY.js} +1 -1
  38. package/dist/{worker-5G5BK23B.js → worker-ATRD6VKM.js} +1 -1
  39. package/package.json +1 -1
  40. package/dist/chunk-7UHDOIUE.js +0 -1
  41. package/dist/chunk-OB6E6UTD.js +0 -1
@@ -1,4 +1,4 @@
1
- import{H as sn,_ as an,c as Yt,j as ut,k as je,m as nn,z as rn}from"./chunk-TPN25AFZ.js";import{B as gn,a as f,b as v,c as ue,d as Oe,e as yt,f as ln,g as un,h as U,i as $,l as _n,m as mn,n as pn,p as gt,u as B,v as Q,z as yn}from"./chunk-NNOX3FYG.js";import{a as qe}from"./chunk-NALXKTUU.js";import{a as Kt,b as Jt,h as zt}from"./chunk-R5LJL6IR.js";import{d as on,g as He,i as We,k as _t,m as mt,o as cn,r as Be,t as dn,u as pt}from"./chunk-2IATUJO6.js";import{D as L,E as Qt,N as Zt,O as en,P as Re,Q as dt,R as tn,S as lt,U as te,W as le,p as Fe,q as Gt,v as Xt,z as ct}from"./chunk-QWE7VKIX.js";import{b as Ue}from"./chunk-ZPQNY5TI.js";import{a as I}from"./chunk-WNUXMPVX.js";import{randomUUID as Fi}from"crypto";async function fn(e,t,n){return(await I().execute({sql:`INSERT OR IGNORE INTO stripe_events
1
+ import{H as sn,_ as an,c as Yt,j as ut,k as je,m as nn,z as rn}from"./chunk-SFUOSJ3A.js";import{B as gn,a as f,b as v,c as ue,d as Oe,e as yt,f as ln,g as un,h as U,i as $,l as _n,m as mn,n as pn,p as gt,u as B,v as Q,z as yn}from"./chunk-NNOX3FYG.js";import{a as qe}from"./chunk-NALXKTUU.js";import{a as Kt,b as Jt,f as zt}from"./chunk-6BD75VKS.js";import{d as on,g as He,i as We,k as _t,m as mt,o as cn,r as Be,t as dn,u as pt}from"./chunk-2IATUJO6.js";import{D as L,E as Qt,N as Zt,O as en,P as Re,Q as dt,R as tn,S as lt,U as te,W as le,p as Fe,q as Gt,v as Xt,z as ct}from"./chunk-CORWWDHL.js";import{f as Ue}from"./chunk-5LYINW7Z.js";import{a as I}from"./chunk-WNUXMPVX.js";import{randomUUID as Fi}from"crypto";async function fn(e,t,n){return(await I().execute({sql:`INSERT OR IGNORE INTO stripe_events
2
2
  (event_id, event_type, stripe_created_at, status, attempt_count, received_at, next_attempt_at, processed_at, updated_at)
3
3
  VALUES (?, ?, ?, 'pending', 0, datetime('now'), datetime('now'), datetime('now'), datetime('now'))`,args:[e,t,n]})).rowsAffected===1?"queued":"duplicate"}async function ra(e=50,t=300){let n=Math.max(1,Math.min(500,Math.trunc(e))),i=await I().execute({sql:`SELECT event_id
4
4
  FROM stripe_events
@@ -932,4 +932,4 @@ MCowBQYDK2VwAyEAi2HR1srL4o18O8BRa7gVJY7G7bupbN3H9AwJrHCDiOg=
932
932
  )
933
933
  ORDER BY edge.confidence DESC, edge.last_seen_at DESC
934
934
  LIMIT 1
935
- FOR SHARE OF p, ns, cs, receipt`,[t.siteId,$("customer_id",t.stableUserId)])).rows[0]??null}async function Wt(e,t){let n=process.env.MCP_SCRAPER_XRAY_SITE_ID?.trim();if(!n)return{status:"skipped",eventName:Pe,reason:"site_not_configured"};if(!Ws(n))return{status:"skipped",eventName:Pe,reason:"site_id_invalid"};let i=String(e.userId).trim();if(!i||!e.invoiceId.trim()||!Number.isSafeInteger(e.amountPaidMinor)||e.amountPaidMinor<0||!/^[a-z]{3}$/i.test(e.currency)||!Number.isFinite(new Date(e.occurredAt).getTime()))throw new Error("analytics_first_party_outcome_invalid");let r=t??{db:v(),record:(a,o)=>Ai({...a,transactionClient:o})},s=await r.db.connect();try{await s.query("BEGIN");let a=await Bs(s,{siteId:n,stableUserId:i});if(!a)return await s.query("ROLLBACK"),{status:"skipped",eventName:Pe,reason:"identity_or_consent_unavailable"};let o={schemaVersion:1,eventId:`mcp_invoice_${e.invoiceId}`.slice(0,200),sourceEventId:`stripe:invoice:${e.invoiceId}`.slice(0,300),source:"mcp_scraper",sourceAccountRef:"first_party_billing",eventKind:"transaction",eventName:Pe,occurredAt:e.occurredAt,personRef:i,orderId:e.invoiceId,valueMinor:e.amountPaidMinor,currency:e.currency.toUpperCase(),consent:{analytics:"granted",adUserData:"granted",adPersonalization:a.advertising_measurement?"granted":"denied",globalPrivacyControl:!1,occurredAt:new Date(a.effective_at).toISOString(),receiptId:a.receipt_id,policyVersion:a.policy_version,purposes:{site_analytics:"granted",enhanced_matching:"granted",advertising_measurement:a.advertising_measurement?"granted":"denied"}},properties:{product:"mcp_scraper",billingKind:"base_plan_paid_invoice",revenueProvenance:"stripe_paid_invoice"}},c=await r.record({siteId:n,event:o},s);return await s.query("COMMIT"),{status:"recorded",eventName:Pe,reason:"recorded",created:c.created,conversionIds:c.conversionIds}}catch(a){throw await s.query("ROLLBACK").catch(()=>{}),a}finally{s.release()}}function Si(e,t){return e&&(t??0)>0}function hi(e){let t=e;return t?.price?.id??t?.pricing?.price_details?.price??t?.plan?.id}function Ce(e){if(typeof e=="string")return e;if(e&&typeof e=="object"&&"id"in e)return String(e.id)}function Vs(e){let t=e.subscription;if(t)return Ce(t);let n=e.parent;return Ce(n?.subscription_details?.subscription)}async function Ks(e,t){let n=await P(e);return n||!t||(n=await je(t),n&&await Ve(n.id,e)),n}async function Js(e,t,n){let i=t.memory_subscription_id;if(!(!i||i===n))try{let r=await e.subscriptions.retrieve(i);r.status!=="canceled"&&!r.cancel_at_period_end&&await e.subscriptions.update(i,{cancel_at_period_end:!0})}catch(r){console.error("[stripe] could not wind down standalone memory subscription",i,r instanceof Error?r.message:r)}}async function Bt(e,t,n){if(!t.id||t.status!=="paid")return{status:"not_applicable",invoiceId:t.id??null};let i=t.lines.data.some(p=>{let E=hi(p);return!!E&&E in L});if(!Si(i,t.total))return{status:"not_applicable",invoiceId:t.id};let r=Vs(t),a=(r?me(await e.subscriptions.retrieve(r))?.price?.id:void 0)??t.lines.data.map(hi).find(p=>!!p&&p in L),o=a?L[a]:void 0;if(!o)return{status:"not_applicable",invoiceId:t.id};let c=Ce(t.customer);if(!c)throw new Error("Paid subscription invoice has no Stripe customer");let l=await Ks(c,t.customer_email);if(!l)throw new Error("Paid subscription invoice does not map to an MCP Scraper account");let _=await vn({invoiceId:t.id,userId:l.id,subscriptionId:r??l.subscription_id,tier:o.tier,concurrency:o.concurrency,creditsMc:o.credits_mc,description:`${o.label} subscription credits`,neverExpires:!!o.credits_never_expire,includedMemoryPlan:o.includes_memory?"pro":null});o.includes_memory&&(await Js(e,l,r??l.subscription_id),await Z(l,V({...l,memory_plan:"pro",subscription_tier:o.tier})));let d=await Je(l);d.ok||console.warn("[stripe] scheduled-action credential sync failed:",d.error??"unknown error");try{await Wt({userId:l.id,invoiceId:t.id,amountPaidMinor:t.amount_paid,currency:t.currency,occurredAt:new Date(((t.status_transitions?.paid_at??n)||Math.floor(Date.now()/1e3))*1e3).toISOString()})}catch(p){console.error("[stripe] X-Ray paid outcome failed",{invoiceId:t.id,error:p instanceof Error?p.message:String(p)})}return{status:_.granted?"fulfilled":"already_fulfilled",invoiceId:t.id,userId:l.id,tier:o.tier}}async function Ni(e,t,n){let i=await e.checkout.sessions.retrieve(t,{expand:["invoice"]});if(i.mode!=="subscription")throw new Error("Checkout session is not a subscription purchase");if(i.payment_status!=="paid"&&i.payment_status!=="no_payment_required")return{status:"not_applicable",invoiceId:Ce(i.invoice)??null};let r=Ce(i.customer);if(n&&r!==n)throw new Error("Checkout session does not belong to this billing account");let s=typeof i.invoice=="object"&&i.invoice&&!("deleted"in i.invoice)?i.invoice:await e.invoices.retrieve(Ce(i.invoice)??"");if(!s?.id)throw new Error("Paid subscription checkout has no invoice");return Bt(e,s,i.created)}var Ci="scale_credit_pack";function ot(e){if(typeof e=="string")return e;if(e&&typeof e=="object"&&"id"in e)return String(e.id)}function wi(e){let t=Number(e);if(!Number.isSafeInteger(t)||t<1||t>lt)throw new Error(`quantity must be a whole number from 1 to ${lt}`);return t}function Vd(e){return e.subscription_tier==="scale"}function Kd(e,t){let n=wi(t);return{purchase_kind:Ci,account_user_id:String(e),eligible_tier:"scale",increment_quantity:String(n),increment_usd:String(Re),credits_per_increment:String(dt)}}async function Ri(e,t,n){let i=await e.checkout.sessions.retrieve(t);if(i.mode!=="payment"||i.metadata?.purchase_kind!==Ci)return{status:"not_applicable",paymentIntentId:ot(i.payment_intent)??null};if(i.payment_status!=="paid")return{status:"not_applicable",paymentIntentId:ot(i.payment_intent)??null};let r=ot(i.customer);if(!r)throw new Error("Paid Scale credit-pack checkout has no Stripe customer");if(n&&r!==n)throw new Error("Checkout session does not belong to this billing account");let s=wi(i.metadata.increment_quantity),a=s*Re*100;if(i.currency!=="usd"||i.amount_subtotal!==a)throw new Error("Scale credit-pack checkout amount does not match the product contract");let o=await e.checkout.sessions.listLineItems(i.id,{limit:2}),c=o.data[0];if(o.data.length!==1||c?.quantity!==s||c.price?.currency!=="usd"||c.price?.unit_amount!==Re*100)throw new Error("Scale credit-pack checkout line item does not match the product contract");let l=await P(r);if(!l)throw new Error("Paid Scale credit-pack checkout does not map to an MCP Scraper account");if(i.metadata.account_user_id!==String(l.id)||i.metadata.eligible_tier!=="scale")throw new Error("Scale credit-pack checkout account metadata does not match the billing account");let _=ot(i.payment_intent);if(!_)throw new Error("Paid Scale credit-pack checkout has no payment intent");let d=s*dt;return{status:(await Yt(l.id,s*tn,Ue.TOPUP,`$${s*Re} Scale credit pack (${d.toLocaleString("en-US")} credits)`,`stripe-payment-intent:${_}`,{neverExpires:!1})).duplicate?"already_fulfilled":"fulfilled",paymentIntentId:_,userId:l.id,quantity:s,credits:d}}var M=new zs(process.env.STRIPE_SECRET_KEY,{apiVersion:"2026-02-25.clover"});async function Xs(e,t){if(!(!e||e===t))try{let n=await M.subscriptions.retrieve(e),i=n.items.data[0]?.price?.id,r=n.status!=="canceled"&&!n.cancel_at_period_end;i&&i in le&&r&&await M.subscriptions.update(e,{cancel_at_period_end:!0})}catch(n){console.error("[stripe] could not wind down standalone memory subscription",e,n instanceof Error?n.message:n)}}var Qs=new Ys;Qs.post("/webhooks",async e=>{let t=e.req.header("stripe-signature"),n=await e.req.text(),i;try{i=M.webhooks.constructEvent(n,t,process.env.STRIPE_WEBHOOK_SECRET)}catch{return e.json({error:"Invalid signature"},400)}try{let r=await fn(i.id,i.type,i.created);return r==="queued"&&Zs(),e.json({received:!0,disposition:r})}catch(r){let s=r instanceof Error?r.message:String(r);return console.error("[stripe] webhook enqueue failed",i.id,s),e.json({error:"Webhook enqueue failed"},500)}});function Zs(){let e=import("./queue-HUP2GNXF.js").then(({drainStripeEventQueue:t})=>t({limit:10,leaseSeconds:300})).catch(t=>{console.error("[stripe] immediate queue drain failed; the scheduled drain will retry",t instanceof Error?t.message:String(t))});Gs(e)}async function ol(e){if(e.type==="checkout.session.completed"||e.type==="checkout.session.async_payment_succeeded"){let t=e.data.object;t.mode==="payment"?await Ri(M,t.id):await Ni(M,t.id);return}if(e.type==="invoice.created"){let t=e.data.object;Oi(t)&&t.status==="draft"&&await M.invoices.update(t.id,{description:Zt,footer:en,custom_fields:[{name:"Pack benefit",value:"2 browsers per $5 monthly pack"},{name:"Billing cadence",value:"Monthly"}]});return}if(e.type==="invoice.paid"||e.type==="invoice.payment_succeeded"){let t=e.data.object;if(Oi(t)){let i=t.customer_email?void 0:await Ti(t.customer,void 0),r=t.customer_email??i?.email;if(!r)throw new Error("Paid concurrency invoice has no customer receipt email");await ea(t.id,r);return}if(t.lines.data.map(xi).find(i=>i&&i in le))return;await Bt(M,t,e.created)}if(e.type==="customer.subscription.created"||e.type==="customer.subscription.updated"){let t=e.data.object,n=Di(t);if(n){let s=await P(t.customer);if(!s)return;let a=De(t.status);await ft(s.id,a?ta(n):0),await vt(s.id,a?t.id:null);return}let i=me(t)?.price?.id??t.items.data[0]?.price?.id;if(i&&i in le){let s=le[i],a=await Ti(t.customer,t.customer_email);if(a){let o=De(t.status),c=o?s.plan:"free";await _e(a.id,c,o?t.id:null),await Z(a,V({...a,memory_plan:c}))}return}let r=await P(t.customer);if(!r)return;if(i&&i in L){let s=L[i],a=De(t.status),o=a?s.tier:null;if(await Et(r.id,o,a?s.concurrency:0,a?t.id:null),s.includes_memory){let c=a?"pro":"free";a&&await Xs(r.memory_subscription_id,t.id),await _e(r.id,c,null),await Z(r,V({...r,memory_plan:c}))}else r.memory_subscription_id===t.id&&(await _e(r.id,"free",null),await Z(r,V({...r,memory_plan:"free"})));if(a){let c=await Je(r);c.ok||console.warn("[stripe] scheduled-action credential sync failed:",c.error??"unknown error")}}}if(e.type==="customer.subscription.deleted"){let t=e.data.object;if(Di(t)){let i=await P(t.customer);i&&(await ft(i.id,0),await vt(i.id,null));return}let n=me(t)?.price?.id??t.items.data[0]?.price?.id;if(n&&n in L){let i=L[n],r=await P(t.customer);r&&(await Et(r.id,null,0,null),(i.includes_memory||r.memory_subscription_id===t.id)&&(await _e(r.id,"free",null),await Z(r,V({...r,memory_plan:"free"}))));return}if(n&&n in le||await bt(t.id)){let i=await bt(t.id)??await P(t.customer);i&&(await _e(i.id,"free",null),await Z(i,V({...i,memory_plan:"free"})));return}}}function Oi(e){return e.lines.data.some(t=>xi(t)===ct)}async function ea(e,t){let i=(await M.invoicePayments.list({invoice:e,status:"paid",limit:10})).data.find(a=>a.status==="paid");if(!i)throw new Error("Paid concurrency invoice has no paid Stripe payment");let r;if(i.payment.type==="charge")r=i.payment.charge;else if(i.payment.type==="payment_intent"&&i.payment.payment_intent){let a=typeof i.payment.payment_intent=="string"?i.payment.payment_intent:i.payment.payment_intent.id;r=(await M.paymentIntents.retrieve(a,{expand:["latest_charge"]})).latest_charge}if(!r)throw new Error("Paid concurrency invoice has no receipt-capable charge");let s=typeof r=="string"?await M.charges.retrieve(r):r;s.receipt_email!==t&&await M.charges.update(s.id,{receipt_email:t})}function Di(e){return e.items.data.find(t=>t.price?.id===ct)}function ta(e){let t=e.quantity??1;if(!Number.isSafeInteger(t)||t<1)throw new Error("Stripe concurrency pack quantity must be a positive safe integer");return t}function xi(e){let t=e;return t?.price?.id??t?.pricing?.price_details?.price??t?.plan?.id}async function Ti(e,t){let n=await P(e);if(n)return n;if(t)return n=await je(t),n&&await Ve(n.id,e),n}export{Ve as a,ft as b,vt as c,Et as d,_e as e,ma as f,Ki as g,fa as h,In as i,It as j,Na as k,Ca as l,Sn as m,ir as n,wa as o,Ra as p,rr as q,Nn as r,Je as s,ra as t,sa as u,aa as v,oa as w,ca as x,ht as y,K as z,me as A,Ma as B,Ua as C,Fa as D,Xe as E,Qe as F,Ln as G,Cr as H,Rr as I,Ct as J,Ga as K,Xa as L,Qa as M,Za as N,oo as O,Un as P,po as Q,yo as R,go as S,fo as T,vo as U,Eo as V,bo as W,Io as X,Ao as Y,So as Z,ho as _,No as $,Co as aa,jn as ba,wo as ca,Lr as da,Ro as ea,se as fa,nt as ga,F as ha,Oo as ia,Pr as ja,Lo as ka,$o as la,ko as ma,zn as na,Yn as oa,Po as pa,jo as qa,Zn as ra,qo as sa,Hr as ta,Xo as ua,fe as va,Qo as wa,uc as xa,si as ya,ai as za,yc as Aa,gc as Ba,oi as Ca,Ec as Da,ci as Ea,di as Fa,li as Ga,ui as Ha,_i as Ia,mi as Ja,at as Ka,Lc as La,$c as Ma,kc as Na,Pc as Oa,Mc as Pa,Uc as Qa,yi as Ra,gi as Sa,Ft as Ta,fi as Ua,vi as Va,Ds as Wa,cd as Xa,dd as Ya,ld as Za,ud as _a,_d as $a,md as ab,pd as bb,yd as cb,gd as db,fd as eb,vd as fb,Ed as gb,bd as hb,Id as ib,Ad as jb,Sd as kb,Ei as lb,hd as mb,Nd as nb,Ai as ob,Cd as pb,wd as qb,Bt as rb,Ni as sb,wi as tb,Vd as ub,Kd as vb,Ri as wb,M as xb,Qs as yb,ol as zb};
935
+ FOR SHARE OF p, ns, cs, receipt`,[t.siteId,$("customer_id",t.stableUserId)])).rows[0]??null}async function Wt(e,t){let n=process.env.MCP_SCRAPER_XRAY_SITE_ID?.trim();if(!n)return{status:"skipped",eventName:Pe,reason:"site_not_configured"};if(!Ws(n))return{status:"skipped",eventName:Pe,reason:"site_id_invalid"};let i=String(e.userId).trim();if(!i||!e.invoiceId.trim()||!Number.isSafeInteger(e.amountPaidMinor)||e.amountPaidMinor<0||!/^[a-z]{3}$/i.test(e.currency)||!Number.isFinite(new Date(e.occurredAt).getTime()))throw new Error("analytics_first_party_outcome_invalid");let r=t??{db:v(),record:(a,o)=>Ai({...a,transactionClient:o})},s=await r.db.connect();try{await s.query("BEGIN");let a=await Bs(s,{siteId:n,stableUserId:i});if(!a)return await s.query("ROLLBACK"),{status:"skipped",eventName:Pe,reason:"identity_or_consent_unavailable"};let o={schemaVersion:1,eventId:`mcp_invoice_${e.invoiceId}`.slice(0,200),sourceEventId:`stripe:invoice:${e.invoiceId}`.slice(0,300),source:"mcp_scraper",sourceAccountRef:"first_party_billing",eventKind:"transaction",eventName:Pe,occurredAt:e.occurredAt,personRef:i,orderId:e.invoiceId,valueMinor:e.amountPaidMinor,currency:e.currency.toUpperCase(),consent:{analytics:"granted",adUserData:"granted",adPersonalization:a.advertising_measurement?"granted":"denied",globalPrivacyControl:!1,occurredAt:new Date(a.effective_at).toISOString(),receiptId:a.receipt_id,policyVersion:a.policy_version,purposes:{site_analytics:"granted",enhanced_matching:"granted",advertising_measurement:a.advertising_measurement?"granted":"denied"}},properties:{product:"mcp_scraper",billingKind:"base_plan_paid_invoice",revenueProvenance:"stripe_paid_invoice"}},c=await r.record({siteId:n,event:o},s);return await s.query("COMMIT"),{status:"recorded",eventName:Pe,reason:"recorded",created:c.created,conversionIds:c.conversionIds}}catch(a){throw await s.query("ROLLBACK").catch(()=>{}),a}finally{s.release()}}function Si(e,t){return e&&(t??0)>0}function hi(e){let t=e;return t?.price?.id??t?.pricing?.price_details?.price??t?.plan?.id}function Ce(e){if(typeof e=="string")return e;if(e&&typeof e=="object"&&"id"in e)return String(e.id)}function Vs(e){let t=e.subscription;if(t)return Ce(t);let n=e.parent;return Ce(n?.subscription_details?.subscription)}async function Ks(e,t){let n=await P(e);return n||!t||(n=await je(t),n&&await Ve(n.id,e)),n}async function Js(e,t,n){let i=t.memory_subscription_id;if(!(!i||i===n))try{let r=await e.subscriptions.retrieve(i);r.status!=="canceled"&&!r.cancel_at_period_end&&await e.subscriptions.update(i,{cancel_at_period_end:!0})}catch(r){console.error("[stripe] could not wind down standalone memory subscription",i,r instanceof Error?r.message:r)}}async function Bt(e,t,n){if(!t.id||t.status!=="paid")return{status:"not_applicable",invoiceId:t.id??null};let i=t.lines.data.some(p=>{let E=hi(p);return!!E&&E in L});if(!Si(i,t.total))return{status:"not_applicable",invoiceId:t.id};let r=Vs(t),a=(r?me(await e.subscriptions.retrieve(r))?.price?.id:void 0)??t.lines.data.map(hi).find(p=>!!p&&p in L),o=a?L[a]:void 0;if(!o)return{status:"not_applicable",invoiceId:t.id};let c=Ce(t.customer);if(!c)throw new Error("Paid subscription invoice has no Stripe customer");let l=await Ks(c,t.customer_email);if(!l)throw new Error("Paid subscription invoice does not map to an MCP Scraper account");let _=await vn({invoiceId:t.id,userId:l.id,subscriptionId:r??l.subscription_id,tier:o.tier,concurrency:o.concurrency,creditsMc:o.credits_mc,description:`${o.label} subscription credits`,neverExpires:!!o.credits_never_expire,includedMemoryPlan:o.includes_memory?"pro":null});o.includes_memory&&(await Js(e,l,r??l.subscription_id),await Z(l,V({...l,memory_plan:"pro",subscription_tier:o.tier})));let d=await Je(l);d.ok||console.warn("[stripe] scheduled-action credential sync failed:",d.error??"unknown error");try{await Wt({userId:l.id,invoiceId:t.id,amountPaidMinor:t.amount_paid,currency:t.currency,occurredAt:new Date(((t.status_transitions?.paid_at??n)||Math.floor(Date.now()/1e3))*1e3).toISOString()})}catch(p){console.error("[stripe] X-Ray paid outcome failed",{invoiceId:t.id,error:p instanceof Error?p.message:String(p)})}return{status:_.granted?"fulfilled":"already_fulfilled",invoiceId:t.id,userId:l.id,tier:o.tier}}async function Ni(e,t,n){let i=await e.checkout.sessions.retrieve(t,{expand:["invoice"]});if(i.mode!=="subscription")throw new Error("Checkout session is not a subscription purchase");if(i.payment_status!=="paid"&&i.payment_status!=="no_payment_required")return{status:"not_applicable",invoiceId:Ce(i.invoice)??null};let r=Ce(i.customer);if(n&&r!==n)throw new Error("Checkout session does not belong to this billing account");let s=typeof i.invoice=="object"&&i.invoice&&!("deleted"in i.invoice)?i.invoice:await e.invoices.retrieve(Ce(i.invoice)??"");if(!s?.id)throw new Error("Paid subscription checkout has no invoice");return Bt(e,s,i.created)}var Ci="scale_credit_pack";function ot(e){if(typeof e=="string")return e;if(e&&typeof e=="object"&&"id"in e)return String(e.id)}function wi(e){let t=Number(e);if(!Number.isSafeInteger(t)||t<1||t>lt)throw new Error(`quantity must be a whole number from 1 to ${lt}`);return t}function Vd(e){return e.subscription_tier==="scale"}function Kd(e,t){let n=wi(t);return{purchase_kind:Ci,account_user_id:String(e),eligible_tier:"scale",increment_quantity:String(n),increment_usd:String(Re),credits_per_increment:String(dt)}}async function Ri(e,t,n){let i=await e.checkout.sessions.retrieve(t);if(i.mode!=="payment"||i.metadata?.purchase_kind!==Ci)return{status:"not_applicable",paymentIntentId:ot(i.payment_intent)??null};if(i.payment_status!=="paid")return{status:"not_applicable",paymentIntentId:ot(i.payment_intent)??null};let r=ot(i.customer);if(!r)throw new Error("Paid Scale credit-pack checkout has no Stripe customer");if(n&&r!==n)throw new Error("Checkout session does not belong to this billing account");let s=wi(i.metadata.increment_quantity),a=s*Re*100;if(i.currency!=="usd"||i.amount_subtotal!==a)throw new Error("Scale credit-pack checkout amount does not match the product contract");let o=await e.checkout.sessions.listLineItems(i.id,{limit:2}),c=o.data[0];if(o.data.length!==1||c?.quantity!==s||c.price?.currency!=="usd"||c.price?.unit_amount!==Re*100)throw new Error("Scale credit-pack checkout line item does not match the product contract");let l=await P(r);if(!l)throw new Error("Paid Scale credit-pack checkout does not map to an MCP Scraper account");if(i.metadata.account_user_id!==String(l.id)||i.metadata.eligible_tier!=="scale")throw new Error("Scale credit-pack checkout account metadata does not match the billing account");let _=ot(i.payment_intent);if(!_)throw new Error("Paid Scale credit-pack checkout has no payment intent");let d=s*dt;return{status:(await Yt(l.id,s*tn,Ue.TOPUP,`$${s*Re} Scale credit pack (${d.toLocaleString("en-US")} credits)`,`stripe-payment-intent:${_}`,{neverExpires:!1})).duplicate?"already_fulfilled":"fulfilled",paymentIntentId:_,userId:l.id,quantity:s,credits:d}}var M=new zs(process.env.STRIPE_SECRET_KEY,{apiVersion:"2026-02-25.clover"});async function Xs(e,t){if(!(!e||e===t))try{let n=await M.subscriptions.retrieve(e),i=n.items.data[0]?.price?.id,r=n.status!=="canceled"&&!n.cancel_at_period_end;i&&i in le&&r&&await M.subscriptions.update(e,{cancel_at_period_end:!0})}catch(n){console.error("[stripe] could not wind down standalone memory subscription",e,n instanceof Error?n.message:n)}}var Qs=new Ys;Qs.post("/webhooks",async e=>{let t=e.req.header("stripe-signature"),n=await e.req.text(),i;try{i=M.webhooks.constructEvent(n,t,process.env.STRIPE_WEBHOOK_SECRET)}catch{return e.json({error:"Invalid signature"},400)}try{let r=await fn(i.id,i.type,i.created);return r==="queued"&&Zs(),e.json({received:!0,disposition:r})}catch(r){let s=r instanceof Error?r.message:String(r);return console.error("[stripe] webhook enqueue failed",i.id,s),e.json({error:"Webhook enqueue failed"},500)}});function Zs(){let e=import("./queue-AC4XKD6Z.js").then(({drainStripeEventQueue:t})=>t({limit:10,leaseSeconds:300})).catch(t=>{console.error("[stripe] immediate queue drain failed; the scheduled drain will retry",t instanceof Error?t.message:String(t))});Gs(e)}async function ol(e){if(e.type==="checkout.session.completed"||e.type==="checkout.session.async_payment_succeeded"){let t=e.data.object;t.mode==="payment"?await Ri(M,t.id):await Ni(M,t.id);return}if(e.type==="invoice.created"){let t=e.data.object;Oi(t)&&t.status==="draft"&&await M.invoices.update(t.id,{description:Zt,footer:en,custom_fields:[{name:"Pack benefit",value:"2 browsers per $5 monthly pack"},{name:"Billing cadence",value:"Monthly"}]});return}if(e.type==="invoice.paid"||e.type==="invoice.payment_succeeded"){let t=e.data.object;if(Oi(t)){let i=t.customer_email?void 0:await Ti(t.customer,void 0),r=t.customer_email??i?.email;if(!r)throw new Error("Paid concurrency invoice has no customer receipt email");await ea(t.id,r);return}if(t.lines.data.map(xi).find(i=>i&&i in le))return;await Bt(M,t,e.created)}if(e.type==="customer.subscription.created"||e.type==="customer.subscription.updated"){let t=e.data.object,n=Di(t);if(n){let s=await P(t.customer);if(!s)return;let a=De(t.status);await ft(s.id,a?ta(n):0),await vt(s.id,a?t.id:null);return}let i=me(t)?.price?.id??t.items.data[0]?.price?.id;if(i&&i in le){let s=le[i],a=await Ti(t.customer,t.customer_email);if(a){let o=De(t.status),c=o?s.plan:"free";await _e(a.id,c,o?t.id:null),await Z(a,V({...a,memory_plan:c}))}return}let r=await P(t.customer);if(!r)return;if(i&&i in L){let s=L[i],a=De(t.status),o=a?s.tier:null;if(await Et(r.id,o,a?s.concurrency:0,a?t.id:null),s.includes_memory){let c=a?"pro":"free";a&&await Xs(r.memory_subscription_id,t.id),await _e(r.id,c,null),await Z(r,V({...r,memory_plan:c}))}else r.memory_subscription_id===t.id&&(await _e(r.id,"free",null),await Z(r,V({...r,memory_plan:"free"})));if(a){let c=await Je(r);c.ok||console.warn("[stripe] scheduled-action credential sync failed:",c.error??"unknown error")}}}if(e.type==="customer.subscription.deleted"){let t=e.data.object;if(Di(t)){let i=await P(t.customer);i&&(await ft(i.id,0),await vt(i.id,null));return}let n=me(t)?.price?.id??t.items.data[0]?.price?.id;if(n&&n in L){let i=L[n],r=await P(t.customer);r&&(await Et(r.id,null,0,null),(i.includes_memory||r.memory_subscription_id===t.id)&&(await _e(r.id,"free",null),await Z(r,V({...r,memory_plan:"free"}))));return}if(n&&n in le||await bt(t.id)){let i=await bt(t.id)??await P(t.customer);i&&(await _e(i.id,"free",null),await Z(i,V({...i,memory_plan:"free"})));return}}}function Oi(e){return e.lines.data.some(t=>xi(t)===ct)}async function ea(e,t){let i=(await M.invoicePayments.list({invoice:e,status:"paid",limit:10})).data.find(a=>a.status==="paid");if(!i)throw new Error("Paid concurrency invoice has no paid Stripe payment");let r;if(i.payment.type==="charge")r=i.payment.charge;else if(i.payment.type==="payment_intent"&&i.payment.payment_intent){let a=typeof i.payment.payment_intent=="string"?i.payment.payment_intent:i.payment.payment_intent.id;r=(await M.paymentIntents.retrieve(a,{expand:["latest_charge"]})).latest_charge}if(!r)throw new Error("Paid concurrency invoice has no receipt-capable charge");let s=typeof r=="string"?await M.charges.retrieve(r):r;s.receipt_email!==t&&await M.charges.update(s.id,{receipt_email:t})}function Di(e){return e.items.data.find(t=>t.price?.id===ct)}function ta(e){let t=e.quantity??1;if(!Number.isSafeInteger(t)||t<1)throw new Error("Stripe concurrency pack quantity must be a positive safe integer");return t}function xi(e){let t=e;return t?.price?.id??t?.pricing?.price_details?.price??t?.plan?.id}async function Ti(e,t){let n=await P(e);if(n)return n;if(t)return n=await je(t),n&&await Ve(n.id,e),n}export{Ve as a,ft as b,vt as c,Et as d,_e as e,ma as f,Ki as g,fa as h,In as i,It as j,Na as k,Ca as l,Sn as m,ir as n,wa as o,Ra as p,rr as q,Nn as r,Je as s,ra as t,sa as u,aa as v,oa as w,ca as x,ht as y,K as z,me as A,Ma as B,Ua as C,Fa as D,Xe as E,Qe as F,Ln as G,Cr as H,Rr as I,Ct as J,Ga as K,Xa as L,Qa as M,Za as N,oo as O,Un as P,po as Q,yo as R,go as S,fo as T,vo as U,Eo as V,bo as W,Io as X,Ao as Y,So as Z,ho as _,No as $,Co as aa,jn as ba,wo as ca,Lr as da,Ro as ea,se as fa,nt as ga,F as ha,Oo as ia,Pr as ja,Lo as ka,$o as la,ko as ma,zn as na,Yn as oa,Po as pa,jo as qa,Zn as ra,qo as sa,Hr as ta,Xo as ua,fe as va,Qo as wa,uc as xa,si as ya,ai as za,yc as Aa,gc as Ba,oi as Ca,Ec as Da,ci as Ea,di as Fa,li as Ga,ui as Ha,_i as Ia,mi as Ja,at as Ka,Lc as La,$c as Ma,kc as Na,Pc as Oa,Mc as Pa,Uc as Qa,yi as Ra,gi as Sa,Ft as Ta,fi as Ua,vi as Va,Ds as Wa,cd as Xa,dd as Ya,ld as Za,ud as _a,_d as $a,md as ab,pd as bb,yd as cb,gd as db,fd as eb,vd as fb,Ed as gb,bd as hb,Id as ib,Ad as jb,Sd as kb,Ei as lb,hd as mb,Nd as nb,Ai as ob,Cd as pb,wd as qb,Bt as rb,Ni as sb,wi as tb,Vd as ub,Kd as vb,Ri as wb,M as xb,Qs as yb,ol as zb};