mcp-scraper 0.97.1 → 0.99.0

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 (104) hide show
  1. package/CHANGELOG.md +11 -2434
  2. package/README.md +16 -412
  3. package/dist/bin/api-server.js +3 -2
  4. package/dist/bin/mcp-scraper-cli.js +33 -27
  5. package/dist/bin/mcp-scraper-core.js +9 -1
  6. package/dist/bin/mcp-scraper-install.js +17 -2
  7. package/dist/bin/mcp-stdio-server.js +9 -1
  8. package/dist/bin/paa-harvest.js +8 -1
  9. package/dist/index.cjs +5 -21830
  10. package/dist/index.d.ts +14 -607
  11. package/dist/index.js +5 -39
  12. package/dist/transport.d.ts +35 -0
  13. package/package.json +11 -51
  14. package/THIRD_PARTY_NOTICES.html +0 -203
  15. package/dist/actions-5X5CQAKO.js +0 -1
  16. package/dist/artifacts-4ZDNP2JW.js +0 -1
  17. package/dist/artifacts-N62OPIT5.js +0 -1
  18. package/dist/artifacts-PSADD5OC.js +0 -1
  19. package/dist/artifacts-RUR3OHAK.js +0 -1
  20. package/dist/blob-store-GIH26EDO.js +0 -1
  21. package/dist/bundle-GS657HXG.js +0 -1
  22. package/dist/chunk-24YDQ3EO.js +0 -5
  23. package/dist/chunk-2L7CHN5N.js +0 -4
  24. package/dist/chunk-3F7AFM53.js +0 -1
  25. package/dist/chunk-4AEW53RU.js +0 -954
  26. package/dist/chunk-4HZXATHB.js +0 -27
  27. package/dist/chunk-4YZ74SJ6.js +0 -1
  28. package/dist/chunk-4ZVO6GX4.js +0 -1
  29. package/dist/chunk-55ZANTHL.js +0 -3
  30. package/dist/chunk-5RQWFYXY.js +0 -930
  31. package/dist/chunk-5TQINRZN.js +0 -12
  32. package/dist/chunk-5UQAL7HV.js +0 -41
  33. package/dist/chunk-6D25Q5BR.js +0 -21728
  34. package/dist/chunk-6N5EC7ZO.js +0 -1
  35. package/dist/chunk-7POHNTVW.js +0 -1
  36. package/dist/chunk-7SR7MEU5.js +0 -62
  37. package/dist/chunk-ANQ4JJVI.js +0 -71
  38. package/dist/chunk-B3JRL45T.js +0 -1
  39. package/dist/chunk-B4ZKPLSP.js +0 -1
  40. package/dist/chunk-B5Y26E3A.js +0 -1
  41. package/dist/chunk-C3JWX6KM.js +0 -10
  42. package/dist/chunk-C7MGJUTU.js +0 -1
  43. package/dist/chunk-CNSVZTTT.js +0 -13
  44. package/dist/chunk-EYGA6LOU.js +0 -1
  45. package/dist/chunk-F3M7INSN.js +0 -41
  46. package/dist/chunk-FLAWC5PF.js +0 -5
  47. package/dist/chunk-FM7BX2LU.js +0 -159
  48. package/dist/chunk-HCK6PLM3.js +0 -3
  49. package/dist/chunk-HNNYXMSI.js +0 -1
  50. package/dist/chunk-IFPION5D.js +0 -121
  51. package/dist/chunk-IPQOBOFY.js +0 -1
  52. package/dist/chunk-J7XDXIB6.js +0 -163
  53. package/dist/chunk-JHDD6R3O.js +0 -8
  54. package/dist/chunk-JMZIDHYQ.js +0 -2
  55. package/dist/chunk-K3VDGJNK.js +0 -1
  56. package/dist/chunk-KBZY2OGP.js +0 -11
  57. package/dist/chunk-KJQXUZ4Y.js +0 -4
  58. package/dist/chunk-KXJCGV3H.js +0 -1
  59. package/dist/chunk-NALXKTUU.js +0 -1
  60. package/dist/chunk-NNOX3FYG.js +0 -198
  61. package/dist/chunk-NQFTETVC.js +0 -189
  62. package/dist/chunk-OILOHQNL.js +0 -2
  63. package/dist/chunk-OLYPLX5C.js +0 -1
  64. package/dist/chunk-P6CDR3RM.js +0 -1
  65. package/dist/chunk-PKQHHCO4.js +0 -20
  66. package/dist/chunk-QCBCOEH5.js +0 -1
  67. package/dist/chunk-QER2ELZP.js +0 -1
  68. package/dist/chunk-RDHGQ2WZ.js +0 -1
  69. package/dist/chunk-SDQW7IJN.js +0 -1
  70. package/dist/chunk-SEZETSB3.js +0 -1
  71. package/dist/chunk-SJNSTO3C.js +0 -42
  72. package/dist/chunk-TZYITYL4.js +0 -2
  73. package/dist/chunk-UIOSADPB.js +0 -1718
  74. package/dist/chunk-UNEJYZ4T.js +0 -102
  75. package/dist/chunk-UUJYICAJ.js +0 -1
  76. package/dist/chunk-VVSHZV5S.js +0 -73
  77. package/dist/chunk-WNUXMPVX.js +0 -1
  78. package/dist/chunk-XNTAHMPA.js +0 -218
  79. package/dist/chunk-ZDECILF6.js +0 -16
  80. package/dist/chunk-ZNPGM3XE.js +0 -4
  81. package/dist/compatibility-UPPKZ4KY.js +0 -1
  82. package/dist/contracts-GUXGFCVV.js +0 -1
  83. package/dist/core-schema-Y47YFKH2.js +0 -899
  84. package/dist/direct-completion-ZVPPEBDU.js +0 -1
  85. package/dist/dispatch-GRMMPKQD.js +0 -1
  86. package/dist/editorial-reading-room/assets/app.js +0 -433
  87. package/dist/editorial-reading-room/assets/index.html +0 -139
  88. package/dist/editorial-reading-room/assets/styles.css +0 -1091
  89. package/dist/index.d.cts +0 -607
  90. package/dist/jobs-NRZHGQ7I.js +0 -1
  91. package/dist/media-artifacts-67CJWI7O.js +0 -1
  92. package/dist/metering-YHZ46GV4.js +0 -1
  93. package/dist/migrations-3AKEC5QE.js +0 -1
  94. package/dist/queue-2VKW7SGH.js +0 -1
  95. package/dist/reconciliation-QC6SILLR.js +0 -1
  96. package/dist/report-artifact-offload-PQNFDNPL.js +0 -1
  97. package/dist/repository-CYXVMYAI.js +0 -1
  98. package/dist/repository-UKDA4IWP.js +0 -1
  99. package/dist/server-EYMJROPX.js +0 -5544
  100. package/dist/settlement-47EUTSGX.js +0 -1
  101. package/dist/vendor-errors-647LSH6H.js +0 -1
  102. package/dist/worker-AWJF7UYR.js +0 -1
  103. package/public/.well-known/xray-install.json +0 -183
  104. package/public/agent-install.md +0 -200
@@ -1,12 +0,0 @@
1
- import{a as D,c as A,d as T,e as C,f as w,g as p}from"./chunk-XNTAHMPA.js";import{C as k,D as x,E as v,b as E,g,y as I}from"./chunk-NQFTETVC.js";import{a as P,b as S}from"./chunk-4YZ74SJ6.js";import{a as _}from"./chunk-WNUXMPVX.js";import{randomUUID as O}from"crypto";var L=class{constructor(t,r,i){this.userId=t;this.sourceSurface=r;this.fence=i;if(i&&i.userId!==t)throw Error("Billing scope principal differs from execution claim")}userId;sourceSurface;fence;identity=`debit:${O()}`;charges=new Map;pending=new Map;compensating=new Set;closing=!1;async debit(t,r,i,c,a){if(this.closing||this.compensating.has(t))throw Error("Billing scope is compensating; new charges are forbidden");let s=this.charges.get(t);if(s?.outcome==="pending")throw Error("Named debit outcome is pending; reconcile before retrying");if(s?.outcome==="funded"&&s.amountMc!==r)throw Error("An applied debit amount cannot change");let o={key:s?.key??`${this.identity}:${t}`,amountMc:r,operation:i,description:c,refundOperation:a,outcome:"pending"};if(s&&(s.operation!==i||s.description!==c||s.refundOperation!==a))throw Error("Named charge identity cannot change");this.charges.set(t,o);let u=(async()=>{if(this.fence){let f=await A(this.fence,{label:t,amountMc:r,operation:i,description:c,refundOperation:a,sourceSurface:this.sourceSurface});if(o.key=f.key,this.closing||this.compensating.has(t))throw Error("Billing scope began compensating while planning")}return this.fence?w(this.userId,r,i,c,o.key,this.fence):w(this.userId,r,i,c,o.key)})();this.pending.set(t,u);try{let f=await u;return o.outcome=f.ok?"funded":"unfunded",{...f,billingKey:o.key}}finally{this.pending.delete(t)}}async compensate(t){this.compensating.add(t),await this.pending.get(t)?.catch(()=>{});try{this.fence&&await this.loadDurablePlans();let r=this.charges.get(t);if(!r)return"not_charged";let i=await C(this.userId,r.key);return i?i.amountMc!==r.amountMc||i.operation!==r.operation||i.description!==r.description?"refund_pending":i.status==="claimed"?this.fence?.mode==="compensate"||r.outcome==="unfunded"?"not_charged":"refund_pending":i.status!=="applied"?"refund_pending":(this.fence?await p(this.userId,r.key,0,r.refundOperation,`${this.sourceSurface} failed`,this.sourceSurface,this.fence):await p(this.userId,r.key,0,r.refundOperation,`${this.sourceSurface} failed`,this.sourceSurface)).final_amount_mc===0?"refunded":"refund_pending":this.fence?.mode==="compensate"||r.outcome==="unfunded"?"not_charged":"refund_pending"}catch{return"refund_pending"}}async compensateAll(){if(this.closing=!0,await Promise.allSettled([...this.pending.values()]),this.fence)try{await this.loadDurablePlans()}catch{return"refund_pending"}let t=await Promise.all([...this.charges.keys()].map(r=>this.compensate(r)));return t.includes("refund_pending")?"refund_pending":t.includes("refunded")?"refunded":"not_charged"}async loadDurablePlans(){if(this.fence)for(let t of await T(this.fence)){let r=this.charges.get(t.label);if(t.sourceSurface!==this.sourceSurface)throw Error("Persisted billing source differs from scope");this.charges.set(t.label,{key:t.key,amountMc:t.amountMc,operation:t.operation,description:t.description,refundOperation:t.refundOperation,outcome:r?.key===t.key?r.outcome:"pending"})}}};async function H(e){if(!Number.isSafeInteger(e.userId)||e.userId<=0||!Number.isSafeInteger(e.refundMc)||e.refundMc<0)throw Error("invalid_legacy_refund");await _().batch([e.admission,{sql:`INSERT INTO credit_lots (user_id, amount_mc, remaining_mc, source, expires_at)
2
- SELECT ?, ?, ?, ?, ? WHERE changes() = 1 AND ? > 0 AND datetime(?) > datetime('now')`,args:[e.userId,e.refundMc,e.refundMc,e.operation,e.expiresAt,e.refundMc,e.expiresAt]},{sql:"UPDATE users SET balance_mc = balance_mc + ? WHERE id = ? AND ? > 0 AND changes() = 1",args:[e.refundMc,e.userId,e.refundMc]},{sql:`INSERT INTO ledger (user_id, amount_mc, operation, description)
3
- SELECT ?, ?, ?, ? WHERE ? > 0 AND changes() = 1`,args:[e.userId,e.refundMc,e.operation,e.description,e.refundMc]},e.acknowledgment],"write")}function J(e){return e.status==="complete"||e.status==="partial"||e.status==="failed"}function y(e,t,r){return e.userId===t&&(e.executionGeneration??0)===r&&J(e)}function W(e){let t=e.options.xraySetupReceipt;return e.options.heldMc===0&&e.options.debitKey==null&&t?.billingClass===E&&t.consumesMcpScraperCredits===!1&&t.heldMc===0&&t.billedMc===0}function b(e,t){if(!e||!y(e,t.userId,t.generation)||JSON.stringify(e.settlementPlan)!==JSON.stringify(t))return null;let r=e.settlementReceipt;return!r||r.jobId!==t.jobId||r.userId!==t.userId||r.generation!==t.generation||e.billedMc!==r.netChargeMc?null:r}async function Q(e,t,r,i,c,a=0){let s=await g(e);if(!s||!y(s,t,a))throw Error("extract_settlement_identity_or_terminal_conflict");if(s.billedMc!=null)return s.settlementReceipt??null;let o=Number(s.options.heldMc??0);if(![o,r,i].every(d=>Number.isSafeInteger(d)&&d>=0)||r+i!==o)throw Error("extract_settlement_amount_conflict");let u=String(s.options.billingClass??"credits");if(u===E&&!W(s))throw Error("xray_extract_zero_charge_finalization_rejected");let f={version:1,jobId:e,userId:t,generation:a,status:s.status,heldMc:o,debitKey:typeof s.options.debitKey=="string"?s.options.debitKey:null,billingClass:u,netChargeMc:i,refundMc:r,reference:c},l;try{l=await k(f)}catch(d){if(l=await g(e).catch(()=>null),!l?.settlementPlan||!y(l,t,a))throw d}if(!l||!y(l,t,a)||!l.settlementPlan)throw Error("extract_settlement_admission_conflict");let n=l.settlementPlan;if(n.jobId!==e||n.userId!==t||n.generation!==a||n.status!==l.status||n.heldMc!==o||n.debitKey!==f.debitKey||n.billingClass!==u)throw Error("extract_settlement_plan_conflict");let N=b(l,n);if(N)return N;let m={version:1,jobId:e,userId:t,generation:a,netChargeMc:n.netChargeMc,refundMc:0,expiredRefundMc:0};try{if(u===E)await x(n,m);else if(n.debitKey){let d=await p(t,n.debitKey,n.netChargeMc,S.EXTRACT_SITE_REFUND,n.reference,"extract_site");m.netChargeMc=d.final_amount_mc,m.refundMc=d.refund_mc,m.expiredRefundMc=d.expired_refund_mc??0,await x(n,m)}else{let h=await _().execute({sql:"SELECT datetime(created_at, ?) AS expires_at FROM site_extract_jobs WHERE id = ?",args:[D,e]}),R=[e,t,a,n.status,JSON.stringify(n)];await H({userId:t,refundMc:n.refundMc,expiresAt:String(h.rows[0]?.expires_at),operation:S.EXTRACT_SITE_REFUND,description:n.reference,admission:{sql:`UPDATE site_extract_jobs SET billed_mc = -1
4
- WHERE id = ? AND user_id = ? AND execution_generation = ? AND status = ?
5
- AND settlement_plan_json = ? AND billed_mc IS NULL`,args:R},acknowledgment:{sql:`UPDATE site_extract_jobs SET billed_mc = ?,
6
- settlement_receipt_json = json_set(?, '$.refundMc', CASE WHEN changes() = 1 THEN ? ELSE 0 END,
7
- '$.expiredRefundMc', CASE WHEN changes() = 1 THEN 0 ELSE ? END),
8
- public_error_json = CASE WHEN json_valid(public_error_json) THEN json_set(public_error_json, '$.charge_status',
9
- CASE WHEN ? > 0 THEN 'charged' WHEN changes() = 1 AND ? > 0 THEN 'refunded' ELSE 'not_charged' END) ELSE public_error_json END,
10
- updated_at = datetime('now')
11
- WHERE id = ? AND user_id = ? AND execution_generation = ? AND status = ?
12
- AND settlement_plan_json = ? AND billed_mc = -1`,args:[n.netChargeMc,JSON.stringify(m),n.refundMc,n.refundMc,n.netChargeMc,n.refundMc,...R]}})}}catch(d){let h=b(await g(e).catch(()=>null),n);if(h)return h;throw d}let M=b(await g(e),n);if(!M)throw Error("extract_settlement_acknowledgment_unknown");return M}async function V(e){if(e.userId==null||e.billedMc!=null)return e.settlementReceipt??null;if(!J(e))throw Error("extract_settlement_requires_terminal_job");let t=Number(e.options.heldMc??0),r=await I(e.id),i=Math.min(r*P.page_scrape,t),c="site";try{c=new URL(e.startUrl).hostname}catch{}return await v(e.id,e.userId,t-i,i,c,e.executionGeneration??0)}export{L as a,Q as b,V as c};
@@ -1,41 +0,0 @@
1
- import{S as K}from"./chunk-FM7BX2LU.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
- CREATE TABLE IF NOT EXISTS gmail_selections (
3
- selection_id TEXT PRIMARY KEY,
4
- owner_identity TEXT NOT NULL,
5
- connection_id TEXT NOT NULL,
6
- purpose TEXT NOT NULL,
7
- source_json TEXT NOT NULL,
8
- message_ids_json TEXT NOT NULL,
9
- message_count INTEGER NOT NULL,
10
- selection_sha256 TEXT NOT NULL,
11
- provider_snapshot_json TEXT,
12
- created_at TEXT NOT NULL,
13
- expires_at TEXT NOT NULL,
14
- UNIQUE(owner_identity, connection_id, purpose, selection_sha256)
15
- )
16
- `),await e.execute("CREATE INDEX IF NOT EXISTS gmail_selections_owner_expiry ON gmail_selections(owner_identity, expires_at)"),await e.execute(`
17
- CREATE TABLE IF NOT EXISTS gmail_action_executions (
18
- action_id TEXT PRIMARY KEY,
19
- owner_identity TEXT NOT NULL,
20
- idempotency_key TEXT NOT NULL,
21
- fingerprint TEXT NOT NULL,
22
- status TEXT NOT NULL,
23
- result_json TEXT,
24
- created_at TEXT NOT NULL,
25
- updated_at TEXT NOT NULL,
26
- UNIQUE(owner_identity, idempotency_key)
27
- )
28
- `),await e.execute("CREATE INDEX IF NOT EXISTS gmail_actions_owner_updated ON gmail_action_executions(owner_identity, updated_at)"),await e.execute(`CREATE TABLE IF NOT EXISTS gmail_action_chunks (
29
- action_id TEXT NOT NULL, chunk_key TEXT NOT NULL, status TEXT NOT NULL,
30
- result_json TEXT, updated_at TEXT NOT NULL,
31
- PRIMARY KEY(action_id, chunk_key)
32
- )`),await e.execute(`CREATE TABLE IF NOT EXISTS gmail_selection_exports (
33
- selection_id TEXT PRIMARY KEY, owner_identity TEXT NOT NULL, fingerprint TEXT NOT NULL,
34
- status TEXT NOT NULL, result_json TEXT, updated_at TEXT NOT NULL
35
- )`)})().catch(t=>{throw k=null,P=null,t})),k}function W(e){let t=[...new Set(e.map(n=>n.trim()).filter(n=>/^[A-Za-z0-9_-]+$/.test(n)))];return t.sort(),t}function V(e){return{selectionId:String(e.selection_id),ownerId:String(e.owner_identity),connectionId:String(e.connection_id),purpose:String(e.purpose),source:JSON.parse(String(e.source_json)),messageIds:JSON.parse(String(e.message_ids_json)),count:Number(e.message_count),selectionSha256:String(e.selection_sha256),createdAt:String(e.created_at),expiresAt:String(e.expires_at),providerSnapshot:typeof e.provider_snapshot_json=="string"?JSON.parse(e.provider_snapshot_json):null}}async function Z(e){await x();let t=W(e.resolvedMessageIds);if(t.length===0)throw new h("selection_empty","No Gmail messages matched the selection.");if(t.length>F)throw new h("selection_too_large",`Narrow the Gmail selection to at most ${F} messages.`);let n=e.source.kind==="query"?{kind:"query",query:e.source.query.trim().replace(/\s+/g," ")}:{kind:"message_ids",messageIds:W(e.source.messageIds)},i=b({connectionId:e.connectionId,purpose:e.purpose,source:n,messageIds:t}),o=await f().execute({sql:"SELECT * FROM gmail_selections WHERE owner_identity = ? AND connection_id = ? AND purpose = ? AND selection_sha256 = ? AND expires_at > ? LIMIT 1",args:[e.ownerId,e.connectionId,e.purpose,i,(e.now??new Date).toISOString()]});if(o.rows[0])return V(o.rows[0]);let r=e.now??new Date,a={selectionId:`gsel_${Y().replace(/-/g,"")}`,ownerId:e.ownerId,connectionId:e.connectionId,purpose:e.purpose,source:n,messageIds:t,count:t.length,selectionSha256:i,createdAt:r.toISOString(),expiresAt:new Date(r.getTime()+ge).toISOString(),providerSnapshot:e.providerSnapshot??null};return await f().execute({sql:"INSERT INTO gmail_selections (selection_id, owner_identity, connection_id, purpose, source_json, message_ids_json, message_count, selection_sha256, provider_snapshot_json, created_at, expires_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",args:[a.selectionId,a.ownerId,a.connectionId,a.purpose,JSON.stringify(a.source),JSON.stringify(a.messageIds),a.count,a.selectionSha256,a.providerSnapshot?JSON.stringify(a.providerSnapshot):null,a.createdAt,a.expiresAt]}),a}async function L(e){await x();let n=(await f().execute({sql:"SELECT * FROM gmail_selections WHERE selection_id = ? AND owner_identity = ? AND connection_id = ? AND expires_at > ? LIMIT 1",args:[e.selectionId,e.ownerId,e.connectionId,(e.now??new Date).toISOString()]})).rows[0];if(!n)throw new h("selection_not_found","Gmail selection not found.",404);return V(n)}function O(e,t,n){if(t!==e.count||n!==e.selectionSha256)throw new h("selection_changed","The Gmail selection receipt does not match the immutable selection.",409)}function j(e){return{actionId:String(e.action_id),ownerId:String(e.owner_identity),idempotencyKey:String(e.idempotency_key),fingerprint:String(e.fingerprint),status:String(e.status),result:typeof e.result_json=="string"?JSON.parse(e.result_json):null,createdAt:String(e.created_at),updatedAt:String(e.updated_at)}}async function D(e){await x();let t=e.idempotencyKey.trim();if(t.length<8||t.length>200)throw new h("idempotency_key_invalid","Idempotency-Key must be 8-200 characters.");let n=await f().execute({sql:"SELECT * FROM gmail_action_executions WHERE owner_identity = ? AND idempotency_key = ? LIMIT 1",args:[e.ownerId,t]});if(n.rows[0]){let r=j(n.rows[0]);if(r.fingerprint!==e.fingerprint)throw new h("idempotency_conflict","This Idempotency-Key is already bound to a different Gmail action.",409);if(r.status==="running"&&!r.result&&Date.now()-Date.parse(r.updatedAt)>6e4){let a=new Date().toISOString(),s=await f().execute({sql:"UPDATE gmail_action_executions SET updated_at = ? WHERE action_id = ? AND updated_at = ?",args:[a,r.actionId,r.updatedAt]});if(Number(s.rowsAffected??0)===1)return{execution:{...r,updatedAt:a},replay:!1}}return{execution:r,replay:!0}}let i=new Date().toISOString(),o={actionId:`gact_${Y().replace(/-/g,"")}`,ownerId:e.ownerId,idempotencyKey:t,fingerprint:e.fingerprint,status:"running",result:null,createdAt:i,updatedAt:i};try{await f().execute({sql:"INSERT INTO gmail_action_executions (action_id, owner_identity, idempotency_key, fingerprint, status, created_at, updated_at) VALUES (?, ?, ?, ?, 'running', ?, ?)",args:[o.actionId,o.ownerId,o.idempotencyKey,o.fingerprint,i,i]})}catch{let r=await f().execute({sql:"SELECT * FROM gmail_action_executions WHERE owner_identity = ? AND idempotency_key = ? LIMIT 1",args:[e.ownerId,t]});if(!r.rows[0])throw new h("action_claim_failed","The Gmail action could not be claimed.",409);let a=j(r.rows[0]);if(a.fingerprint!==e.fingerprint)throw new h("idempotency_conflict","This Idempotency-Key is already bound to a different Gmail action.",409);return{execution:a,replay:!0}}return{execution:o,replay:!1}}async function M(e){await x(),await f().execute({sql:"UPDATE gmail_action_executions SET updated_at = ? WHERE action_id = ? AND status = 'running'",args:[new Date().toISOString(),e]})}function Ie(e){return{actionId:String(e.action_id),chunkKey:String(e.chunk_key),status:String(e.status),result:typeof e.result_json=="string"?JSON.parse(e.result_json):null,updatedAt:String(e.updated_at)}}async function G(e,t){await x();let n=new Date().toISOString();try{return await f().execute({sql:"INSERT INTO gmail_action_chunks (action_id, chunk_key, status, updated_at) VALUES (?, ?, 'running', ?)",args:[e,t,n]}),{receipt:{actionId:e,chunkKey:t,status:"running",result:null,updatedAt:n},claimed:!0}}catch{let i=await f().execute({sql:"SELECT * FROM gmail_action_chunks WHERE action_id = ? AND chunk_key = ? LIMIT 1",args:[e,t]});if(!i.rows[0])throw new h("action_chunk_claim_failed","The Gmail action chunk could not be claimed.",409);return{receipt:Ie(i.rows[0]),claimed:!1}}}async function S(e,t,n,i){await x(),await f().execute({sql:"UPDATE gmail_action_chunks SET status = ?, result_json = ?, updated_at = ? WHERE action_id = ? AND chunk_key = ?",args:[n,JSON.stringify(i),new Date().toISOString(),e,t]})}async function Q(e){await x();let t=await f().execute({sql:"SELECT * FROM gmail_selection_exports WHERE selection_id = ? AND owner_identity = ? LIMIT 1",args:[e.selectionId,e.ownerId]});if(t.rows[0]){let n=t.rows[0];if(String(n.fingerprint)!==e.fingerprint)throw new h("export_conflict","This Gmail selection export receipt conflicts with the stored export.",409);let i=typeof n.result_json=="string"?JSON.parse(n.result_json):null;if(i)return{replay:i,claimed:!1};if(Date.now()-Date.parse(String(n.updated_at))>5*6e4){let o=await f().execute({sql:"UPDATE gmail_selection_exports SET updated_at = ? WHERE selection_id = ? AND owner_identity = ? AND updated_at = ?",args:[new Date().toISOString(),e.selectionId,e.ownerId,String(n.updated_at)]});if(Number(o.rowsAffected??0)===1)return{replay:null,claimed:!0}}return{replay:null,claimed:!1}}try{return await f().execute({sql:"INSERT INTO gmail_selection_exports (selection_id, owner_identity, fingerprint, status, updated_at) VALUES (?, ?, ?, 'running', ?)",args:[e.selectionId,e.ownerId,e.fingerprint,new Date().toISOString()]}),{replay:null,claimed:!0}}catch{let n=await f().execute({sql:"SELECT * FROM gmail_selection_exports WHERE selection_id = ? AND owner_identity = ? LIMIT 1",args:[e.selectionId,e.ownerId]});if(!n.rows[0])throw new h("export_claim_failed","The Gmail export could not be claimed.",409);let i=n.rows[0];if(String(i.fingerprint)!==e.fingerprint)throw new h("export_conflict","This Gmail selection export receipt conflicts with the stored export.",409);return{replay:typeof i.result_json=="string"?JSON.parse(i.result_json):null,claimed:!1}}}async function ee(e,t,n){await x(),await f().execute({sql:"UPDATE gmail_selection_exports SET status = 'complete', result_json = ?, updated_at = ? WHERE selection_id = ? AND owner_identity = ?",args:[JSON.stringify(n),new Date().toISOString(),t,e]})}async function v(e,t,n){await x();let i=new Date().toISOString();await f().execute({sql:"UPDATE gmail_action_executions SET status = ?, result_json = ?, updated_at = ? WHERE action_id = ?",args:[t,JSON.stringify(n),i,e]});let o=await f().execute({sql:"SELECT * FROM gmail_action_executions WHERE action_id = ? LIMIT 1",args:[e]});if(!o.rows[0])throw new h("action_not_found","Gmail action not found.",404);return j(o.rows[0])}var we="2026-08-27.1",qe="9c82b270bb70e7795814cac408a41786ec70d4d7a4bb0f4a11bcc1b7fd02088b",N=2e4,ye=10080*60*1e3,u=class extends Error{constructor(n,i,o=400,r=o===429||o>=500,a=null){super(i);this.code=n;this.status=o;this.retryable=r;this.retryAfterMs=a;this.name="GmailServiceError"}code;status;retryable;retryAfterMs};function I(e){return e&&typeof e=="object"&&!Array.isArray(e)?e:null}function p(e){return typeof e=="string"&&e.length>0?e:null}function T(e){return typeof e=="number"&&Number.isFinite(e)?e:null}function C(e){if(!/^[A-Za-z0-9_-]*={0,2}$/.test(e))throw new u("gmail_invalid_base64","Gmail returned invalid encoded content.",502);let t=e.replace(/-/g,"+").replace(/_/g,"/");return Buffer.from(t.padEnd(Math.ceil(t.length/4)*4,"="),"base64")}function _e(e){return/^[\x20-\x7e]*$/.test(e)?e:`=?UTF-8?B?${Buffer.from(e,"utf8").toString("base64")}?=`}function xe(e,t,n){let i=Buffer.from(n,"utf8").toString("base64").match(/.{1,76}/g)?.join(`\r
36
- `)??"";return[`To: ${e}`,`Subject: ${_e(t)}`,"MIME-Version: 1.0","Content-Type: text/plain; charset=UTF-8","Content-Transfer-Encoding: base64","",i].join(`\r
37
- `)}function ae(e){let t=e.toString("latin1").replace(/=\r?\n/g,""),n=[];for(let i=0;i<t.length;i++)t[i]==="="&&/^[0-9A-Fa-f]{2}$/.test(t.slice(i+1,i+3))?(n.push(Number.parseInt(t.slice(i+1,i+3),16)),i+=2):n.push(t.charCodeAt(i)&255);return Buffer.from(n)}function B(e){return e.replace(/=\?([^?]+)\?([bq])\?([^?]+)\?=/gi,(t,n,i,o)=>{try{let r=i.toLowerCase()==="b"?Buffer.from(o,"base64"):ae(Buffer.from(o.replace(/_/g," "),"latin1"));return/^(?:utf-8|us-ascii)$/i.test(n)?r.toString("utf8"):r.toString("latin1")}catch{return o}})}function Se(e){return Array.isArray(e)?e.flatMap(t=>{let n=I(t),i=p(n?.name),o=p(n?.value);return!i||o===null?[]:[{name:i,value:B(o.replace(/\r?\n[ \t]+/g," "))}]}):[]}function _(e,t){return e.find(n=>n.name.toLowerCase()===t.toLowerCase())?.value??null}function R(e){return e?(e.match(/(?:"(?:[^"\\]|\\.)*"|[^,])+/g)??[]).flatMap(n=>{let i=n.trim(),o=i.match(/^(.*?)\s*<([^<>\s]+@[^<>\s]+)>$/),r=(o?.[2]??i).replace(/^mailto:/i,"").trim().toLowerCase();if(!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(r))return[];let a=o?.[1]?.trim().replace(/^"|"$/g,"")||null;return[{name:a?B(a):null,email:r}]}):[]}function be(e,t){let n=C(e),i=_(t,"content-transfer-encoding")?.toLowerCase();if(i==="quoted-printable")return ae(n);if(i==="base64"){let o=n.toString("ascii").replace(/\s/g,"");return/^[A-Za-z0-9+/]*={0,2}$/.test(o)?Buffer.from(o,"base64"):n}return n}function Te(e){return e.replace(/<!--[\s\S]*?-->/g,"").replace(/<!doctype\b[^>]*>/gi,"").replace(/<script\b[^>]*>[\s\S]*?<\/script>/gi,"").replace(/<style\b[^>]*>[\s\S]*?<\/style>/gi,"").replace(/<(?:iframe|object|embed|svg|math)\b[^>]*>[\s\S]*?<\/(?:iframe|object|embed|svg|math)>/gi,"").replace(/<\/?(?:script|style|iframe|object|embed|svg|math|form|input|button|textarea|select|option|meta|link|base|img|audio|video|source|track)\b[^>]*>/gi,"").replace(/\son\w+\s*=\s*(?:"[^"]*"|'[^']*'|[^\s>]+)/gi,"").replace(/\s(?:href|src|srcset|action|formaction|poster|background|xlink:href)\s*=\s*(?:"[^"]*"|'[^']*'|[^\s>]+)/gi,"").replace(/<[^>]*>/g," ").replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/\s+/g," ").trim()}function se(){return U("sha256").update(X()).update("\0gmail-ref-v1").digest()}function ce(e){let t=Buffer.from(JSON.stringify(e)).toString("base64url"),n=re("sha256",se()).update(t).digest("base64url");return`gref1.${t}.${n}`}function te(e,t,n){let[i,o,r]=e.split(".");if(i!=="gref1"||!o||!r)throw new u("reference_not_found","Gmail reference not found.",404,!1);let a=re("sha256",se()).update(o).digest(),s;try{s=Buffer.from(r,"base64url")}catch{throw new u("reference_not_found","Gmail reference not found.",404,!1)}if(a.length!==s.length||!he(a,s))throw new u("reference_not_found","Gmail reference not found.",404,!1);let l;try{l=JSON.parse(Buffer.from(o,"base64url").toString("utf8"))}catch{throw new u("reference_not_found","Gmail reference not found.",404,!1)}if(l.ownerId!==t||l.kind!==n||typeof l.expiresAt!="number"||l.expiresAt<=Date.now())throw new u("reference_not_found","Gmail reference not found.",404,!1);return l}function Ae(e){return ce({kind:"attachment",...e,expiresAt:Date.now()+ye})}function le(e){let t=Se(e.part.headers),n=I(e.part.body),i=p(e.part.mimeType)?.toLowerCase()??"application/octet-stream",o=B(p(e.part.filename)??""),r=p(e.part.partId)??e.path,a=p(n?.data),s=p(n?.attachmentId),l=_(t,"content-id")?.replace(/^<|>$/g,"")??null,c=/^inline\b/i.test(_(t,"content-disposition")??"")||!!l,d=i.startsWith("text/"),m=null,g=!0;d&&a?m=be(a,t).toString("utf8"):d&&s&&(g=!1);let w=!!o||!!s||c&&!!a&&!d,y=null,A=T(n?.size)??(a?C(a).byteLength:0);if(w){let E=A;y=Ae({ownerId:e.ownerId,connectionId:e.connectionId,messageId:e.messageId,partId:r,attachmentId:s,filename:o||`gmail-${e.messageId}-${r}`,mimeType:i,size:E}),e.attachments.push({filename:o||`gmail-${e.messageId}-${r}`,declaredMime:i,size:E,inline:c,contentId:l,partId:r,attachmentRef:y})}let me=Array.isArray(e.part.parts)?e.part.parts.map((E,pe)=>le({...e,part:I(E)??{},path:`${e.path}.${pe+1}`})):[];return{partId:r,mimeType:i,filename:o,headers:t,size:A,inline:c,contentId:l,contentComplete:g,text:m,attachmentRef:y,parts:me}}function z(e,t){return[...e.mimeType===t&&e.text!==null?[e.text]:[],...e.parts.flatMap(i=>z(i,t))]}function ne(e){let t=I(e.payload),n=p(t?.id),i=I(t?.payload);if(!n||!i)throw new u("gmail_invalid_message","Gmail returned an invalid message.",502);let o=[],r=le({part:i,ownerId:e.ownerId,connectionId:e.connectionId,messageId:n,path:"0",attachments:o}),a=r.headers,s=z(r,"text/plain").join(`
38
- `).trim()||null,l=z(r,"text/html").join(`
39
- `).trim()||null;return{messageId:n,threadId:p(t?.threadId),messageIdHeader:_(a,"message-id"),internalDate:p(t?.internalDate)?new Date(Number(t.internalDate)).toISOString():null,headers:a,from:R(_(a,"from")),to:R(_(a,"to")),cc:R(_(a,"cc")),bcc:R(_(a,"bcc")),replyTo:R(_(a,"reply-to")),subject:_(a,"subject"),labels:Array.isArray(t?.labelIds)?t.labelIds.filter(c=>typeof c=="string"):[],snippet:p(t?.snippet),plainText:s,sanitizedHtml:l?Te(l):null,contentComplete:de(r),providerSizeEstimate:T(t?.sizeEstimate),mime:r,attachments:o,provenance:{provider:"gmail",connectionId:e.connectionId,fetchedAt:(e.fetchedAt??new Date).toISOString(),format:"full"}}}function de(e){return e.contentComplete&&e.parts.every(de)}var ie=class{providerCall;createArtifact;createJsonlArtifact;constructor(t={}){this.providerCall=t.providerCall??K,this.createArtifact=t.createArtifact??H,this.createJsonlArtifact=t.createJsonlArtifact??J}async sendMessage(t){let n=t.to.trim().toLowerCase(),i=t.subject.trim();if(!/^[^\s@<>]+@[^\s@<>]+\.[^\s@<>]+$/.test(n)||/[\r\n]/.test(t.to))throw new u("invalid_request","A valid recipient email address is required.");if(!i||i.length>500||/[\r\n]/.test(i))throw new u("invalid_request","A subject of at most 500 characters without line breaks is required.");if(!t.body||t.body.length>5e4)throw new u("invalid_request","A plain-text body of at most 50,000 characters is required.");if(t.idempotencyKey.length<8||t.idempotencyKey.length>200)throw new u("idempotency_key_invalid","Idempotency key must contain 8-200 characters.");let o=b({connectionId:t.connectionId,to:n,subject:i,bodySha256:U("sha256").update(t.body).digest("hex")}),r=await D({ownerId:t.ownerId,idempotencyKey:t.idempotencyKey,fingerprint:o});if(r.replay&&r.execution.result)return{...r.execution.result,replay:!0};if(r.replay)return{actionId:r.execution.actionId,status:"outcome_unknown",replay:!0,retryable:!1};let a=await G(r.execution.actionId,"send:0");if(!a.claimed)return{...a.receipt.result??{},actionId:r.execution.actionId,status:a.receipt.status,replay:!0};try{let s=I(await this.providerCall({identity:t.providerIdentity??t.ownerId,connectionId:t.connectionId,method:"POST",path:"/gmail/v1/users/me/messages/send",body:{raw:Buffer.from(xe(n,i,t.body),"utf8").toString("base64url")},requestId:t.idempotencyKey})),l={actionId:r.execution.actionId,status:"complete",messageId:p(s?.id),threadId:p(s?.threadId),replay:!1};return await S(r.execution.actionId,"send:0","complete",l),await v(r.execution.actionId,"complete",l),l}catch(s){let l={actionId:r.execution.actionId,status:"outcome_unknown",code:q(s),retryable:!1};throw await S(r.execution.actionId,"send:0","failed",l),await v(r.execution.actionId,"partial",l),s}}async searchMessages(t){let n=t.query.trim();if(!n||n.length>2e3)throw new u("invalid_request","A Gmail query of at most 2,000 characters is required.");let i=t.limit??25;if(!Number.isInteger(i)||i<1||i>500)throw new u("invalid_request","Gmail search limit must be an integer from 1 to 500.");let o=i,r;if(t.cursor){let c=te(t.cursor,t.ownerId,"search_cursor");if(c.connectionId!==t.connectionId||c.query!==n)throw new u("cursor_not_found","Gmail cursor not found.",404,!1);r=p(c.pageToken)??void 0}let a=I(await this.providerCall({identity:t.providerIdentity??t.ownerId,connectionId:t.connectionId,method:"GET",path:"/gmail/v1/users/me/messages",query:{q:n,maxResults:o,pageToken:r}})),s=Array.isArray(a?.messages)?a.messages.flatMap(c=>{let d=I(c),m=p(d?.id);return m?[{messageId:m,threadId:p(d?.threadId)}]:[]}):[],l=p(a?.nextPageToken);return{messages:s,estimatedMatches:T(a?.resultSizeEstimate),complete:!l,truncated:!!l,nextCursor:l?ce({kind:"search_cursor",ownerId:t.ownerId,connectionId:t.connectionId,query:n,pageToken:l,expiresAt:Date.now()+1440*60*1e3}):null}}async getMessage(t){let n=await this.getCompleteMessage(t),i=!!n.canonicalArtifact,o=n.plainText&&Buffer.byteLength(n.plainText)>N?`${Buffer.from(n.plainText).subarray(0,N).toString("utf8")}\u2026`:n.plainText;return{...n,plainText:o,contentComplete:n.contentComplete&&!i}}async getCompleteMessage(t){if(!/^[A-Za-z0-9_-]+$/.test(t.messageId))throw new u("invalid_request","A valid Gmail message ID is required.");let n=encodeURIComponent(t.messageId),i=t.providerIdentity??t.ownerId,o=await this.providerCall({identity:i,connectionId:t.connectionId,method:"GET",path:`/gmail/v1/users/me/messages/${n}`,query:{format:"full"}}),r=ne({ownerId:t.ownerId,connectionId:t.connectionId,payload:o}),a=null;if(t.includeRawArtifact!==!1){let d=I(await this.providerCall({identity:i,connectionId:t.connectionId,method:"GET",path:`/gmail/v1/users/me/messages/${n}`,query:{format:"raw"}})),m=p(d?.raw);if(!m)throw new u("gmail_raw_unavailable","Gmail did not return the raw message.",502);a=await this.createArtifact({ownerId:t.ownerId,exportId:`gmail-raw-${t.messageId}`,filename:`${t.messageId}.eml`,content:C(m),contentType:"message/rfc822"})}let s=JSON.stringify(r),c=Buffer.byteLength(s)>N||!r.contentComplete?await this.createArtifact({ownerId:t.ownerId,exportId:`gmail-message-${t.messageId}`,filename:`${t.messageId}.json`,content:s,contentType:"application/json"}):null;return{...r,rawArtifact:a,canonicalArtifact:c}}async getAttachment(t){let n=te(t.attachmentRef,t.ownerId,"attachment"),i=p(n.connectionId),o=p(n.messageId);if(!i||!o)throw new u("reference_not_found","Gmail reference not found.",404,!1);let r,a=p(n.attachmentId);if(a){let w=I(await this.providerCall({identity:t.providerIdentity??t.ownerId,connectionId:i,method:"GET",path:`/gmail/v1/users/me/messages/${encodeURIComponent(o)}/attachments/${encodeURIComponent(a)}`})),y=p(w?.data);if(!y)throw new u("gmail_attachment_unavailable","Gmail did not return attachment bytes.",502);r=C(y);let A=T(w?.size);if(A!==null&&A!==r.byteLength)throw new u("gmail_attachment_size_mismatch","Gmail attachment bytes did not match the declared size.",502)}else{let w=I(await this.providerCall({identity:t.providerIdentity??t.ownerId,connectionId:i,method:"GET",path:`/gmail/v1/users/me/messages/${encodeURIComponent(o)}`,query:{format:"full"}})),y=ue(I(w?.payload),p(n.partId)??"");if(!y)throw new u("reference_not_found","Gmail reference not found.",404,!1);r=C(y)}let s=p(n.mimeType)??"application/octet-stream",l=T(n.size);if(l!==null&&l>0&&l!==r.byteLength)throw new u("gmail_attachment_size_mismatch","Gmail attachment bytes did not match the reviewed MIME part size.",502);let c=Ge(r,s),d=p(n.filename)??`gmail-${o}.bin`,m=await this.createArtifact({ownerId:t.ownerId,exportId:`gmail-attachment-${o}`,filename:d,content:r,contentType:c}),g=c.startsWith("text/")||c==="application/json"?r.subarray(0,N).toString("utf8"):null;return{filename:d,declaredMime:s,observedMime:c,bytes:r.byteLength,sha256:U("sha256").update(r).digest("hex"),contentComplete:g!==null?r.byteLength<=N:!0,text:g,artifact:m}}async prepareSelection(t){let n,i=null;if(t.source.kind==="message_ids"){if(!t.source.messageIds.length||t.source.messageIds.some(o=>typeof o!="string"||!/^[A-Za-z0-9_-]+$/.test(o.trim())))throw new u("invalid_request","Every explicit Gmail message ID must be valid.");n=[...new Set(t.source.messageIds.map(o=>o.trim()))];for(let o of n)try{await this.providerCall({identity:t.providerIdentity??t.ownerId,connectionId:t.connectionId,method:"GET",path:`/gmail/v1/users/me/messages/${encodeURIComponent(o)}`,query:{format:"metadata"}})}catch{throw new u("selection_message_not_found","One or more explicit Gmail message IDs do not exist in this connection.",404,!1)}}else{n=[];let o,r=null;do{let a=I(await this.providerCall({identity:t.providerIdentity??t.ownerId,connectionId:t.connectionId,method:"GET",path:"/gmail/v1/users/me/messages",query:{q:t.source.query.trim(),maxResults:500,pageToken:o}}));r===null&&(r=T(a?.resultSizeEstimate));for(let s of Array.isArray(a?.messages)?a.messages:[]){let l=p(I(s)?.id);l&&n.push(l)}if(new Set(n).size>5e3)throw new u("selection_too_large","Narrow the Gmail selection to at most 5,000 messages.");o=p(a?.nextPageToken)??void 0}while(o);if(t.exactRange){let a=Date.parse(t.exactRange.from),s=Date.parse(t.exactRange.to);if(!Number.isFinite(a)||!Number.isFinite(s)||a>=s)throw new u("invalid_request","exactRange.from must be before exactRange.to.");let l=[];for(let c of n){let d=await this.providerCall({identity:t.providerIdentity??t.ownerId,connectionId:t.connectionId,method:"GET",path:`/gmail/v1/users/me/messages/${encodeURIComponent(c)}`,query:{format:"full"}}),m=ne({ownerId:t.ownerId,connectionId:t.connectionId,payload:d}),g=m.internalDate?Date.parse(m.internalDate):Number.NaN;Number.isFinite(g)&&g>=a&&g<s&&l.push(c)}n=l}i={estimatedMatches:r,pagesComplete:!0,...t.exactRange?{exactRange:t.exactRange}:{}}}return Z({ownerId:t.ownerId,connectionId:t.connectionId,source:t.source,purpose:t.purpose,resolvedMessageIds:n,providerSnapshot:i})}async exportSelection(t){let n=await L(t);if(n.purpose!=="export"&&n.purpose!=="scheduled_export")throw new u("selection_purpose_mismatch","This Gmail selection was not prepared for export.",409,!1);O(n,t.expectedCount,t.selectionSha256);let i=b({selectionId:n.selectionId,selectionSha256:n.selectionSha256,expectedCount:n.count}),o=await Q({ownerId:t.ownerId,selectionId:n.selectionId,fingerprint:i});if(o.replay)return{...o.replay,replay:!0};if(!o.claimed)throw new u("export_in_progress","This Gmail selection export is already running; retry shortly with the same receipt.",409,!0);let r=[];for(let m of n.messageIds)r.push(await this.getCompleteMessage({ownerId:t.ownerId,providerIdentity:t.providerIdentity,connectionId:t.connectionId,messageId:m}));let a=`gexp_${n.selectionSha256.slice(0,32)}`,s={version:we,selectionId:n.selectionId,selectionSha256:n.selectionSha256,count:r.length},l=[JSON.stringify({type:"manifest",...s}),...r.map(m=>JSON.stringify({type:"message",message:m}))].join(`
40
- `)+`
41
- `,c=await this.createJsonlArtifact({ownerId:t.ownerId,exportId:a,filename:`gmail-${n.selectionId}.jsonl`,content:l,stableCreatedAt:n.createdAt,stableKey:i.slice(0,32)}),d={exportId:a,selectionId:n.selectionId,selectionSha256:n.selectionSha256,count:r.length,status:"complete",artifact:c,sampleMessages:r.slice(0,5).map(ke)};return await ee(t.ownerId,n.selectionId,d),d}async bulkManageSelection(t){let n=await L(t);if(n.purpose!=="mailbox_action")throw new u("selection_purpose_mismatch","This Gmail selection was not prepared for mailbox actions.",409,!1);O(n,t.expectedCount,t.selectionSha256);let i=b({selectionSha256:n.selectionSha256,operation:t.operation}),o=await D({ownerId:t.ownerId,idempotencyKey:t.idempotencyKey,fingerprint:i});if(o.replay&&o.execution.result)return o.execution.result;if(o.replay)return{actionId:o.execution.actionId,selectionId:n.selectionId,status:"running",changedCount:0,failedCount:0,failedChunks:[],retryable:!0};let r=[],a=0,s=Ee(t.operation);if(s.mode==="batch"){s.validateIds.length&&await this.validateLabels(t.providerIdentity??t.ownerId,t.connectionId,s.validateIds);let c=oe(n.messageIds,1e3);for(let d=0;d<c.length;d++){await M(o.execution.actionId);let m=`batch:${d}`,g=await G(o.execution.actionId,m);if(!g.claimed){g.receipt.status==="complete"?a+=Number(g.receipt.result?.changedCount??c[d].length):r.push({chunk:d,code:g.receipt.status==="failed"?String(g.receipt.result?.code??"provider_error"):"outcome_unknown"});continue}try{await this.providerCall({identity:t.providerIdentity??t.ownerId,connectionId:t.connectionId,method:"POST",path:"/gmail/v1/users/me/messages/batchModify",body:{ids:c[d],addLabelIds:s.addLabelIds,removeLabelIds:s.removeLabelIds},requestId:`${t.idempotencyKey}:${d}`}),a+=c[d].length,await S(o.execution.actionId,m,"complete",{changedCount:c[d].length})}catch(w){let y=q(w);r.push({chunk:d,code:y}),await S(o.execution.actionId,m,"failed",{code:y})}}}else for(let c=0;c<n.messageIds.length;c++){await M(o.execution.actionId);let d=`single:${c}`,m=await G(o.execution.actionId,d);if(!m.claimed){m.receipt.status==="complete"?a+=1:r.length<20&&r.push({chunk:c,code:m.receipt.status==="failed"?String(m.receipt.result?.code??"provider_error"):"outcome_unknown"});continue}try{await this.providerCall({identity:t.providerIdentity??t.ownerId,connectionId:t.connectionId,method:"POST",path:`/gmail/v1/users/me/messages/${encodeURIComponent(n.messageIds[c])}/${s.path}`,body:{},requestId:`${t.idempotencyKey}:${c}`}),a+=1,await S(o.execution.actionId,d,"complete",{changedCount:1})}catch(g){let w=q(g);r.length<20&&r.push({chunk:c,code:w}),await S(o.execution.actionId,d,"failed",{code:w})}}let l={actionId:o.execution.actionId,selectionId:n.selectionId,status:r.length?"partial":"complete",changedCount:a,failedCount:n.count-a,failedChunks:r.slice(0,20)};return await v(o.execution.actionId,r.length?"partial":"complete",l),l}async permanentlyDeleteSelection(t){if(t.confirmPermanentDelete!==!0)throw new u("permanent_delete_confirmation_required","Set confirmPermanentDelete to true after explicit user confirmation.");let n=await L(t);if(O(n,t.expectedCount,t.selectionSha256),n.purpose!=="mailbox_action")throw new u("selection_purpose_mismatch","This Gmail selection was not prepared for mailbox actions.",409,!1);let i=b({selectionSha256:n.selectionSha256,operation:"permanent_delete"}),o=await D({ownerId:t.ownerId,idempotencyKey:t.idempotencyKey,fingerprint:i});if(o.replay&&o.execution.result)return o.execution.result;if(o.replay)return{actionId:o.execution.actionId,selectionId:n.selectionId,status:"running",submittedCount:0,failedCount:0,failedChunks:[],retryable:!0,providerGuarantee:"The original permanent-delete attempt is still being finalized; no provider chunk was replayed."};let r=[],a=0,s=oe(n.messageIds,1e3);for(let c=0;c<s.length;c++){await M(o.execution.actionId);let d=`delete:${c}`,m=await G(o.execution.actionId,d);if(!m.claimed){m.receipt.status==="complete"?a+=Number(m.receipt.result?.submittedCount??s[c].length):r.push({chunk:c,code:m.receipt.status==="failed"?String(m.receipt.result?.code??"provider_error"):"outcome_unknown"});continue}try{await this.providerCall({identity:t.providerIdentity??t.ownerId,connectionId:t.connectionId,method:"POST",path:"/gmail/v1/users/me/messages/batchDelete",body:{ids:s[c]},requestId:`${t.idempotencyKey}:${c}`}),a+=s[c].length,await S(o.execution.actionId,d,"complete",{submittedCount:s[c].length})}catch(g){let w=q(g);r.push({chunk:c,code:w}),await S(o.execution.actionId,d,"failed",{code:w})}}let l={actionId:o.execution.actionId,selectionId:n.selectionId,status:r.length?"partial":"complete",submittedCount:a,failedCount:n.count-a,failedChunks:r.slice(0,20),providerGuarantee:"Gmail accepts batch deletion but does not report whether every supplied message previously existed."};return await v(o.execution.actionId,r.length?"partial":"complete",l),l}async validateLabels(t,n,i){let o=I(await this.providerCall({identity:t,connectionId:n,method:"GET",path:"/gmail/v1/users/me/labels"})),r=new Set((Array.isArray(o?.labels)?o.labels:[]).map(s=>p(I(s)?.id)).filter(s=>!!s));if(i.filter(s=>!r.has(s)).length)throw new u("gmail_label_not_found","One or more Gmail label IDs were not found.",404,!1)}};function Ee(e){if(e.kind==="trash")return{mode:"single",path:"trash"};if(e.kind==="restore")return{mode:"single",path:"untrash"};if(e.kind==="labels"){let n=[...new Set(e.addLabelIds??[])],i=[...new Set(e.removeLabelIds??[])];if(!n.length&&!i.length)throw new u("invalid_request","At least one label must be added or removed.");if(n.some(o=>i.includes(o)))throw new u("invalid_request","The same label cannot be added and removed.");return{mode:"batch",addLabelIds:n,removeLabelIds:i,validateIds:[...n,...i]}}return{mode:"batch",...{mark_read:{addLabelIds:[],removeLabelIds:["UNREAD"]},mark_unread:{addLabelIds:["UNREAD"],removeLabelIds:[]},archive:{addLabelIds:[],removeLabelIds:["INBOX"]},move_to_inbox:{addLabelIds:["INBOX"],removeLabelIds:[]}}[e.kind],validateIds:[]}}function oe(e,t){let n=[];for(let i=0;i<e.length;i+=t)n.push(e.slice(i,i+t));return n}function q(e){return e&&typeof e=="object"&&typeof e.code=="string"?String(e.code):"provider_error"}function ke(e){return{messageId:e.messageId,threadId:e.threadId,internalDate:e.internalDate,from:e.from,to:e.to,subject:e.subject,snippet:e.snippet,labels:e.labels,attachmentCount:e.attachments.length}}function ue(e,t){if(!e)return null;if(p(e.partId)===t)return p(I(e.body)?.data);for(let n of Array.isArray(e.parts)?e.parts:[]){let i=ue(I(n),t);if(i!==null)return i}return null}function Ge(e,t){if(e.subarray(0,5).toString("ascii")==="%PDF-")return"application/pdf";if(e.subarray(0,4).equals(Buffer.from([80,75,3,4])))return"application/zip";if(e.subarray(0,8).equals(Buffer.from([137,80,78,71,13,10,26,10])))return"image/png";if(e.subarray(0,3).equals(Buffer.from([255,216,255])))return"image/jpeg";if(t.startsWith("text/"))try{return new TextDecoder("utf-8",{fatal:!0}).decode(e),t}catch{return"application/octet-stream"}if(t==="application/json")try{return JSON.parse(new TextDecoder("utf-8",{fatal:!0}).decode(e)),t}catch{return"application/octet-stream"}return"application/octet-stream"}export{h as a,b,L as c,O as d,we as e,qe as f,N as g,ye as h,u as i,R as j,ne as k,ie as l};