everyapp 0.2.1 → 0.3.0-rc.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 (120) hide show
  1. package/README.md +6 -77
  2. package/bin/everyapp.js +235 -0
  3. package/dist/access-F3GKBKAW.js +1 -0
  4. package/dist/activity-4MFMH5JP.js +12 -0
  5. package/dist/apps-63K2DGVT.js +9 -0
  6. package/dist/chunk-2UFJRKEE.js +4 -0
  7. package/dist/chunk-3AAHHUJC.js +11 -0
  8. package/dist/chunk-3Z53CH4F.js +6 -0
  9. package/dist/chunk-5ZTFC6DK.js +1 -0
  10. package/dist/chunk-6O3GJS5H.js +15 -0
  11. package/dist/chunk-74EST4VW.js +2 -0
  12. package/dist/chunk-7LG3F4FF.js +10 -0
  13. package/dist/chunk-AUDGOIHE.js +1 -0
  14. package/dist/chunk-BHMRY53V.js +2 -0
  15. package/dist/chunk-DQWOXSL3.js +32 -0
  16. package/dist/chunk-E3EPK27P.js +10 -0
  17. package/dist/chunk-E7EUXUVD.js +1 -0
  18. package/dist/chunk-ECLJ5IAL.js +126 -0
  19. package/dist/chunk-EQX4GKJ2.js +4 -0
  20. package/dist/chunk-EUNGJMJ6.js +20 -0
  21. package/dist/chunk-F6IH47GT.js +4 -0
  22. package/dist/chunk-G64S77GC.js +33 -0
  23. package/dist/chunk-GD2JZMD3.js +1 -0
  24. package/dist/chunk-GRFPP4UW.js +7 -0
  25. package/dist/chunk-IA534DGW.js +10 -0
  26. package/dist/chunk-IG26HYRR.js +45 -0
  27. package/dist/chunk-IZEOAOKL.js +6 -0
  28. package/dist/chunk-JYKRUS5C.js +1 -0
  29. package/dist/chunk-KMAOZRV4.js +18 -0
  30. package/dist/chunk-MC56CUQI.js +7 -0
  31. package/dist/chunk-MDORVBPD.js +1 -0
  32. package/dist/chunk-N4E5YE4X.js +5 -0
  33. package/dist/chunk-NJFWEYX7.js +1 -0
  34. package/dist/chunk-OEOVNJAN.js +1 -0
  35. package/dist/chunk-OVKVV6MK.js +2 -0
  36. package/dist/chunk-PL6EORDJ.js +15 -0
  37. package/dist/chunk-PMPIMHKG.js +6 -0
  38. package/dist/chunk-QZWSSWMP.js +22 -0
  39. package/dist/chunk-R4CGF622.js +2 -0
  40. package/dist/chunk-RFVMR32Y.js +1 -0
  41. package/dist/chunk-RQFHVU3Y.js +25 -0
  42. package/dist/chunk-SAT3PGZU.js +57 -0
  43. package/dist/chunk-SPPR6WCI.js +1 -0
  44. package/dist/chunk-TPWSGRNT.js +30 -0
  45. package/dist/chunk-VVQRET35.js +2 -0
  46. package/dist/chunk-VXJQGJ7Y.js +2 -0
  47. package/dist/chunk-WEM3WLOC.js +1 -0
  48. package/dist/chunk-Y3VIFPN5.js +1 -0
  49. package/dist/chunk-YJBYZWSP.js +22 -0
  50. package/dist/chunk-ZYL2ZHCF.js +98 -0
  51. package/dist/configure-2KMHM22T.js +8 -0
  52. package/dist/create-ELEJMZBS.js +22 -0
  53. package/dist/db-MZIAKGBN.js +9 -0
  54. package/dist/delete-H47KPJSB.js +3 -0
  55. package/dist/deploy-HGFJLLUO.js +1 -0
  56. package/dist/dev-62VA7UEM.js +86 -0
  57. package/dist/email-NNFD3VVB.js +10 -0
  58. package/dist/events-JDY76EG6.js +15 -0
  59. package/dist/groups-NQFXDZZP.js +8 -0
  60. package/dist/index.js +92 -1
  61. package/dist/install-JTZWRZIL.js +1 -0
  62. package/dist/login-P6LYQQWP.js +1 -0
  63. package/dist/mcp-NCFWEBMD.js +1 -0
  64. package/dist/provider-WVBI2VED.js +13 -0
  65. package/dist/release-6FYSPXXA.js +1 -0
  66. package/dist/restore-XBU7DOJV.js +3 -0
  67. package/dist/secret-ML5EXS3O.js +1 -0
  68. package/dist/setup-IEXCISLP.js +1 -0
  69. package/dist/status-OPLPKJ4U.js +4 -0
  70. package/dist/teardown-3JMMLK6O.js +22 -0
  71. package/dist/update-37ZDATLR.js +1 -0
  72. package/dist/workspace-DAFZVYQ2.js +21 -0
  73. package/package.json +30 -27
  74. package/skills/build-every-app/SKILL.md +199 -0
  75. package/skills/build-every-app/patterns.md +134 -0
  76. package/skills/everyapp/SKILL.md +292 -0
  77. package/skills/everyapp/mcp.md +336 -0
  78. package/skills/everyapp/security-review.md +61 -0
  79. package/skills/everyapp/setup/README.md +263 -0
  80. package/skills/everyapp/setup/access.md +178 -0
  81. package/skills/everyapp/setup/context.md +117 -0
  82. package/skills/everyapp/setup/dataforseo.md +287 -0
  83. package/skills/everyapp/setup/email.md +366 -0
  84. package/skills/everyapp/setup/gateway.md +243 -0
  85. package/skills/everyapp/setup/google.md +360 -0
  86. package/skills/everyapp/setup/microsoft-365.md +281 -0
  87. package/skills/everyapp/setup/openai.md +318 -0
  88. package/skills/everyapp/setup/openrouter.md +309 -0
  89. package/skills/everyapp/setup/providers.md +353 -0
  90. package/skills/everyapp/setup/remote-mcp.md +199 -0
  91. package/skills/everyapp/setup/slack.md +344 -0
  92. package/skills/everyapp/setup/workers-ai.md +138 -0
  93. package/bin/__everyapp_bash_complete.js +0 -12
  94. package/dist/bash-complete.js +0 -3
  95. package/dist/chunk-3TJKOYE5.js +0 -13
  96. package/dist/chunk-4YDNA5LP.js +0 -9
  97. package/dist/chunk-7OLTQZZZ.js +0 -47
  98. package/dist/chunk-AEQXMWNU.js +0 -39
  99. package/dist/chunk-BIXKPCDH.js +0 -2
  100. package/dist/chunk-E2N6VUZY.js +0 -1
  101. package/dist/chunk-GSP5Y7U6.js +0 -7
  102. package/dist/chunk-HSYSKQ25.js +0 -8
  103. package/dist/chunk-JXZGJYRJ.js +0 -8
  104. package/dist/chunk-PMLXP26K.js +0 -1
  105. package/dist/chunk-SGRMXPI7.js +0 -4
  106. package/dist/chunk-UHLZLYQP.js +0 -6
  107. package/dist/chunk-VEYSNPDH.js +0 -3
  108. package/dist/chunk-WO3NE7ZU.js +0 -7
  109. package/dist/chunk-YJ2DKIZS.js +0 -1
  110. package/dist/chunk-YPYDHMNH.js +0 -1
  111. package/dist/create-KOQ2DWKU.js +0 -22
  112. package/dist/deploy-RFR6W22M.js +0 -55
  113. package/dist/deploy-YV2RWODJ.js +0 -7
  114. package/dist/dev-FPQWEHYM.js +0 -0
  115. package/dist/generateConfig-46Z3ERF3.js +0 -1
  116. package/dist/login-ZFFQASKS.js +0 -1
  117. package/dist/logout-AEE4AZ5D.js +0 -1
  118. package/dist/remoteD1Shell-CGFP46AW.js +0 -6
  119. package/dist/setupLocal-PC6YBN2X.js +0 -6
  120. package/gateway/every-app-gateway-build.tar.gz +0 -0
@@ -0,0 +1,126 @@
1
+ import{$ as I,B as j,C as Z,W as Q,Z as m,y as K}from"./chunk-ZYL2ZHCF.js";import{e as N}from"./chunk-SPPR6WCI.js";import{c as E,k,tb as l}from"./chunk-SAT3PGZU.js";var ee=`SELECT users.id AS id, users.email AS email, users.name AS name, members.role AS role
2
+ FROM members JOIN users ON users.id = members.user_id
3
+ WHERE members.organization_id = ?1 AND lower(users.email) = ?2
4
+ LIMIT 1`,T=(e,n,a)=>`EXISTS (
5
+ SELECT 1 FROM members owners JOIN users owner ON owner.id = owners.user_id
6
+ WHERE owners.organization_id = ${e} AND owners.role = 'owner' AND owners.user_id <> ${n}
7
+ AND (owner.banned IS NULL OR owner.banned = 0 OR (owner.ban_expires IS NOT NULL AND owner.ban_expires <= ${a}))
8
+ )`;async function Be(e,n,a,r){let t=a.trim().toLowerCase(),i=Date.now(),[d=[],,u=[]]=await e.run([{sql:ee,params:[n,t]},{sql:`UPDATE members SET role = ?3
9
+ WHERE organization_id = ?1
10
+ AND user_id = (SELECT id FROM users WHERE lower(email) = ?2 LIMIT 1)
11
+ AND role <> ?3
12
+ AND NOT (
13
+ role = 'owner' AND ?3 <> 'owner'
14
+ AND NOT ${T("?1","members.user_id","?4")}
15
+ )`,params:[n,t,r,i]},{sql:ee,params:[n,t]}]),s=ae(d[0]);if(!s)return{kind:"not_found"};if(s.role===r)return{kind:"unchanged",member:s};let o=ae(u[0])??s;return o.role===r?{kind:"changed",member:o,previousRole:s.role}:{kind:"last_owner",member:s}}function ae(e){return e?{id:String(e.id),email:String(e.email),name:String(e.name??""),role:String(e.role)}:null}import{createHash as ve,randomBytes as q,randomUUID as O}from"node:crypto";async function he(e){let n=await I(e);if(!n||!n.hasOwner)throw new l("WORKSPACE_NOT_CLAIMED",`The Gateway has no owner yet
16
+ The setup claim makes the workspace, named after its owner; rename it after.`,{fix:"open the Gateway in a browser and claim it, then run this again"});return n.organization}function aa(e,n){return Q(async()=>{let a=await he(e),r=a.name!==n;return r&&await e.run([{sql:"UPDATE organizations SET name = ? WHERE id = ?",params:[n,a.id]}]),{organization:{...a,name:n},previousName:a.name,changed:r}})}var We=72*60*60*1e3,we=60*60*1e3,ne=1e9,re=60,te=255,G=90,ye=19,Ce=e=>ve("sha256").update(e).digest("hex"),y=e=>`((',' || replace(${e}, ' ', '') || ',') LIKE '%,owner,%')`,me=e=>`(NOT ${y(e)} OR ${T("?2","?1","?3")})`,v=`EXISTS (SELECT 1 FROM members m WHERE m.user_id = ?1 AND m.organization_id = ?2 AND ${me("m.role")})`,h=`EXISTS (SELECT 1 FROM members m WHERE m.user_id = ?1 AND m.organization_id = ?2)
17
+ AND NOT EXISTS (SELECT 1 FROM members mine WHERE mine.user_id = ?1 AND ${y("mine.role")}
18
+ AND NOT ${T("mine.organization_id","?1","?3")})`,ze=e=>`(banned = 1 AND (ban_expires IS NULL OR ban_expires > ${e}))`;function C(e,n){let a=[];for(let r=0;r<e.length;r+=n)a.push(e.slice(r,r+n));return a}function Le(e){let n=(e??"").split(",").map(a=>a.trim());return n.includes("owner")?"owner":n.includes("admin")?"admin":n.includes("member")?"member":null}var g=e=>Number(e??0);function z(e,n){let a=Number(e.banned??0)===1,r=e.ban_expires==null?null:Number(e.ban_expires);return{id:String(e.id),name:String(e.name??""),email:String(e.email),role:String(e.role??"member"),primaryRole:Le(m(e.role)),deactivated:a&&(r===null||r>n),createdAt:g(e.created_at)}}function B(e,n){let a=String(e.status),r=g(e.expires_at);return{id:String(e.id),email:String(e.email),role:String(e.role??"member"),status:a,expiresAt:r,createdAt:g(e.created_at),live:a==="pending"&&r>n}}function pe(e){return{id:String(e.id),name:String(e.name),description:m(e.description),createdAt:g(e.created_at),memberCount:g(e.member_count),appCount:g(e.app_count)}}function Y(e){return{id:String(e.id),appSlug:String(e.app_slug),name:String(e.name),description:String(e.description??""),status:String(e.status),scope:String(e.scope),tier:String(e.tier),hostname:m(e.hostname),everyone:Number(e.is_default??0)===1,manifest:m(e.manifest),secretNames:m(e.secret_names),accessCount:g(e.access_count)}}var L="u.id, u.name, u.email, m.role, u.banned, u.ban_expires, u.created_at",J=`a.id, a.app_slug, a.name, a.description, a.status, a.scope, a.tier, a.hostname, a.is_default, a.manifest, a.secret_names,
19
+ (SELECT COUNT(DISTINCT g.user_id) FROM (
20
+ SELECT ua.user_id FROM user_app_access ua WHERE ua.app_row_id = a.id AND ua.organization_id = a.organization_id
21
+ UNION ALL
22
+ SELECT gm.user_id FROM group_app_access ga JOIN group_members gm ON gm.group_id = ga.group_id
23
+ WHERE ga.app_row_id = a.id AND ga.organization_id = a.organization_id AND gm.organization_id = a.organization_id
24
+ ) g JOIN members mm ON mm.user_id = g.user_id AND mm.organization_id = a.organization_id) AS access_count`,W=e=>({id:String(e.id),name:String(e.name),slug:String(e.slug)});async function ue(e,n){let a=n.trim(),[r=[],t=[]]=await e.run([{sql:`SELECT id, name, slug FROM organizations
25
+ WHERE id = ?1 OR slug = ?1 OR lower(name) = lower(?1)
26
+ ORDER BY created_at, id`,params:[a]},{sql:"SELECT id, name, slug FROM organizations ORDER BY created_at, id"}]),i=r.map(W),d=i.find(s=>s.id===a)??i.find(s=>s.slug===a);if(d)return d;if(i.length===1)return i[0];if(i.length>1)throw new l("ORG_AMBIGUOUS",`${i.length} organizations are named ${a}: ${k(i.map(s=>`${s.slug} (${s.id})`))}
27
+ A name isn't unique, and any owner or admin can rename their organization; a slug or id is one organization's.`,{fix:"name it by its slug or id with --org",data:{organizations:i}});let u=t.map(W);throw new l("ORGANIZATION_NOT_FOUND",`No organization named ${a} on this Gateway${u.length>0?`
28
+ The Gateway has: ${k(u.map(s=>`${s.slug} (${s.name})`))}.`:""}`,{fix:"name one by its slug, id or name with --org",data:{organizations:u}})}async function Me(e,n){if(n.email===null)return{actor:n.actor,email:null,userId:null};let[a=[]]=await e.run([{sql:"SELECT id FROM users WHERE lower(email) = lower(?) AND email_verified = 1",params:[n.email]}]);return{actor:n.actor,email:n.email,userId:m(a[0]?.id)}}var le=()=>new l("ORGANIZATION_NOT_FOUND",`The Gateway has no organization yet
29
+ Its owner creates the first one by claiming it.`,{rerun:`${E} setup`,rerunNote:"prints the owner link"});async function na(e,n){if(n!==void 0)return ue(e,n);let a=await I(e);if(!a)throw le();return a.organization}async function ra(e,n,a={}){let[r,t]=await Promise.all([I(e),Me(e,n)]);if(a.org===void 0&&!r)throw le();let i=a.org===void 0?r.organization:await ue(e,a.org);return{db:e,organization:i,installOrganizationId:r?.organization.id??null,operator:t,now:a.now??Date.now()}}async function S(e,n){let a=n.trim(),[r=[]]=await e.db.run([{sql:`SELECT ${L} FROM members m JOIN users u ON u.id = m.user_id
30
+ WHERE m.organization_id = ?1 AND (lower(u.email) = lower(?2) OR u.id = ?2)
31
+ ORDER BY (u.id = ?2) DESC LIMIT 1`,params:[e.organization.id,a]}]),t=r[0];if(!t)throw new l("USER_NOT_FOUND",`${a} isn't a member of ${e.organization.name}`,{rerun:`${E} workspace users`,rerunNote:"lists the members and invitations"});return z(t,e.now)}async function w(e,n,{callable:a=!1}={}){let r=n.trim(),[t=[]]=await e.db.run([{sql:`SELECT ${J} FROM apps a
32
+ WHERE (a.organization_id = ?1${a?" OR a.scope = 'shared'":""}) AND a.status != '${N}'
33
+ AND (a.app_slug = ?2 OR a.id = ?2)
34
+ ORDER BY (a.organization_id = ?1) DESC, (a.id = ?2) DESC LIMIT 1`,params:[e.organization.id,r]}]),i=t[0];if(!i)throw new l("APP_NOT_FOUND",`No app named ${r} in ${e.organization.name}`,{rerun:`${E} workspace apps`,rerunNote:"lists them"});return Y(i)}async function ge(e,n){let a=n.trim(),[r=[]]=await e.db.run([{sql:`${be} AND (g.id = ?2 OR lower(g.name) = lower(?2)) ORDER BY (g.id = ?2) DESC LIMIT 1`,params:[e.organization.id,a]}]),t=r[0];if(!t)throw new l("GROUP_NOT_FOUND",`No group named ${a} in ${e.organization.name}`,{rerun:`${E} workspace groups`,rerunNote:"lists them"});return pe(t)}async function _e(e,n){let a=n.trim(),[r=[]]=await e.db.run([{sql:`SELECT id, email, role, status, expires_at, created_at FROM invitations
35
+ WHERE organization_id = ?1 AND status = 'pending' AND (id = ?2 OR lower(email) = lower(?2))
36
+ ORDER BY (id = ?2) DESC, created_at DESC LIMIT 1`,params:[e.organization.id,a]}]),t=r[0];if(!t)throw new l("INVITATION_NOT_PENDING",`No pending invitation for ${a} in ${e.organization.name}
37
+ It was accepted, canceled or never made.`,{rerun:`${E} workspace users`,rerunNote:"lists the pending invitations"});return B(t,e.now)}async function ta(e){let n=e.organization.id,[a=[],r=[]]=await e.db.run([{sql:`SELECT u.email FROM members m JOIN users u ON u.id = m.user_id
38
+ WHERE m.organization_id = ?1 AND ${y("m.role")} ORDER BY m.created_at, u.email`,params:[n]},{sql:`SELECT
39
+ (SELECT COUNT(*) FROM members WHERE organization_id = ?1) AS members,
40
+ (SELECT COUNT(*) FROM members m JOIN users u ON u.id = m.user_id WHERE m.organization_id = ?1 AND ${ze("?2")}) AS deactivated,
41
+ (SELECT COUNT(*) FROM invitations WHERE organization_id = ?1 AND status = 'pending' AND expires_at > ?2) AS invitations,
42
+ (SELECT COUNT(*) FROM groups WHERE organization_id = ?1) AS groups,
43
+ (SELECT COUNT(*) FROM apps WHERE organization_id = ?1 AND status != '${N}') AS apps`,params:[n,e.now]}]),t=r[0]??{};return{organization:e.organization,owners:a.map(i=>String(i.email)),counts:{members:g(t.members),deactivated:g(t.deactivated),invitations:g(t.invitations),groups:g(t.groups),apps:g(t.apps)}}}async function ia(e){let[n=[],a=[]]=await e.db.run([{sql:`SELECT ${L} FROM members m JOIN users u ON u.id = m.user_id
44
+ WHERE m.organization_id = ?1 ORDER BY u.email`,params:[e.organization.id]},{sql:`SELECT id, email, role, status, expires_at, created_at FROM invitations
45
+ WHERE organization_id = ?1 AND status = 'pending' ORDER BY created_at DESC`,params:[e.organization.id]}]),r={owner:0,admin:1,member:2};return{members:n.map(t=>z(t,e.now)).sort((t,i)=>(r[t.primaryRole??"member"]??3)-(r[i.primaryRole??"member"]??3)||t.email.localeCompare(i.email)),invitations:a.map(t=>B(t,e.now))}}function Ee(){let e=`einv_${q(32).toString("base64url")}`;return{token:e,hash:Ce(e)}}var oa=(e,n)=>`${e}/accept-invitation?token=${encodeURIComponent(n)}`,sa=(e,n)=>`${e}/reset-password?token=${encodeURIComponent(n)}`;async function da(e,n,a){let r=n.trim().toLowerCase(),t=await $e(e,"invite");await ie(e,r);let i=O(),{token:d,hash:u}=Ee(),s=e.now+We,[,,o=[]]=await e.db.run([{sql:`INSERT INTO invitations (id, organization_id, email, role, status, expires_at, created_at, inviter_id)
46
+ SELECT ?1, ?2, ?3, ?4, 'pending', ?5, ?6, ?7
47
+ WHERE NOT EXISTS (SELECT 1 FROM members m JOIN users u ON u.id = m.user_id WHERE m.organization_id = ?2 AND lower(u.email) = ?3)
48
+ AND NOT EXISTS (SELECT 1 FROM invitations i WHERE i.organization_id = ?2 AND lower(i.email) = ?3 AND i.status = 'pending' AND i.expires_at > ?6)`,params:[i,e.organization.id,r,a,s,e.now,t]},{sql:`INSERT INTO invitation_link_tokens (id, invitation_id, token_hash, created_at)
49
+ SELECT ?1, ?2, ?3, ?4 WHERE EXISTS (SELECT 1 FROM invitations WHERE id = ?2)`,params:[O(),i,u,e.now]},{sql:"SELECT id, email, role, status, expires_at, created_at FROM invitations WHERE id = ?",params:[i]}]),p=o[0];if(!p)throw await ie(e,r),new l("ALREADY_INVITED",`${r} was invited meanwhile`,{retryable:!0});return{invitation:B(p,e.now),token:d}}async function $e(e,n){let{operator:a}=e;if(a.userId!==null){let[t=[]]=await e.db.run([{sql:"SELECT 1 AS member FROM members WHERE user_id = ? AND organization_id = ?",params:[a.userId,e.organization.id]}]);if(t.length>0)return a.userId}let r=a.email===null?"An API token has no account on the Gateway":a.userId===null?`${a.email} has no account on this Gateway (a verified one)`:`${a.email} isn't a member of ${e.organization.name}`;throw new l("WORKSPACE_NOT_A_MEMBER",`Only a member can ${n}: an invitation records who sent it
50
+ ${r}.`,{fix:a.email===null?`log in with your Cloudflare account (${E} login), claim the Gateway (${E} setup) or get invited, or invite from Admin \u2192 Users`:`claim the Gateway (${E} setup) or get invited to ${e.organization.name}, or invite from Admin \u2192 Users`})}async function ie(e,n){let[a=[],r=[]]=await e.db.run([{sql:"SELECT u.email FROM members m JOIN users u ON u.id = m.user_id WHERE m.organization_id = ?1 AND lower(u.email) = ?2",params:[e.organization.id,n]},{sql:"SELECT id FROM invitations WHERE organization_id = ?1 AND lower(email) = ?2 AND status = 'pending' AND expires_at > ?3",params:[e.organization.id,n,e.now]}]);if(a.length>0)throw new l("ALREADY_MEMBER",`${n} is a member of ${e.organization.name} already`,{rerun:`${E} workspace users`,rerunNote:"lists the members"});if(r.length>0)throw new l("ALREADY_INVITED",`${n} has a pending invitation to ${e.organization.name} already`,{rerun:`${E} workspace invite-link ${n}`,rerunNote:"prints a new link for it"})}async function ca(e,n){let a=await _e(e,n);if(!a.live)throw new l("INVITATION_NOT_PENDING",`The invitation for ${a.email} expired on ${new Date(a.expiresAt).toISOString()}`,{rerun:`${E} workspace invite ${a.email}`,rerunNote:"makes a new one"});let{token:r,hash:t}=Ee(),[i=[]]=await e.db.run([{sql:`INSERT INTO invitation_link_tokens (id, invitation_id, token_hash, created_at)
51
+ SELECT ?1, ?2, ?3, ?4 WHERE EXISTS (SELECT 1 FROM invitations WHERE id = ?2 AND status = 'pending' AND expires_at > ?4)
52
+ RETURNING id`,params:[O(),a.id,t,e.now]}]);if(i.length===0)throw new l("INVITATION_NOT_PENDING",`The invitation for ${a.email} was used or canceled meanwhile`);return{invitation:a,token:r}}async function ma(e,n){let a=await _e(e,n),[r=[]]=await e.db.run([{sql:"UPDATE invitations SET status = 'canceled' WHERE id = ? AND organization_id = ? AND status = 'pending' RETURNING id",params:[a.id,e.organization.id]}]);if(r.length===0)throw new l("INVITATION_NOT_PENDING",`The invitation for ${a.email} was used or canceled meanwhile`);return{...a,status:"canceled",live:!1}}function oe(e,n,a,r){let i=r.id===e.organization.id?`${n.email} is the last owner of ${r.name} who can act, so they can't be ${a}`:`${n.email} is the last owner of ${r.name} who can act, and a deactivation is account-wide: it would leave ${r.name} without one`,d=r.id===e.installOrganizationId?{rerun:`${E} workspace role <email> owner`,rerunNote:"for someone else, then this command again"}:{fix:`an owner of ${r.name} makes someone else an owner under Manage workspace \u2192 Users, then run this again`};return new l("LAST_OWNER",`${i}
53
+ Make someone else an owner of ${r.name} first, then try again.`,{...d,data:{organization:r,member:{id:n.id,email:n.email,name:n.name}}})}async function Ue(e,n,a){let[r=[]]=await e.db.run([{sql:`SELECT o.id, o.name, o.slug FROM members mine JOIN organizations o ON o.id = mine.organization_id
54
+ WHERE mine.user_id = ?1 AND ${a?"1":"mine.organization_id = ?3"} AND ${y("mine.role")}
55
+ AND NOT ${T("mine.organization_id","?1","?2")}
56
+ ORDER BY (mine.organization_id = ?3) DESC, o.created_at, o.id`,params:[n,e.now,e.organization.id]}]);return r.map(W)}async function f(e,n,a,r,{afterWrite:t=!1}={}){let i=t?await S(e,n.id):n,d=await Ue(e,i.id,r);if(d[0])throw oe(e,i,a,d[0]);if(t)throw oe(e,i,a,e.organization)}function Ne(e,n,a){let r=[n.id,e.organization.id,e.now];return[{sql:`UPDATE users SET banned = 1, ban_reason = ?4, ban_expires = NULL, updated_at = ?3
57
+ WHERE id = ?1 AND ${h} RETURNING id`,params:[...r,a]},{sql:`DELETE FROM sessions WHERE user_id = ?1 AND ${h}`,params:r},{sql:`UPDATE user_access_tokens SET revoked_at = ?3, updated_at = ?3
58
+ WHERE user_id = ?1 AND revoked_at IS NULL AND ${h}`,params:r},{sql:`UPDATE mcp_connections SET revoked_at = ?3, revoked_reason = 'user_deactivated'
59
+ WHERE user_id = ?1 AND revoked_at IS NULL AND ${h}`,params:r}]}async function pa(e,n){let a=await S(e,n);await f(e,a,"deactivated",!0);let[r=[]]=await e.db.run(Ne(e,a,`Deactivated by ${e.operator.actor} (${E} workspace deactivate)`));return r.length===0&&await f(e,a,"deactivated",!0,{afterWrite:!0}),{member:{...a,deactivated:!0},already:a.deactivated}}async function ua(e,n){let a=await S(e,n);return await e.db.run([{sql:`UPDATE users SET banned = 0, ban_reason = NULL, ban_expires = NULL, updated_at = ?3
60
+ WHERE id = ?1 AND EXISTS (SELECT 1 FROM members m WHERE m.user_id = ?1 AND m.organization_id = ?2)`,params:[a.id,e.organization.id,e.now]}]),{member:{...a,deactivated:!1},already:!a.deactivated}}async function la(e,n,a){let r=await S(e,n);await f(e,r,"removed",!1);let[t=[]]=await e.db.run([{sql:"SELECT COUNT(*) AS n FROM members WHERE user_id = ? AND organization_id != ?",params:[r.id,e.organization.id]}]),i=g(t[0]?.n);if(i===0&&await a.accessMayLetBackIn(r)){let[o=[]]=await e.db.run(Ne(e,r,`Removed by ${e.operator.actor} (${E} workspace remove); deactivated instead, as Cloudflare Access would let them back in`));return o.length===0&&await f(e,r,"removed",!0,{afterWrite:!0}),{member:{...r,deactivated:!0},deactivatedInstead:!0,accountDeleted:!1,otherOrganizations:i}}let d=[r.id,e.organization.id,e.now],[,,,,u=[],s=[]]=await e.db.run([{sql:`DELETE FROM user_app_access WHERE user_id = ?1 AND organization_id = ?2 AND ${v}`,params:d},{sql:`DELETE FROM group_members WHERE user_id = ?1 AND organization_id = ?2 AND ${v}`,params:d},{sql:`UPDATE user_access_tokens SET revoked_at = ?3, updated_at = ?3
61
+ WHERE user_id = ?1 AND organization_id = ?2 AND revoked_at IS NULL AND ${v}`,params:d},{sql:`UPDATE mcp_connections SET revoked_at = ?3, revoked_reason = 'member_removed'
62
+ WHERE user_id = ?1 AND organization_id = ?2 AND revoked_at IS NULL AND ${v}`,params:d},{sql:`DELETE FROM members WHERE user_id = ?1 AND organization_id = ?2 AND ${me("role")} RETURNING id`,params:d},a.deleteAccounts?{sql:"DELETE FROM users WHERE id = ?1 AND NOT EXISTS (SELECT 1 FROM members WHERE user_id = ?1) RETURNING id",params:[r.id]}:{sql:"SELECT NULL AS id WHERE 0"}]);return u.length===0&&await f(e,r,"removed",!1,{afterWrite:!0}),{member:r,deactivatedInstead:!1,accountDeleted:s.length>0,otherOrganizations:i}}async function ga(e,n){let a=await S(e,n);if(a.deactivated)throw new l("PASSWORD_RESET_REQUIRES_ACTIVE_USER",`${a.email} is deactivated, and a password-reset link is only for an active account`,{rerun:`${E} workspace reactivate ${a.email}`,rerunNote:"first, if they should be back"});let[r=[]]=await e.db.run([{sql:`SELECT o.id, o.name, o.slug FROM members m JOIN organizations o ON o.id = m.organization_id
63
+ WHERE m.user_id = ?1 AND m.organization_id != ?2 ORDER BY o.created_at, o.id`,params:[a.id,e.organization.id]}]);if(r.length>0){let d=r.map(W);throw new l("USER_IN_OTHER_ORGANIZATION",`${a.email} also belongs to ${k(d.map(u=>u.name))}, and a password is account-wide
64
+ The Gateway's own rule: a password-reset link is never made for someone in another organization, since it would reach that one too.`,{fix:"they reset it themselves with Forgot password (the Gateway's email must be configured), or they are removed from the other organization first",data:{member:{id:a.id,email:a.email,name:a.name},organizations:d}})}let t=q(24).toString("base64url"),i=e.now+we;return await e.db.run([{sql:`INSERT INTO verifications (id, identifier, value, expires_at, created_at, updated_at)
65
+ VALUES (?1, ?2, ?3, ?4, ?5, ?5)`,params:[O(),`reset-password:${t}`,a.id,i,e.now]}]),{member:a,token:t,expiresAt:i}}var be=`SELECT g.id, g.name, g.description, g.created_at,
66
+ (SELECT COUNT(*) FROM group_members gm WHERE gm.group_id = g.id) AS member_count,
67
+ (SELECT COUNT(*) FROM group_app_access ga JOIN apps a ON a.id = ga.app_row_id AND a.status != '${N}' WHERE ga.group_id = g.id) AS app_count
68
+ FROM groups g WHERE g.organization_id = ?1`;async function _a(e){let[n=[]]=await e.db.run([{sql:`${be} ORDER BY g.name`,params:[e.organization.id]}]);return n.map(pe)}function Ae(e){let n=e.trim();if(n.length<1||n.length>re)throw new l("GROUP_NAME_INVALID",`A group name is 1 to ${re} characters${n?` (${n.length} given)`:""}`);return n}function Re(e){return new l("GROUP_NAME_TAKEN",`A group named "${e}" exists already in this organization`,{rerun:`${E} workspace groups`,rerunNote:"lists them"})}var xe=()=>`grp_${q(8).toString("hex")}`;async function Ea(e,n){let a=Ae(n.name),r=n.description?.trim()||null,t=xe(),[i=[]]=await e.db.run([{sql:`INSERT INTO groups (id, organization_id, name, description, created_at, created_by)
69
+ SELECT ?1, ?2, ?3, ?4, ?5, ?6
70
+ WHERE NOT EXISTS (SELECT 1 FROM groups WHERE organization_id = ?2 AND lower(name) = lower(?3))
71
+ RETURNING id`,params:[t,e.organization.id,a,r,e.now,e.operator.userId]}]);if(i.length===0)throw Re(a);return{id:t,name:a,description:r,createdAt:e.now,memberCount:0,appCount:0}}async function Na(e,n,a){let r=await ge(e,n),t=a.name===void 0?r.name:Ae(a.name),i=a.description===void 0?r.description:a.description.trim()||null,[d=[]]=await e.db.run([{sql:`UPDATE groups SET name = ?3, description = ?4
72
+ WHERE id = ?1 AND organization_id = ?2
73
+ AND NOT EXISTS (SELECT 1 FROM groups WHERE organization_id = ?2 AND lower(name) = lower(?3) AND id != ?1)
74
+ RETURNING id`,params:[r.id,e.organization.id,t,i]}]);if(d.length===0)throw Re(t);return{...r,name:t,description:i}}async function ba(e,n){let a=await ge(e,n),r=[a.id,e.organization.id];return await e.db.run([{sql:"DELETE FROM group_app_access WHERE group_id = ?1 AND organization_id = ?2",params:r},{sql:"DELETE FROM group_members WHERE group_id = ?1 AND organization_id = ?2",params:r},{sql:"DELETE FROM groups WHERE id = ?1 AND organization_id = ?2",params:r}]),a}async function se(e,n){let[a=[]]=await e.db.run([{sql:`SELECT ${L}, (gm.user_id IS NOT NULL) AS in_group
75
+ FROM members m JOIN users u ON u.id = m.user_id
76
+ LEFT JOIN group_members gm ON gm.group_id = ?2 AND gm.user_id = u.id
77
+ WHERE m.organization_id = ?1 ORDER BY u.email`,params:[e.organization.id,n.id]}]);return a.map(r=>({...z(r,e.now),inGroup:Number(r.in_group)===1}))}function X(e,n){let a=new Set(e);if(n.set){let i=new Set(n.set);return{add:[...i].filter(d=>!a.has(d)),remove:[...a].filter(d=>!i.has(d))}}let r=[...new Set(n.add??[])].filter(i=>!a.has(i)),t=[...new Set(n.remove??[])].filter(i=>a.has(i));return{add:r,remove:t}}async function R(e,n){let a=[];for(let r of n){let t=await S(e,r);a.some(i=>i.id===t.id)||a.push(t)}return a}async function x(e,n){let a=[];for(let r of n){let t=await w(e,r);a.some(i=>i.id===t.id)||a.push(t)}return a}async function Aa(e,n,a){let[r,t,i]=await Promise.all([a.set?R(e,a.set):void 0,R(e,a.add??[]),R(e,a.remove??[])]),d=await se(e,n),u=d.filter(p=>p.inGroup).map(p=>p.id),s=X(u,{set:r?.map(p=>p.id),add:t.map(p=>p.id),remove:i.map(p=>p.id)}),o=new Map(d.map(p=>[p.id,p]));return await e.db.run([...C(s.remove,G).map(p=>({sql:`DELETE FROM group_members WHERE group_id = ? AND organization_id = ? AND user_id IN (${p.map(()=>"?").join(", ")})`,params:[n.id,e.organization.id,...p]})),...s.add.map(p=>({sql:`INSERT INTO group_members (group_id, user_id, organization_id, added_at, added_by)
78
+ SELECT ?1, ?2, ?3, ?4, ?5 WHERE EXISTS (SELECT 1 FROM members WHERE user_id = ?2 AND organization_id = ?3)
79
+ ON CONFLICT DO NOTHING`,params:[n.id,p,e.organization.id,e.now,e.operator.userId]}))]),{added:s.add.map(p=>o.get(p)),removed:s.remove.map(p=>o.get(p)),members:await se(e,n)}}async function de(e,n){let[a=[]]=await e.db.run([{sql:`SELECT ${J}, (ga.group_id IS NOT NULL) AS granted FROM apps a
80
+ LEFT JOIN group_app_access ga ON ga.group_id = ?2 AND ga.app_row_id = a.id
81
+ WHERE a.organization_id = ?1 AND a.scope != 'shared' AND a.status != '${N}' ORDER BY a.name`,params:[e.organization.id,n.id]}]);return a.map(r=>({...Y(r),granted:Number(r.granted)===1}))}function M(e){return new l("SHARED_APP_ACCESS",`${e.appSlug} is a shared app: every member of every organization can open it, so its access can't be changed`)}async function Ra(e,n,a){let[r,t,i]=await Promise.all([a.set?x(e,a.set):void 0,x(e,a.add??[]),x(e,a.remove??[])]);for(let o of[...r??[],...t])if(o.scope==="shared")throw M(o);let d=await de(e,n),u=X(d.filter(o=>o.granted).map(o=>o.id),{set:r?.map(o=>o.id),add:t.map(o=>o.id),remove:i.map(o=>o.id)}),s=new Map(d.map(o=>[o.id,o]));return await e.db.run([...C(u.remove,G).map(o=>({sql:`DELETE FROM group_app_access WHERE group_id = ? AND organization_id = ? AND app_row_id IN (${o.map(()=>"?").join(", ")})`,params:[n.id,e.organization.id,...o]})),...u.add.map(o=>({sql:`INSERT INTO group_app_access (group_id, app_row_id, organization_id, granted_at, granted_by)
82
+ SELECT ?1, ?2, ?3, ?4, ?5
83
+ WHERE EXISTS (SELECT 1 FROM apps WHERE id = ?2 AND organization_id = ?3 AND scope != 'shared' AND status != '${N}')
84
+ ON CONFLICT DO NOTHING`,params:[n.id,o,e.organization.id,e.now,e.operator.userId]}))]),{added:u.add.map(o=>s.get(o)),removed:u.remove.map(o=>s.get(o)),apps:await de(e,n)}}async function Oa(e){let[n=[]]=await e.db.run([{sql:`SELECT ${J} FROM apps a WHERE a.organization_id = ?1 AND a.status != '${N}' ORDER BY a.name`,params:[e.organization.id]}]);return n.map(Y)}function Fe(e){let n=e.trim();if(n.length<1||n.length>te)throw new l("APP_NAME_INVALID",`An app's name is 1 to ${te} characters${n?` (${n.length} given)`:", not empty"}`,{fix:"give --name the name the app library should show, or leave --name off"});return n}async function Sa(e,n,a){let r=await w(e,n);if(a.name===void 0&&a.description===void 0&&a.everyone===void 0)throw new l("NOTHING_TO_SET","Nothing to set: give --name, --description or --everyone on|off");if(r.scope==="shared"&&a.everyone)throw M(r);let t=a.name===void 0?r.name:Fe(a.name),i=a.description===void 0?r.description:a.description.trim(),d=a.everyone??r.everyone,u=[];if(d&&!r.everyone){let[o=[]]=await e.db.run([{sql:"SELECT user_id FROM members WHERE organization_id = ?",params:[e.organization.id]}]);for(let p of C(o,ye))u.push({sql:`INSERT INTO user_app_access (id, user_id, app_row_id, organization_id, granted_by) VALUES ${p.map(()=>"(?, ?, ?, ?, ?)").join(", ")} ON CONFLICT DO NOTHING RETURNING id`,params:p.flatMap($=>[O(),String($.user_id),r.id,e.organization.id,e.operator.userId])})}let[,...s]=await e.db.run([{sql:`UPDATE apps SET name = ?3, description = ?4, is_default = ?5, updated_at = ?6
85
+ WHERE id = ?1 AND organization_id = ?2 AND status != '${N}'`,params:[r.id,e.organization.id,t,i,d?1:0,e.now]},...u]);return{app:await w(e,r.id),granted:s.reduce((o,p)=>o+p.length,0)}}async function ce(e,n){if(n.scope==="shared")throw M(n);let[a=[]]=await e.db.run([{sql:`SELECT ${L},
86
+ (ua.id IS NOT NULL) AS direct,
87
+ (SELECT group_concat(g.name, char(31)) FROM group_app_access ga
88
+ JOIN group_members gm ON gm.group_id = ga.group_id AND gm.user_id = u.id
89
+ JOIN groups g ON g.id = ga.group_id
90
+ WHERE ga.app_row_id = ?2 AND ga.organization_id = ?1) AS via_groups
91
+ FROM members m JOIN users u ON u.id = m.user_id
92
+ LEFT JOIN user_app_access ua ON ua.app_row_id = ?2 AND ua.organization_id = ?1 AND ua.user_id = u.id
93
+ WHERE m.organization_id = ?1 ORDER BY u.email`,params:[e.organization.id,n.id]}]);return a.map(r=>({...z(r,e.now),direct:Number(r.direct)===1,viaGroups:m(r.via_groups)?.split("").sort()??[]}))}async function Ta(e,n,a){if(n.scope==="shared")throw M(n);let[r,t,i]=await Promise.all([a.set?R(e,a.set):void 0,R(e,a.add??[]),R(e,a.remove??[])]),d=await ce(e,n),u=X(d.filter(o=>o.direct).map(o=>o.id),{set:r?.map(o=>o.id),add:t.map(o=>o.id),remove:i.map(o=>o.id)}),s=new Map(d.map(o=>[o.id,o]));return await e.db.run([...C(u.remove,G).map(o=>({sql:`DELETE FROM user_app_access WHERE app_row_id = ? AND organization_id = ? AND user_id IN (${o.map(()=>"?").join(", ")})`,params:[n.id,e.organization.id,...o]})),...u.add.map(o=>({sql:`INSERT INTO user_app_access (id, user_id, app_row_id, organization_id, granted_at, granted_by)
94
+ SELECT ?1, ?2, ?3, ?4, ?5, ?6 WHERE EXISTS (SELECT 1 FROM members WHERE user_id = ?2 AND organization_id = ?4)
95
+ ON CONFLICT DO NOTHING`,params:[O(),o,n.id,e.organization.id,e.now,e.operator.userId]}))]),{granted:u.add.map(o=>s.get(o)),revoked:u.remove.map(o=>s.get(o)),users:await ce(e,n)}}async function fa(e,n,a){let r=await w(e,n,{callable:!0});if(a!==null&&(!Number.isInteger(a)||a<1||a>ne))throw new l("INVALID_CAP",`A monthly cap is a whole number from 1 to ${ne.toLocaleString("en-US")}, or off`);let[t=[]]=await e.db.run([{sql:"SELECT monthly_call_cap FROM org_app_settings WHERE organization_id = ? AND app_row_id = ?",params:[e.organization.id,r.id]}]),i=t[0]?.monthly_call_cap==null?null:Number(t[0].monthly_call_cap),d=a===null?null:await Z(e.db,{organizationId:e.organization.id,deployer:e.operator,now:e.now}),s=(a===null?i!==null:i===null||a>i)?await j(e.db,{organizationId:e.organization.id,type:"cap.raised",actor:K(e.operator),data:{app:{id:r.appSlug,rowId:r.id,name:r.name},cap:a,previousCap:i,source:"app"},appRowId:r.id,now:e.now}):[],o=await e.db.run([a===null?{sql:"DELETE FROM org_app_settings WHERE organization_id = ? AND app_row_id = ?",params:[e.organization.id,r.id]}:{sql:`INSERT INTO org_app_settings (organization_id, app_row_id, monthly_call_cap, updated_at, updated_by)
96
+ VALUES (?1, ?2, ?3, ?4, ?5)
97
+ ON CONFLICT (organization_id, app_row_id) DO UPDATE SET monthly_call_cap = ?3, updated_at = ?4, updated_by = ?5`,params:[e.organization.id,r.id,a,e.now,e.operator.userId]},...d?[d]:[],...s]),p=d?m(o[1]?.[0]?.id):null;return{app:r,cap:a,was:i,capAlertsId:p}}var He=/^\d{4}-(0[1-9]|1[0-2])$/;function Pe(e){return`${e.getUTCFullYear()}-${String(e.getUTCMonth()+1).padStart(2,"0")}`}function qe(e,n){let[a,r]=e.split("-").map(Number);return Pe(new Date(Date.UTC(a,r-1+n,1)))}var F=`COALESCE(SUM(d.calls), 0) AS calls, COALESCE(SUM(d.failures), 0) AS failures,
98
+ COALESCE(SUM(d.input_tokens), 0) AS input_tokens, COALESCE(SUM(d.output_tokens), 0) AS output_tokens,
99
+ COALESCE(SUM(d.cost_micros), 0) AS cost_micros`,H=e=>({calls:g(e.calls),failures:g(e.failures),inputTokens:g(e.input_tokens),outputTokens:g(e.output_tokens),costMicros:g(e.cost_micros)}),P={calls:0,failures:0,inputTokens:0,outputTokens:0,costMicros:0};async function Da(e,n){if(!He.test(n))throw new l("INVALID_MONTH",`--month ${n} isn't a month: use YYYY-MM`);let a=e.organization.id,r=`${n}-01`,t=`${qe(n,1)}-01`,i=Date.parse(`${r}T00:00:00.000Z`),d=Date.parse(`${t}T00:00:00.000Z`),u="d.organization_id = ?1 AND d.day >= ?2 AND d.day < ?3",s="c.organization_id = ?1 AND c.decision = 'allowed' AND c.created_at >= ?2 AND c.created_at < ?3",[o=[],p=[],$=[],De=[],ke=[],Ie=[]]=await e.db.run([{sql:`SELECT d.app_row_id, a.name, a.app_slug, ${F} FROM usage_daily d LEFT JOIN apps a ON a.id = d.app_row_id
100
+ WHERE ${u} GROUP BY d.app_row_id, a.name, a.app_slug`,params:[a,r,t]},{sql:`SELECT d.user_id, u.name, u.email, ${F} FROM usage_daily d
101
+ LEFT JOIN members m ON m.user_id = d.user_id AND m.organization_id = d.organization_id
102
+ LEFT JOIN users u ON u.id = m.user_id
103
+ WHERE ${u} GROUP BY d.user_id, u.name, u.email`,params:[a,r,t]},{sql:`SELECT d.kind, d.target, ${F} FROM usage_daily d WHERE ${u} GROUP BY d.kind, d.target`,params:[a,r,t]},{sql:`SELECT c.app_row_id, a.name, a.app_slug, COUNT(*) AS tool_calls FROM mcp_tool_calls c
104
+ LEFT JOIN apps a ON a.id = c.app_row_id WHERE ${s} GROUP BY c.app_row_id, a.name, a.app_slug`,params:[a,i,d]},{sql:`SELECT c.user_id, u.name, u.email, COUNT(*) AS tool_calls FROM mcp_tool_calls c
105
+ LEFT JOIN members m ON m.user_id = c.user_id AND m.organization_id = c.organization_id
106
+ LEFT JOIN users u ON u.id = m.user_id
107
+ WHERE ${s} GROUP BY c.user_id, u.name, u.email`,params:[a,i,d]},{sql:`SELECT a.id AS app_row_id, a.name, a.app_slug, s.monthly_call_cap FROM apps a
108
+ LEFT JOIN org_app_settings s ON s.app_row_id = a.id AND s.organization_id = ?1
109
+ WHERE (a.organization_id = ?1 OR a.scope = 'shared') AND a.status != '${N}'`,params:[a]}]),A=new Map;for(let c of o)A.set(String(c.app_row_id),{appRowId:String(c.app_row_id),appSlug:m(c.app_slug),name:m(c.name),...H(c),toolCalls:0,monthlyCallCap:null,callable:!1});for(let c of De){let _=m(c.app_row_id);if(!_)continue;let b=A.get(_);b?b.toolCalls=g(c.tool_calls):A.set(_,{appRowId:_,appSlug:m(c.app_slug),name:m(c.name),...P,toolCalls:g(c.tool_calls),monthlyCallCap:null,callable:!1})}for(let c of Ie){let _=String(c.app_row_id),b=c.monthly_call_cap==null?null:Number(c.monthly_call_cap),U=A.get(_);U?(U.callable=!0,U.monthlyCallCap=b):A.set(_,{appRowId:_,appSlug:m(c.app_slug),name:m(c.name),...P,toolCalls:0,monthlyCallCap:b,callable:!0})}let D=new Map;for(let c of p)D.set(String(c.user_id),{userId:String(c.user_id),name:m(c.name),email:m(c.email),...H(c),toolCalls:0});for(let c of ke){let _=String(c.user_id),b=D.get(_);b?b.toolCalls=g(c.tool_calls):D.set(_,{userId:_,name:m(c.name),email:m(c.email),...P,toolCalls:g(c.tool_calls)})}let V=(c,_)=>_.calls-c.calls||_.toolCalls-c.toolCalls;return{month:n,byApp:[...A.values()].sort((c,_)=>V(c,_)||(c.name??c.appRowId).localeCompare(_.name??_.appRowId)),byMember:[...D.values()].sort(V),byTarget:$.map(c=>({kind:String(c.kind),target:String(c.target),...H(c)})).sort((c,_)=>_.calls-c.calls)}}var Ge=200;async function ka(e,n){let a=Math.min(Math.max(1,Math.trunc(n.limit??50)||1),Ge),r=["c.organization_id = ?"],t=[e.organization.id];n.before&&(r.push("(c.created_at < ? OR (c.created_at = ? AND c.id < ?))"),t.push(n.before.createdAt,n.before.createdAt,n.before.id));for(let[s,o]of[["c.app_row_id",n.appRowId],["c.user_id",n.userId],["c.decision",n.decision],["c.risk",n.risk]])o!==void 0&&(r.push(`${s} = ?`),t.push(o));n.since!==void 0&&(r.push("c.created_at >= ?"),t.push(n.since)),t.push(a+1);let[i=[]]=await e.db.run([{sql:`SELECT c.id, c.created_at, c.user_id, u.name AS user_name, u.email AS user_email,
110
+ c.credential_kind, c.client_name, c.client_info, c.app_row_id, c.app_slug, a.name AS app_name, a.status AS app_status,
111
+ c.tool_name, c.via, c.risk, c.decision, c.reason, c.outcome, c.duration_ms, c.result_bytes
112
+ FROM mcp_tool_calls c
113
+ LEFT JOIN apps a ON a.id = c.app_row_id
114
+ LEFT JOIN members m ON m.user_id = c.user_id AND m.organization_id = c.organization_id
115
+ LEFT JOIN users u ON u.id = m.user_id
116
+ WHERE ${r.join(" AND ")}
117
+ ORDER BY c.created_at DESC, c.id DESC LIMIT ?`,params:t}]),d=i.slice(0,a),u=d.at(-1);return{calls:d.map(s=>{let o=m(s.app_row_id),p=m(s.app_status);return{id:String(s.id),createdAt:g(s.created_at),user:{id:String(s.user_id),name:m(s.user_name),email:m(s.user_email)},credential:{kind:String(s.credential_kind),clientName:m(s.client_name),clientInfo:m(s.client_info)},app:{rowId:o,slug:m(s.app_slug),name:m(s.app_name),removed:o!==null&&(p===null||p===N)},tool:{name:String(s.tool_name),risk:m(s.risk),via:m(s.via)},decision:s.decision==="allowed"?"allowed":"blocked",reason:m(s.reason),outcome:String(s.outcome),durationMs:s.duration_ms==null?null:Number(s.duration_ms),resultBytes:s.result_bytes==null?null:Number(s.result_bytes)}}),nextBefore:i.length>a&&u?{createdAt:g(u.created_at),id:String(u.id)}:null}}var Oe=`SELECT t.id, t.user_id, u.email, t.name, t.token_prefix, t.app_row_id, a.app_slug, a.name AS app_name,
118
+ t.scopes, t.created_at, t.expires_at, t.last_used_at, t.revoked_at
119
+ FROM user_access_tokens t JOIN users u ON u.id = t.user_id
120
+ LEFT JOIN apps a ON a.id = t.app_row_id AND a.organization_id = t.organization_id
121
+ WHERE t.organization_id = ?1`;function Se(e,n){let a=e.revoked_at==null?null:Number(e.revoked_at),r=g(e.expires_at),t=[];try{let i=JSON.parse(String(e.scopes??"[]"));t=Array.isArray(i)?i.map(String):[]}catch{t=[]}return{id:String(e.id),user:{id:String(e.user_id),email:String(e.email)},name:String(e.name),prefix:String(e.token_prefix),app:{rowId:m(e.app_row_id),slug:m(e.app_slug),name:m(e.app_name)},scopes:t,createdAt:g(e.created_at),expiresAt:r,lastUsedAt:e.last_used_at==null?null:Number(e.last_used_at),revokedAt:a,active:a===null&&r>n}}async function Ia(e,n){let[a=[]]=await e.db.run([{sql:`${Oe}${n?" AND t.user_id = ?2":""} ORDER BY t.created_at DESC`,params:n?[e.organization.id,n]:[e.organization.id]}]);return a.map(r=>Se(r,e.now))}async function va(e,n){let[a=[]]=await e.db.run([{sql:`${Oe} AND t.id = ?2`,params:[e.organization.id,n.trim()]}]),r=a[0];if(!r)throw new l("TOKEN_NOT_FOUND",`No personal access token ${n.trim()} in ${e.organization.name}`,{rerun:`${E} workspace tokens`,rerunNote:"lists them by id"});let t=Se(r,e.now);return t.revokedAt!==null?{token:t,already:!0}:(await e.db.run([{sql:"UPDATE user_access_tokens SET revoked_at = ?3, updated_at = ?3 WHERE id = ?1 AND organization_id = ?2 AND revoked_at IS NULL",params:[t.id,e.organization.id,e.now]}]),{token:{...t,revokedAt:e.now,active:!1},already:!1})}var Te=`SELECT c.id, c.user_id, u.email, c.client_name, c.client_domain, c.redirect_host, c.app_scope, c.access,
122
+ c.created_at, c.last_used_at, c.revoked_at, c.revoked_reason,
123
+ (SELECT group_concat(a.app_slug, char(31)) FROM mcp_connection_apps ca JOIN apps a ON a.id = ca.app_row_id WHERE ca.connection_id = c.id) AS app_slugs
124
+ FROM mcp_connections c JOIN users u ON u.id = c.user_id
125
+ WHERE c.organization_id = ?1`;function fe(e){return{id:String(e.id),user:{id:String(e.user_id),email:String(e.email)},clientName:String(e.client_name),clientDomain:m(e.client_domain),redirectHost:String(e.redirect_host),apps:e.app_scope==="all"?"all":m(e.app_slugs)?.split("").sort()??[],access:e.access==="write"?"write":"read",createdAt:g(e.created_at),lastUsedAt:e.last_used_at==null?null:Number(e.last_used_at),revokedAt:e.revoked_at==null?null:Number(e.revoked_at),revokedReason:m(e.revoked_reason)}}async function ha(e,n){let[a=[]]=await e.db.run([{sql:`${Te} AND c.revoked_at IS NULL${n?" AND c.user_id = ?2":""} ORDER BY c.created_at DESC`,params:n?[e.organization.id,n]:[e.organization.id]}]);return a.map(fe)}async function Wa(e,n){let[a=[]]=await e.db.run([{sql:`${Te} AND c.id = ?2`,params:[e.organization.id,n.trim()]}]),r=a[0];if(!r)throw new l("CONNECTION_NOT_FOUND",`No AI connection ${n.trim()} in ${e.organization.name}`,{rerun:`${E} workspace connections`,rerunNote:"lists them by id"});let t=fe(r);return t.revokedAt!==null?{connection:t,already:!0}:(await e.db.run([{sql:`UPDATE mcp_connections SET revoked_at = ?3, revoked_by = ?4, revoked_reason = 'user'
126
+ WHERE id = ?1 AND organization_id = ?2 AND revoked_at IS NULL`,params:[t.id,e.organization.id,e.now,e.operator.userId]}]),{connection:{...t,revokedAt:e.now,revokedReason:"user"},already:!1})}export{Be as a,aa as b,ne as c,na as d,ra as e,S as f,w as g,ge as h,ta as i,ia as j,oa as k,sa as l,da as m,ca as n,ma as o,pa as p,ua as q,la as r,ga as s,_a as t,Ea as u,Na as v,ba as w,se as x,Aa as y,de as z,Ra as A,Oa as B,Fe as C,Sa as D,ce as E,Ta as F,fa as G,He as H,Pe as I,Da as J,Ge as K,ka as L,Ia as M,va as N,ha as O,Wa as P};
@@ -0,0 +1,4 @@
1
+ import{d as L}from"./chunk-ECLJ5IAL.js";import{A as x,E as T,O as y,P as h,Q as O,R as F,qa as k,sa as z,w as I}from"./chunk-ZYL2ZHCF.js";import{a as D}from"./chunk-F6IH47GT.js";import{c as v,f as A,hc as C}from"./chunk-SAT3PGZU.js";import u from"chalk";import f from"chalk";async function E(t){let{flags:e,out:l,createCf:i}=t,r=await z({gateway:k(e.gateway),accountId:e["account-id"],interactive:D(e.json??!1),login:{json:e.json,out:l,step:"login"},createCf:i});await x(r.db);let o=await L(r.db,e.org);return{gateway:r,organization:o}}function $(t){return t===null?f.dim("never"):new Date(t).toISOString().slice(0,16).replace("T"," ")}var d=t=>t===null?null:new Date(t).toISOString();function R(t){return t.sink==="email"?t.recipients==="owners"?"email \u2192 owners":"email \u2192 owners and admins":t.url?I(t.url):"(no URL)"}function B(t){return t.includes("*")?"everything":t.join(", ")}function X(t){return{id:t.id,name:t.name,sink:t.sink,target:R(t),recipients:t.recipients,events:t.events,enabled:t.enabled,builtin:t.builtin,createdAt:d(t.createdAt),createdBy:t.createdBy,lastDeliveryAt:d(t.lastDeliveryAt),lastDeliveryStatus:t.lastDeliveryStatus,consecutiveFailures:t.consecutiveFailures}}var H=t=>`${t.name} (${t.id})`;function N(t,e){let l=y(t,e),i=t.lastStatusCode!==null&&t.lastStatusCode>0?t.lastStatusCode:null,r=i===null?"":t.sink==="email"?`, ${i} mailed`:` ${i}`;switch(l){case"delivered":return f.green(`delivered${r}`);case"dead":return f.red("dead");case"failed":return f.yellow(`failed${r}, retrying`);default:return f.dim(t.attempts>0?"sending":"queued")}}function b(t,e){return{id:t.id,eventId:t.eventId,type:t.type,subscriptionId:t.subscriptionId,subscriptionName:t.subscriptionName,sink:t.sink,status:t.status,state:y(t,e),attempts:t.attempts,lastStatusCode:t.lastStatusCode,lastError:t.lastError,nextAttemptAt:d(t.nextAttemptAt),lastAttemptAt:d(t.lastAttemptAt),deliveredAt:d(t.deliveredAt),redeliveredAt:d(t.redeliveredAt),createdAt:d(t.createdAt)}}var S=t=>({id:t.id,name:t.name,slug:t.slug});var j=20;function et(t){let e=Number(t);if(!Number.isInteger(e)||e<1||e>h)throw new Error(`Use a whole number from 1 to ${h}.`);return e}var G=t=>{let e=t.lastError?.split(`
2
+ `)[0];return e?u.dim(e.length>60?`${e.slice(0,59)}\u2026`:e):""};async function nt(t,e){let{out:l,flags:i}=t,{gateway:r,organization:o}=await E(t),c=t.now?.()??Date.now(),n=e?await T(r.db,o,e):null,s=await O(r.db,{organizationId:o.id,...n?{subscriptionId:n.id}:{},dead:i.dead??!1,limit:i.limit??j,now:c}),m=n?` to ${n.name}`:"",p=i.dead?"dead ":"",g=s.length===0?`No ${p}deliveries${m} in the last 30 days`:s.length===1?`The last ${p}delivery${m}`:`The last ${s.length} ${p}deliveries${m}`,w=s.filter(a=>a.status==="dead");l.emit({type:"done",message:g,display:[...s.length===0?[u.dim(`${g}.`)]:[...C(["WHEN","DELIVERY","EVENT","TO","STATUS","TRIES","NEXT","LAST ERROR"],s.map(a=>[$(a.createdAt),a.id,a.type??u.dim("(expired)"),a.subscriptionName??u.dim(a.subscriptionId),N(a,c),String(a.attempts),a.status==="pending"&&a.nextAttemptAt!==null?$(a.nextAttemptAt):"",G(a)])),...w.length>0?["",u.dim(`Send a dead one again: ${v} events redeliver <delivery>`)]:[]]].join(`
3
+ `),data:{organization:S(o),subscriptionId:n?.id??null,dead:i.dead??!1,deliveries:s.map(a=>b(a,c))}})}async function at(t,e){let{out:l}=t,{gateway:i,organization:r}=await E(t),o=t.now?.()??Date.now(),{delivery:c,previous:n,outcome:s}=await F(i.db,r,e,o),m=`${n.type??"the event"} to ${n.subscriptionName??n.subscriptionId}`,p=n.status==="dead"?`it was dead after ${A(n.attempts,"attempt")}`:`it was ${n.attempts>0?"failing":"queued"}`,g=s==="attempting"?`${n.id} is being sent right now. Nothing changed.`:s==="delivered"?`${n.id} was already delivered (${m}). Nothing changed.`:`Queued ${n.id} again (${m}; ${p}).`,w=s==="queued"?"The Gateway sends it within a minute, with the full retry schedule.":`See how it went: ${v} events deliveries ${n.subscriptionId}`;l.emit({type:"done",message:`${g} ${w}`,display:[g,u.dim(w)].join(`
4
+ `),data:{outcome:s,delivery:b(c,o),previousStatus:n.status,organization:S(r)}})}export{E as a,$ as b,R as c,B as d,X as e,H as f,b as g,S as h,et as i,nt as j,at as k};
@@ -0,0 +1,20 @@
1
+ import{b as k}from"./chunk-7LG3F4FF.js";import{Bb as M,Hb as U,bc as p,c as q,g as H,i as h,tb as S,xb as C}from"./chunk-SAT3PGZU.js";import{randomBytes as J}from"node:crypto";import R from"node:os";var Z={["app.deploy"]:{noun:"deploy",of:e=>`a deploy${e?` of ${e}`:""}`},["app.register"]:{noun:"registration",of:e=>`a registration${e?` of ${e}`:""}`},["app.secrets"]:{noun:"secret change",of:e=>`a secret change${e?` on ${e}`:""}`},["app.email"]:{noun:"email change",of:e=>`an email change${e?` on ${e}`:""}`},["gateway.deploy"]:{noun:"Gateway install",of:()=>"a Gateway install"},["gateway.upgrade"]:{noun:"Gateway upgrade",of:()=>"a Gateway upgrade"},["gateway.reconcile"]:{noun:"Gateway update",of:()=>"an update of the Gateway's apps"},["gateway.secrets"]:{noun:"Gateway settings change",of:()=>"a change to the Gateway's settings"},["access.sync"]:{noun:"Cloudflare Access update",of:()=>"an update of Cloudflare Access"},["db.restore"]:{noun:"database restore",of:e=>`a restore of ${e?`${e}'s database`:"the Gateway's database"}`}},ee=`CREATE TABLE IF NOT EXISTS _everyapp_deploy_lease (
2
+ id TEXT PRIMARY KEY,
3
+ holder TEXT NOT NULL,
4
+ purpose TEXT NOT NULL,
5
+ acquired_at INTEGER NOT NULL,
6
+ expires_at INTEGER NOT NULL,
7
+ app TEXT,
8
+ deployer TEXT,
9
+ machine TEXT
10
+ )`,B=["app","deployer","machine"],te=`INSERT INTO _everyapp_deploy_lease (id, holder, purpose, acquired_at, expires_at, app, deployer, machine)
11
+ VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8)
12
+ ON CONFLICT(id) DO UPDATE SET holder = excluded.holder, purpose = excluded.purpose,
13
+ acquired_at = excluded.acquired_at, expires_at = excluded.expires_at,
14
+ app = excluded.app, deployer = excluded.deployer, machine = excluded.machine
15
+ WHERE _everyapp_deploy_lease.expires_at < ?4 OR _everyapp_deploy_lease.holder = ?2
16
+ RETURNING holder`,ae="UPDATE _everyapp_deploy_lease SET expires_at = ? WHERE id = ? AND holder = ? RETURNING holder",g=3*6e4,re=3e4,W=2e4,se=5*6e4,ne=5e3;function oe(){return R.hostname().split(".")[0]||R.hostname()}function ie(){return`${R.hostname()}:${process.pid}:${J(4).toString("hex")}`}var X=`SELECT id, holder, purpose, acquired_at, expires_at, ${B.join(", ")} FROM _everyapp_deploy_lease`,$=new WeakMap;function b(e){let t=$.get(e);return t||(t=(async()=>{let[,r=[]]=await e.run([{sql:ee},{sql:"PRAGMA table_info(_everyapp_deploy_lease)"}]),u=new Set(r.map(s=>String(s.name))),n=B.filter(s=>!u.has(s));n.length>0&&await e.run(n.map(s=>({sql:`ALTER TABLE _everyapp_deploy_lease ADD COLUMN ${s} TEXT`})))})(),t.catch(()=>$.delete(e)),$.set(e,t)),t}function F(e){let t=String(e.holder);return{id:String(e.id),holder:t,purpose:String(e.purpose),acquiredAt:Number(e.acquired_at),expiresAt:Number(e.expires_at),app:h(e.app),deployer:h(e.deployer),machine:h(e.machine)??t.split(":")[0].split(".")[0]}}async function pe(e,t){await b(e);let[r=[]]=await e.run([{sql:`${X} WHERE id = ?`,params:[t]}]);return r[0]?F(r[0]):null}async function Ae(e,t=Date.now()){await b(e);let[r=[]]=await e.run([{sql:`${X} WHERE expires_at > ? ORDER BY acquired_at`,params:[t]}]);return r.map(F)}var D=e=>Z[e.purpose];function x(e){return D(e)?.of(e.app)??"another run"}function Y(e,t=Date.now()){return`${e.deployer?`${e.deployer} on `:""}${e.machine}, started ${p(t-e.acquiredAt)} ago`}function Le(e,t=Date.now()){return`${x(e)} from ${Y(e,t)}`}async function j({db:e,id:t,purpose:r,app:u,out:n,step:s,now:o=Date.now,sleep:z=l=>new Promise(A=>setTimeout(A,l)),waitMs:_=se,heartbeatMs:v=re}){let l=ie(),A=o()+_,d=t==="gateway"?"the Gateway":u??"this app";await b(e);let I,m=null;for(;;){let i=o(),[c=[]]=await e.run([{sql:te,params:[t,l,r,i,i+g,u??null,k(),oe()]}]);if(c[0]?.holder===l){I=i;break}let a=await pe(e,t);if(o()>=A)throw new S("LEASE_HELD",a?`${H(x(a))} is still running after ${p(_)}
17
+ It's from ${a.deployer?`${a.deployer} on `:""}${a.machine}. If it stopped without cleaning up, it's released within ${p(a.expiresAt-o())}.`:`Couldn't take hold of ${d} after ${p(_)}`,{retryable:!0,rerunNote:`once it's done (${q} status shows it)`,...a?{data:{holder:a}}:{}});a&&(m=a,n.emit({type:"progress",step:s,message:`Waiting for ${x(a)} to finish (${Y(a,o())})`,data:{holder:a}})),await z(ne)}m&&n.emit({type:"step",step:s,status:"ok",message:`The other ${D(m)?.noun??"run"} finished.`,data:{waitedFor:D(m)?.noun??"run"}});let L=I,f=!1,T=!1,y=!1,w=null,N=i=>n.emit({type:"warning",code:"LEASE_HEARTBEAT",step:s,message:i}),K=async()=>{if(f||y)return;let i=o();try{let[c=[]]=await e.run([{sql:ae,params:[i+g,t,l]}],{timeoutMs:W});c.length>0?L=i:f=!0}catch(c){if(y)return;let a=o()-L;if(a>g/2){f=!0;return}let V=c instanceof M?`The database didn't answer within ${p(W)}`:C(c);N(`Can't reach Cloudflare to keep hold of ${d} (${p(a)} so far)
18
+ ${V}. Another run can take over in ${p(L+g-o())} if this continues.`)}},P=()=>w??=K().finally(()=>{w=null}),E=v>0?setInterval(()=>{P().then(()=>{!f||y||T||(T=!0,clearInterval(E),N(`This run lost its hold on ${d}
19
+ Its hold expired, and another run may have started. It stops before its next change.`))})},v):void 0;E?.unref();let G=()=>e.run([{sql:"DELETE FROM _everyapp_deploy_lease WHERE id = ? AND holder = ?",params:[t,l]}]),O=()=>{y=!0,clearInterval(E)},Q=U({label:`freeing ${d} for other runs`,async:async()=>{O(),await G()}});return{id:t,holder:l,async check(){if(await w,await P(),f)throw T=!0,clearInterval(E),new S("LEASE_LOST",`Stopped: this run lost its hold on ${d}
20
+ Its hold expired, so it stopped before its next change to avoid overlapping another run.`,{retryable:!0})},async release(){O(),await G(),Q()}}}var le="gateway",Te="access";function ue(e){return`app:${e}`}function we({db:e,out:t},{workerName:r,appId:u,purpose:n}){return j({db:e,id:ue(r),purpose:n,app:u,out:t,step:"app.lease"})}function Se(e,t){return j({db:e.db,id:le,purpose:t,out:e.out,step:"gateway.lease",waitMs:e.leaseWaitMs,...e.sleep?{sleep:e.sleep}:{}})}export{Ae as a,Le as b,j as c,le as d,Te as e,ue as f,we as g,Se as h};
@@ -0,0 +1,4 @@
1
+ import{Db as d,tb as g,vb as m}from"./chunk-SAT3PGZU.js";import{confirm as f,input as u,password as h,select as y}from"@inquirer/prompts";import t from"chalk";function A(e){return!!(process.stdin.isTTY&&process.stderr.isTTY)&&!e&&!process.env.CI}var a={prefix:{idle:t.cyan("?"),done:t.green("\u2714")},style:{message:(e,r)=>r==="done"?`${e} ${t.dim("\xB7")}`:t.bold(e),answer:e=>t.cyan(e),defaultAnswer:e=>t.dim(`(${e})`),highlight:e=>t.cyan(e),help:e=>t.dim(e),error:e=>t.red(`> ${e}`),description:e=>t.dim(e),keysHelpTip:()=>{}}};async function l({context:e=[]},r){d(),e.length>0&&process.stderr.write(`${e.map(n=>t.dim(n)).join(`
2
+ `)}
3
+ `);try{return await r({output:process.stderr})}catch(n){throw n instanceof Error&&n.name==="ExitPromptError"?new m:n}}var T=(e,r)=>l({context:r},n=>f({message:e,default:!1,theme:a},n)),C=(e,r)=>l({context:r},n=>f({message:e,default:!0,theme:a},n));async function w(e,r,{context:n,cancelled:s}={}){if(!await e(r,n))throw new m(s)}function P(e,r,n={}){let s=Math.max(...r.map(i=>i.label.length));return l(n,i=>y({message:e,choices:r.map(o=>({name:o.hint?`${o.label.padEnd(s)} ${t.dim(o.hint)}`:o.label,short:o.label,value:o.value})),theme:a},i))}function E(e,r={}){let{validate:n}=r;return l(r,s=>u({message:e,...r.initial?{default:r.initial}:{},...n?{validate:i=>n(i)??!0}:{},theme:a},s))}function $(e,r={}){let n="";return l(r,s=>h({message:e,mask:!1,toggleMask:!1,validate:i=>(n=i,i.trim()||r.optional?!0:"Enter a value."),theme:{...a,style:{...a.style,maskedText:"(hidden)",answer:()=>n.trim()?t.dim("\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022"):t.dim("skipped")}}},s))}function I(e){d(),process.stderr.write(`${e}
4
+ `)}async function R({yes:e,interactive:r,confirm:n=T,question:s,unattended:i,context:o,cancelled:p,data:c}){if(!e){if(!r)throw new g("CONFIRMATION_REQUIRED",i,c?{data:c}:{});await w(n,s,{context:o,cancelled:p})}}export{A as a,T as b,C as c,w as d,P as e,E as f,$ as g,I as h,R as i};
@@ -0,0 +1,33 @@
1
+ import{a as ir,b as or,c as ar,d as dr,f as be}from"./chunk-RQFHVU3Y.js";import{b as cr,c as lr}from"./chunk-5ZTFC6DK.js";import{a as rr,d as nr,e as he}from"./chunk-YJBYZWSP.js";import{a as sr,b as pr}from"./chunk-BHMRY53V.js";import{b as Dt}from"./chunk-IG26HYRR.js";import{a as Ct}from"./chunk-IA534DGW.js";import{a as Et,b as At,d as me,e as It,m as St,p as Nt}from"./chunk-MDORVBPD.js";import{a as zt,b as Bt,c as Kt,d as Ft,e as Ht}from"./chunk-MC56CUQI.js";import{b as Zt,c as Qt,d as Xt,f as er,g as we,h as ye,j as tr}from"./chunk-NJFWEYX7.js";import{d as Mt,e as xt,f as Ut,g as Wt,m as jt}from"./chunk-KMAOZRV4.js";import{n as Gt}from"./chunk-PMPIMHKG.js";import{a as Vt,b as qt,c as Yt,d as Jt,g as ge}from"./chunk-3Z53CH4F.js";import{P as ct}from"./chunk-6O3GJS5H.js";import{c as Ot,e as fe,f as $t}from"./chunk-GRFPP4UW.js";import{a as _,b as F,e as de,f as T,g as kt,h as W}from"./chunk-PL6EORDJ.js";import{c as $,d as _t,g as H,h as Tt}from"./chunk-DQWOXSL3.js";import{b as Lt}from"./chunk-3AAHHUJC.js";import{g as pt}from"./chunk-EUNGJMJ6.js";import{$ as gt,ga as wt,ia as yt,ja as ht,m as lt,n as dt,o as mt,p as ft,qa as bt,sa as Rt,u as ut}from"./chunk-ZYL2ZHCF.js";import{f as le}from"./chunk-7LG3F4FF.js";import{a as Y,e as Pt,f as ue}from"./chunk-GD2JZMD3.js";import{a as ot,b as at,h as st}from"./chunk-F6IH47GT.js";import{H as Ke,Kb as et,Ob as ce,Qb as tt,Tb as rt,Xb as nt,Zb as it,b as se,bb as Fe,c as N,d as O,fb as He,gb as Ve,k as pe,kb as qe,lb as Ye,oc as vt,tb as d,ub as Je,vb as Ze,wb as Qe,xb as Xe,zb as K}from"./chunk-SAT3PGZU.js";import Or from"node:path";import Wr from"chalk";async function mr({whoami:e,discovery:i,out:n,offer:t}){let{deps:a}=t,o=t.accountId?["--account-id",t.accountId]:[];if(!a.interactive){let f=await Gr(e,t).catch(()=>null),u=[N,"setup","--domain",f??"<hostname>",...o].join(" ");throw new Je("install_gateway",`Install a Gateway first: ${jr(i)}
2
+ Apps deploy behind one. Setup needs a person once, to create the owner account.`,void 0,{rerun:u,data:{accounts:i.probed,...f?{domain:f}:{}}})}let r=await le({whoami:e,flag:t.accountId,interactive:!0}),s=r.name??r.id,l=await he(a.createCf(r.id),r.id),g=`apps.${l.length===1?l[0]:await a.prompts.pickZone(l)}`;if(t.yes)st(Wr.dim(`${s} has no Gateway yet, so --yes installs one at ${g} first.`));else if(!await(t.confirm??at)(`Install a Gateway at ${g}?`,[`${s} has no Gateway yet. Apps deploy behind one, so it's installed first.`]))throw new Ze(`Cancelled. Nothing deployed.
3
+ Apps deploy behind a Gateway. To install one elsewhere: ${[N,"setup","--domain","<hostname>",...o].join(" ")}`);return await nr({whoami:e,discovery:i,flags:{domain:g,"account-id":r.id,"force-dns":t.forceDns,yes:t.yes,verbose:t.verbose},out:n,deps:a}),ut({whoami:e,createCf:a.createCf,accountId:r.id,interactive:!0})}async function Gr(e,i){let n=await le({whoami:e,flag:i.accountId,interactive:!1});return`apps.${(await he(i.deps.createCf(n.id),n.id))[0]}`}function jr(e){let i=e.probed.map(n=>n.name??n.id);return i.length===1?`${i[0]} has none yet`:`none of ${i.join(", ")} has one yet`}import zr from"node:fs/promises";var fr=64,Br=["d1","kv","hyperdrive","r2"];function Kr(e){return Br.includes(e)}function Fr(e,i){let n=structuredClone(e),t=n.name===$.workerName,a=n.env??{};for(let[l,m]of Object.entries(a))Hr(l,m,i);i.shared&&a.EVERY_APP_ORG_ID&&(delete a.EVERY_APP_ORG_ID,a.EVERYAPP_SHARED={type:"text",value:"1"});let o=JSON.stringify([$.publicKey]),r=Re(n,l=>l===o?JSON.stringify(i.identityPublicKeys):l.replaceAll($.gatewayUrl,()=>i.gatewayUrl).replaceAll($.organizationId,()=>i.organizationId).replaceAll($.workerName,()=>i.workerName));if(t&&i.deletedDurableObjects?.length){let l=r.exports??={};for(let m of i.deletedDurableObjects){if(l[m])throw new d("APP_POLICY",`Durable Object class ${m} is both exported by the build and being deleted; declare it in everyapp.config.ts, or stop exporting it.`);l[m]={type:"durable-object",state:"deleted"}}}let s=gr(r);if(s.length>0)throw new d("INSTALL_PLACEHOLDER_LEFT",`The build of ${String(r.name)} still holds a build placeholder after installing it, at ${s.join(", ")}. Build the Worker from everyAppWorker() in cloudflare.config.ts, and leave its names, keys and ids to the deploy.`);return Vr(r),r}async function ur({cwd:e,target:i}){for await(let{file:n,config:t}of Gt(e))await zr.writeFile(n,`${JSON.stringify(Fr(t,i),null,2)}
4
+ `)}function Hr(e,i,n){let t=String(i.type);if(!Kr(t))return;let a=_t(e);if(i[t==="d1"||t==="r2"?"name":"id"]!==a)return;let r=n.resources[t]?.[e];if(!r)throw new d("INSTALL_INPUTS_MISSING",`The build binds ${_[t]} ${e}, which the deploy didn't provision`,{fix:"declare it in everyapp.config.ts's resources"});Object.assign(i,r)}function Re(e,i){return typeof e=="string"?i(e):Array.isArray(e)?e.map(n=>Re(n,i)):e&&typeof e=="object"?Object.fromEntries(Object.entries(e).map(([n,t])=>[n,Re(t,i)])):e}function gr(e,i=""){let n=[$.workerName,$.organizationId,$.gatewayUrl,$.publicKey].flatMap(a=>[a,JSON.stringify(a).slice(1,-1)]),t=a=>n.some(o=>a.includes(o));return typeof e=="string"?t(e)?[i||"(root)"]:[]:e&&typeof e=="object"?Object.entries(e).flatMap(([a,o])=>{let r=i?`${i}.${a}`:a;return t(a)?[r]:gr(o,r)}):[]}function Vr(e){let i=[...Object.entries(e.env??{}),...Object.entries(e.exports??{})].filter(([,n])=>n.type==="workflow");for(let[n,t]of i){let a=String(t.name);if(a.length>fr)throw new d("WORKFLOW_NAME_TOO_LONG",`${n} would be the Workflow "${a}", longer than Cloudflare's ${fr} characters`,{fix:"shorten its binding name in everyapp.config.ts"})}}import qr from"node:fs/promises";import wr from"node:path";import{parseEnv as Yr}from"node:util";var I=".everyapp/secrets.env",A="POSTGRES_DATABASE_URL";async function yr(e){let i;try{i=await qr.readFile(wr.join(e,I),"utf8")}catch(t){if(tt(t))return{};throw t}ir(e,`${wr.dirname(I)}/`);let n={};for(let[t,a]of Object.entries(Yr(i)))a?.trim()&&(n[t]=a.trim());return n}function ve(e){return`${e}_ORIGIN_URL`}function hr(e,i,n){let t=ve(n);return e[t]?{url:e[t],variable:t}:(i.resources?.hyperdrive??[]).length===1&&e[A]?{url:e[A],variable:A}:null}var Jr={postgres:5432,postgresql:5432,mysql:3306};function J(e,i){let n=l=>new d("DATABASE_URL_INVALID",`${i} in ${I} ${l}`,{fix:"write it as postgres://<user>:<password>@<host>:<port>/<database>"}),t;try{t=new URL(e)}catch{throw n("isn't a URL")}let a=t.protocol.replace(/:$/,"");if(a!=="postgres"&&a!=="postgresql"&&a!=="mysql")throw n("isn't a postgres:// or mysql:// URL");let o=decodeURIComponent(t.pathname.replace(/^\//,"")),r=decodeURIComponent(t.username),s=decodeURIComponent(t.password);if(!t.hostname||!o||!r||!s)throw n("needs a host, a database, a user and a password");return{scheme:a,host:t.hostname,port:t.port?Number(t.port):Jr[a],database:o,user:r,password:s}}function br(e,i){let n=e;for(let t of i)t&&(n=n.split(t).join("***"));return n}async function Rr({cf:e,names:i,appId:n,out:t}){let a=[];for(let o of[...new Set(i)].sort()){try{if(await cr(e,o))continue;await lr(e,o)}catch(r){if(K(r,"already_exists"))continue;throw K(r,"r2_not_enabled")?new d("R2_NOT_ENABLED",`R2 isn't enabled in this Cloudflare account, and ${n} needs an R2 bucket (${o})
5
+ Enable it once in the dashboard: R2 Object Storage \u2192 Get started (free until something is stored).`,{fix:"enable R2 in the Cloudflare dashboard (R2 Object Storage)",rerun:O()}):r}a.push(o),t.emit({type:"progress",step:"app.build",message:`Created R2 bucket "${o}".`,data:{bucket:o}})}return a}async function Ee({cf:e,gatewayDb:i,registration:n},t){let a=t?.name??"",o=t?.workerName??n.workerName;if(!(await F(i,n.workerName)).some(s=>s.kind==="worker"&&s.binding===a)){if(await Ot(e,o)!==null)throw new d("WORKER_NAME_TAKEN",`A Worker named ${o} already exists in this Cloudflare account
6
+ No deploy of this app created it; it may belong to another Gateway or project.`,{fix:"delete or rename it",rerun:O()});await T(i,n.workerName,{kind:"worker",binding:a,name:o,resourceId:o})}}async function vr(e){let{cf:i,registration:n,manifest:t}=e,a=await F(e.gatewayDb,n.workerName),o=(p,w)=>Xr({...e,owned:a,kind:p,binding:w,name:ke(n,p,w),find:p==="d1"?v=>lt(i,v):v=>mt(i,v),create:p==="d1"?v=>dt(i,v):v=>ft(i,v)}),r={};for(let p of t.resources?.d1??[])r[p]={name:ke(n,"d1",p),id:await o("d1",p)};let s={};for(let p of t.resources?.kv??[])s[p]={id:await o("kv",p)};let l=t.resources?.r2??[],m=l.length?{r2:Object.fromEntries(l.map(p=>[p,{name:ke(n,"r2",p)}]))}:{},g=t.resources?.hyperdrive??[];if(g.length===0)return{d1:r,kv:s,...m};let f=new Map(g.map(({name:p})=>{let w=hr(e.secrets??{},t,p);return[p,w?J(w.url,w.variable):null]})),u={};for(let{name:p,caching:w="off"}of g)u[p]={id:await Qr({...e,owned:a,binding:p,name:Zr(n.workerName,p),origin:f.get(p)??null,caching:w})};return{d1:r,kv:s,...m,hyperdrive:u}}function Zr(e,i){return`${e}${Ye}${i.toLowerCase().replaceAll("_","-")}`}async function Qr(e){let{cf:i,gatewayDb:n,registration:t,owned:a,binding:o,name:r,origin:s,caching:l}=e,{onRecreated:m,onChanged:g}=e,{workerName:f}=t,u={kind:"hyperdrive",binding:o,name:r},p=W(u),w=ve(o),v=a.find(k=>k.kind==="hyperdrive"&&k.binding===o&&k.name===r),R=await Zt(i,r),h=async k=>{let S=s!==null&&!we(k,s),D=!er(k,l);!S&&!D||(await Xt(i,k.id,{...S?{origin:s}:{},...D||l==="off"?{caching:l}:{}}),S&&g?.(`Pointed ${p} at the database in ${I}.`),D&&g?.(l==="off"?`Turned off query caching on ${p} (Hyperdrive never invalidates a cached read when the app writes; caching: "default" in everyapp.config.ts turns it on).`:`Turned on Hyperdrive's query caching on ${p} (caching: "default").`))};if(v?.resourceId){if(R?.id===v.resourceId)return await h(R),R.id;if(R)throw Er(u,v.resourceId);m?.(p,u.kind)}else if(v){if(R)return await T(n,f,{...u,resourceId:R.id}),await h(R),R.id}else if(R){if(s&&we(R,s))return await T(n,f,{...u,resourceId:R.id}),g?.(`Adopted ${p}, which connects to the database in ${I}.`),await h(R),R.id;throw new d("RESOURCE_NAME_TAKEN",`A Hyperdrive config named "${r}" already exists in this Cloudflare account
7
+ No deploy of this app created it.`,{fix:`to use it, set ${w} in ${I} to the URL of the database it connects to; otherwise delete or rename it`,rerun:O()})}if(!s)throw new d("HYPERDRIVE_ORIGIN_MISSING",`${o} needs the database its Hyperdrive config connects to
8
+ Creating the config needs its URL.`,{fix:`set ${w} (or POSTGRES_DATABASE_URL, when it is the app's only config) in ${I} to postgres://<user>:<password>@<host>:<port>/<database>`,rerun:O()});return kr(e,u,()=>Qt(i,r,s,l))}function ke(e,i,n){let t=e.resources[i][n];if(!t||qe(t))throw new d("RESOURCE_NAME_MISSING",`The Gateway assigned no usable ${_[i]} name for binding ${n}`,{rerun:`${N} setup`,rerunNote:"to upgrade the Gateway"});return t}async function Xr(e){let{gatewayDb:i,registration:n,owned:t,kind:a,binding:o,name:r,find:s,create:l,onRecreated:m}=e,{workerName:g}=n,f={kind:a,binding:o,name:r},u=t.find(w=>w.kind===a&&w.binding===o&&w.name===r),p=await s(r);if(u?.resourceId){if(p===u.resourceId)return p;if(p)throw Er(f,u.resourceId);m?.(W(f),a)}else if(u){if(p)return await T(i,g,{...f,resourceId:p}),p}else if(p)throw new d("RESOURCE_NAME_TAKEN",`A ${_[a]} named "${r}" already exists in this Cloudflare account
9
+ No deploy of this app created it; it may belong to another Gateway, app or project.`,{fix:"delete or rename it",rerun:O()});return kr(e,f,()=>l(r))}async function kr({gatewayDb:e,registration:i,onCreated:n},t,a){let{workerName:o}=i;await T(e,o,{...t,resourceId:null});let r;try{r=await a()}catch(s){throw K(s,"already_exists")?(await kt(e,o,{kind:t.kind,binding:t.binding}),new d("RESOURCE_NAME_TAKEN",`${W(t)} was created by someone else while this deploy was creating it`,{fix:"delete or rename it",rerun:O()})):s}return await T(e,o,{...t,resourceId:r}),n?.(W(t),t.kind),r}function Er(e,i){return new d("RESOURCE_REPLACED",`${W(e)} isn't the one this app created
10
+ That one (${i}) was deleted, and this one was created by someone else since.`,{fix:"delete or rename it",rerun:O()})}function Ae(e,i){return(i.resources?.workflows??[]).map(n=>({binding:n.name,className:n.className,name:Tt(e,n.name),worker:n.worker?H(e,n.worker):e}))}async function Ar({cf:e,workerName:i,names:n}){for(let t of n){let a=await ye(e,t);if(a&&a.script_name!==i)throw new d("WORKFLOW_NAME_TAKEN",`A Workflow named "${t}" already exists in this Cloudflare account
11
+ It runs on Worker ${a.script_name??"(unknown)"}, not ${i}; deploying would take it over.`,{fix:"delete or rename it",rerun:O()})}}async function Ir({cf:e,workerName:i,previousManifest:n,names:t}){let a=Fe.safeParse(n);if(!a.success)return[];let o=[];for(let r of Ae(i,a.data))t.includes(r.name)||(await ye(e,r.name))?.script_name===r.worker&&o.push(r);return o}import{execa as en}from"execa";var tn=10*6e4;function Z({packageName:e,binName:i,env:n={},missing:t}){return async({args:a,cwd:o,env:r})=>{let s;try{s=(await et(o,e,i)).binPath}catch{throw t()}let l=await en(process.execPath,[s,...a],{cwd:o,env:{NODE_NO_WARNINGS:"1",...n,...r},stdin:"ignore",reject:!1,timeout:tn});return{exitCode:l.timedOut?124:l.exitCode??1,stdout:String(l.stdout??""),stderr:String(l.stderr??"")}}}async function Q({run:e,args:i,cwd:n,databaseUrl:t,reasonPatterns:a,failed:o}){let{password:r}=J(t,A),s=await e({args:i,cwd:n,env:{[A]:t}});if(s.exitCode===0)return s.stdout;let m=br(`${s.stderr}
12
+ ${s.stdout}`,[t,r,encodeURIComponent(r)]).split(`
13
+ `).map(f=>f.trim()).filter(Boolean),g=a.map(f=>m.find(u=>f.test(u))).find(f=>f!==void 0);throw o(g??m.at(-1)??`exit ${s.exitCode}`)}function rn(){return Z({packageName:"drizzle-kit",binName:"drizzle-kit",missing:()=>new d("DRIZZLE_KIT_MISSING",`Postgres migrations need drizzle-kit, which isn't installed
14
+ Nothing was migrated or uploaded.`,{fix:"add drizzle-kit to devDependencies, then deploy again"})})}async function Sr({cwd:e,databaseUrl:i,config:n,run:t=rn()}){await Q({run:t,args:["migrate",...n?["--config",n]:[]],cwd:e,databaseUrl:i,reasonPatterns:[/error/i],failed:a=>new d("MIGRATION_FAILED",`drizzle-kit couldn't migrate the Postgres database
15
+ ${a}. Nothing was uploaded.`,{fix:`check ${A} in ${I} and the migrations`})})}function nn(){return Z({packageName:"prisma",binName:"prisma",env:{PRISMA_HIDE_UPDATE_MESSAGE:"1"},missing:()=>new d("PRISMA_MISSING",`Prisma migrations need prisma, which isn't installed
16
+ Nothing was migrated or uploaded.`,{fix:"add prisma to devDependencies, then deploy again"})})}async function Nr({cwd:e,databaseUrl:i,config:n,run:t=nn()}){return[...(await Q({run:t,args:["migrate","deploy",...n?["--config",n]:[]],cwd:e,databaseUrl:i,reasonPatterns:[/\bP\d{4}\b/,/error/i],failed:o=>new d("MIGRATION_FAILED",`prisma migrate deploy couldn't migrate the Postgres database
17
+ ${o}. Nothing was uploaded.`,{fix:`check ${A} in ${I}, prisma.config.ts (its datasource reads it) and the migrations`})})).matchAll(/^Applying migration `([^`]+)`/gm)].map(o=>o[1])}var on=new Set(["pending","binding"]);async function $r(e){let i={rollback:null};try{return await an(e,i)}catch(n){throw Qe(n,i.rollback)}}async function an(e,i){let{cwd:n,out:t}=e,a=e.interactive??ot(e.json??!1),o=e.release,r=o?.manifest??e.manifest??await Y(n),s=o?.dir??n;o&&cn(r);let l=r.migrations?.dialect==="postgresql",m=l||r.resources?.hyperdrive?.length?await yr(n):{};if(l&&!m[A])throw new d("POSTGRES_URL_MISSING",`${r.id} needs a Postgres URL to migrate its database
18
+ Format: postgres://<user>:<password>@<host>:<port>/<database>`,{fix:`set ${A} in ${I}, then deploy again`});let g=o?null:await pr(n);if(!o&&!g)throw new d("MISSING_CLOUDFLARE_CONFIG",sr);g&&!g.usesEveryAppWorker&&t.emit({type:"warning",code:"NONSTANDARD_CLOUDFLARE_CONFIG",message:`cloudflare.config.ts doesn't use everyAppWorker()
19
+ The deploy checks the Worker it builds against the app policy.`});let f=e.offerInstall,u=zt(e.reconcile,t,e.verbose);t.emit({type:"step",step:"app.connect",status:"start",message:"Finding your Gateway..."});let{cf:p,accountId:w,accountName:v,databaseId:R,db:h,install:k,gatewayUrl:S,deployer:D}=await Rt({gateway:e.gateway,accountId:e.accountId,interactive:a,login:{json:e.json,out:t,step:"app.login"},createCf:e.createCf,onNoGateway:f?({whoami:x,discovery:re})=>mr({whoami:x,discovery:re,out:t,offer:{accountId:e.accountId,yes:f.yes,confirm:f.confirm,forceDns:e.forceDns,verbose:e.verbose,deps:{...rr({gateway:u,interactive:a}),...e.createCf?{createCf:e.createCf}:{},...f.setup}}}):void 0});t.emit({type:"step",step:"app.connect",status:"ok",data:{gatewayUrl:S}});let Ie=await Ct(h,k);pn(r,Ie,S);let[Dr,Se]=await Promise.all([gt(h),yt(h,r.id)]),Ne=!Se||on.has(Se.status);t.emit({type:"step",step:"app.deploy",status:"ok",message:`Deploying ${r.id}${o?` ${o.release.version} from ${be(o.origin)}`:""} to ${S}.`,data:{appId:r.id,organizationName:Dr?.organization.name??v,firstDeploy:Ne,gatewayUrl:S,gatewayHost:new URL(S).host,...o?{version:o.release.version,origin:be(o.origin),release:{version:o.release.version,gitSha:o.release.gitSha,origin:o.origin,sha256:o.release.sha256}}:{}}}),await jt(k,u.source);let Oe=k.jwtPublicKey;if(!Oe)throw new d("IDENTITY_KEY_UNKNOWN",`The Gateway is missing its sign-in public key
20
+ App Workers need it to check who is signed in.`,{fix:"restore JWT_PUBLIC_KEY as in https://github.com/every-app/every-app/blob/main/docs/runbooks/key-rotation.md"});let{plan:E,organization:L,hasOwner:Pr,deployerGranted:_r}=await Bt(h,{manifest:r,install:k,deployer:D,accountName:v}),C=E.app.hostname,y=E.app.workerName,$e=E.kind!=="existing",Ce=Ve(r,E.app.tier);if(Ce.length>0)throw new d("TIER_POLICY",`${r.id} can't be deployed as configured
21
+ ${Ce.join(`
22
+ `)}`,{fix:"change everyapp.config.ts, then deploy again"});let X=nt(r),ee=it(r);t.emit({type:"step",step:"app.register",status:"ok",message:`${$e?"Registered":"Updating"} ${r.id} as ${y} at https://${C} (${E.app.status}).`,data:{appId:r.id,workerName:y,hostname:C,status:E.app.status,existingApp:!$e,firstDeploy:Ne,defaultAccess:E.app.isDefault,deployerAccess:_r,hasOwner:Pr,publicRoutes:X,mcp:ee,scope:E.app.scope,organizationId:L.id,organizationName:L.name,gatewayUrl:S}});let{outsideBase:G,newHost:De}=await Mt({cf:p,out:t,install:k,hostname:C,forceDns:e.forceDns,cfAsks:a&&t.verbose}),j=await pt({db:h,out:t},{workerName:y,appId:r.id,purpose:"app.deploy"}),z,te,V=[];try{let x=ln(E,r,e.allowDeleteDurableObjectData??!1),re=await dn({cf:p,plan:E,workerName:y,manifest:r,allowDelete:e.allowDeleteWorkflows??!1}),Te=!1,ne={cf:p,gatewayDb:h,registration:{workerName:y,resources:E.resources},onCreated:(c,b)=>{t.emit({type:"progress",step:"app.resources",message:`Created ${c}.`}),b==="hyperdrive"&&(Te=!0)},onRecreated:(c,b)=>t.emit({type:"warning",code:"RESOURCE_RECREATED",step:"app.resources",message:`The ${b==="d1"?"database":_[b]} ${r.id} used before is gone; creating a new, empty one
23
+ ${c} no longer exists in this Cloudflare account.`}),onChanged:c=>t.emit({type:"progress",step:"app.resources",message:c})},P=(r.workers??[]).map(c=>({name:c.name,workerName:H(y,c.name)}));t.emit({type:"step",step:"app.resources",status:"start",message:"Preparing the app's resources..."}),await Ee(ne);for(let c of P)await Ee(ne,c);let U=await ht(h,E.app.id),ie=ge(r).receives;!ie&&U.inbound.length>0&&t.emit({type:"warning",code:"EMAIL_INBOUND_UNDECLARED",step:"app.email",message:`everyapp.config.ts no longer declares inbound email; removing the app's mail routes
24
+ Its addresses (${U.inbound.join(", ")}) stay on the Gateway until you clear them.`,data:{rerun:`${N} email unset inbound`}});let B=await Vt({cf:p,gatewayDb:h,accountId:w,workerName:y,addresses:ie?U.inbound:[],interactive:a,enableRouting:e.enableEmailRouting,confirm:e.confirm}),Le=await vr({...ne,manifest:r,secrets:m});if(t.emit({type:"step",step:"app.resources",status:"ok",message:"The app's resources are ready."}),Te){let c=r.resources?.hyperdrive?.some(b=>b.caching==="default")?"default":"off";t.emit({type:"step",step:"app.hyperdrive",status:"ok",message:"Created the app's Hyperdrive config.",data:{caching:c}})}!o&&r.install!==!1&&(t.emit({type:"step",step:"app.install",status:"start",message:"Installing dependencies..."}),await(e.installDeps??rt)({cwd:n,description:"Installing dependencies...",install:r.install,verbose:e.verbose??!1}),t.emit({type:"step",step:"app.install",status:"ok"}));let Me={workerName:y,organizationId:L.id,gatewayUrl:S,identityPublicKeys:[Oe],resources:Le,deletedDurableObjects:x,helperWorkers:P.map(c=>c.workerName)};o||(t.emit({type:"step",step:"app.build",status:"start",message:"Building..."}),await ar({cwd:n,cf:p,buildCommand:r.build,verbose:e.verbose??!1})),await ur({cwd:s,target:Me});let{workflows:xe,helperWorkflows:Ue,r2Buckets:Tr}=await dr({cwd:s,inputs:Me});await Rr({cf:p,names:Tr,appId:r.id,out:t});for(let c of[{workerName:y,names:xe},...P.map(b=>({workerName:b.workerName,names:Ue[b.workerName]??[]}))])await Ar({cf:p,...c});t.emit({type:"step",step:"app.build",status:"ok",message:`${o?"Installed the release":"Built the app"} and checked its Worker${P.length?"s":""}.`,data:{release:o!==void 0,workflows:[...xe,...Object.values(Ue).flat()]}}),o?t.emit({type:"progress",step:"app.schema",message:`The release's publisher checked its migrations against its schema when it packed ${r.id} ${o.release.version}.`}):await or({cwd:n,manifest:r,out:t});let Lr=(await F(h,y)).filter(c=>c.kind==="worker"),We=c=>Lr.find(b=>b.binding===c)?.versionId,Mr={question:"Replace the version that's serving?",effect:"Migrations run first."};for(let c of[{workerName:y,shownAs:r.id,recordedVersionIds:[E.versionId,We("")]},...P.map(b=>({workerName:b.workerName,shownAs:`${r.id}'s ${b.name} Worker`,recordedVersionIds:[We(b.name)]}))])await $t({cf:p,...c,interactive:a,confirm:e.confirm,change:Mr});await j.check(),i.rollback=await mn({cf:p,out:t,cwd:s,manifest:r,resources:Le,accountId:w,registry:h,workerName:y,restoreCommand:`${N} db restore${o?` ${r.id}`:""}`,appSecrets:m,drizzleKit:e.drizzleKit,prisma:e.prisma});let Ge={GATEWAY_URL:S,EVERY_APP_ORG_ID:L.id};for(let c of P)await j.check(),t.emit({type:"step",step:"app.helper",status:"start",message:`Uploading ${c.workerName}...`,data:{name:c.name,workerName:c.workerName}}),await fe({cf:p,cwd:s,workerName:c.workerName,buildOutputWorker:c.workerName,accountId:w,message:`everyapp ${se} ${r.id} ${c.name}`,secrets:Ge,interactive:a,attach:t.verbose,out:t,step:"app.helper",onUploaded:b=>de(h,y,b,c.name)}),t.emit({type:"step",step:"app.helper",status:"ok",message:`Uploaded ${c.workerName}.`,data:{name:c.name,workerName:c.workerName}});await j.check(),t.emit({type:"step",step:"app.upload",status:"start",message:`Uploading ${y}...`});let je=await fe({cf:p,cwd:s,workerName:y,accountId:w,message:`everyapp ${se} ${r.id}`,secrets:Ge,interactive:a,attach:t.verbose,out:t,step:"app.upload",onUploaded:c=>de(h,y,c)});if(!je.versionId)throw new d("VERSION_UNKNOWN",`Cloudflare reports no version for ${r.id} after the upload`,{data:{workerName:y}});z=je.versionId,t.emit({type:"step",step:"app.upload",status:"ok",message:`Uploaded version ${z}.`,data:{versionId:z}});for(let c of re)await tr(p,c.name),t.emit({type:"step",step:"app.workflows",status:"ok",message:`Deleted the Workflow ${c.binding} (${c.name}) with its instances.`,data:{binding:c.binding,name:c.name}});let ze=ge(r).sends&&k.deploymentMode!=="hosted";if(B){await j.check(),t.emit({type:"step",step:"app.email",status:"start",message:`Routing ${r.id}'s mail...`,data:{removing:B.routes.length===0}});let{routed:c,removed:b}=await qt({cf:p,gatewayDb:h,plan:B,onProgress:ae=>t.emit({type:"progress",step:"app.email",message:ae})}),q={appId:r.id,workerName:y,senders:U.senders,routed:c,removed:b,sendersSettable:ze},Be=q.sendersSettable?Jt(q.routed,q.senders):[];t.emit({type:"step",step:"app.email",status:"ok",message:Yt(q),data:{addresses:c,removed:b,enabled:B.enable.map(({domain:ae})=>ae),...Be.length>0?{replyHint:`To reply from ${Be.join(", ")}, set up Email Sending, then: ${N} email set --sender`}:{}}})}!B&&ie&&U.inbound.length===0&&(t.emit({type:"step",step:"app.email",status:"skip",message:`${r.id} receives no mail yet.`}),V.push({command:`${N} email set --inbound <address>`,note:`routes mail to ${r.id}`})),ze&&U.senders.length===0&&V.push({command:`${N} email set --sender '*@<domain>'`,note:`lets ${r.id} send as your domain`});let xr=(E.previousManifest?.workers??[]).map(c=>String(c.name)).filter(c=>!P.some(b=>b.name===c));for(let c of xr)t.emit({type:"warning",code:"HELPER_WORKER_KEPT",step:"app.upload",message:`Helper Worker ${c} is no longer in everyapp.config.ts, but it still runs
25
+ Its Worker is ${H(y,c)}.`,data:{fix:"delete that Worker in the Cloudflare dashboard"}});let oe=await At(p,y).catch(c=>(t.emit({type:"progress",step:"app.secrets",message:`Couldn't list ${y}'s secrets: ${Xe(c).split(`
26
+ `)[0]}`}),null));te=await wt(h,E.app.id,{versionId:z,manifest:r,actor:D.actor,email:D.email,source:o?"release":"cli",...oe?{secretNames:oe}:{}});let Ur=await sn({cf:p,manifest:r,appId:r.id,secretNames:oe,out:t,next:V,providers:Ie});await Dt(h,{appRowId:E.app.id,setup:Ur,deployer:D},t)}finally{await j.release()}await Kt({cf:p,db:h,databaseId:R,out:t,accountId:w,appId:r.id,workerName:y,publishHost:De,interactive:a,forceDns:e.forceDns,seams:{...e.reconcile,openRelease:u.openRelease,source:u.source},verb:"deploy"});let M=`https://${C}`,Pe=!G&&(e.waitForLive??!0),_e=await Ft({wait:Pe,db:h,appRowId:E.app.id,appId:r.id,hostname:C,out:t,seams:e.live,message:`${r.id} is live at ${M}.`,verb:"deploy"});if(!_e){let x=G?"outside-base":Pe?void 0:De?"certificate":"first-visit";t.emit(te==="active"&&!G?{type:"step",step:"app.live",status:"ok",message:`${r.id} is live at ${M}.`,data:{hostname:C,url:M}}:{type:"step",step:"app.live",status:"skip",message:`${r.id} isn't live yet: ${M}.`,data:{hostname:C,url:M,...x?{reason:x}:{}}})}return await ct({cf:p,db:h,install:k,out:t},{appId:r.id,surface:{publicRoutes:X.length>0,mcp:ee!==null}}),G&&t.emit({type:"warning",code:"APP_HOST_OUTSIDE_BASE",step:"app.domain",message:`${C} isn't one label below ${k.appBaseDomain}
27
+ The Gateway only serves names directly under ${k.appBaseDomain}, so ${r.id} can't be reached.`}),{liveUrl:M,gatewayUrl:S,organizationId:L.id,organizationName:L.name,hostname:C,workerName:y,versionId:z,live:_e||te==="active"&&!G,publicRoutes:X,mcp:ee,next:V}}async function sn({cf:e,manifest:i,appId:n,secretNames:t,out:a,next:o,providers:r}){if(!It(i,r))return me({manifest:i,appId:n,gatewayNames:[],secretNames:[],lookup:r}).setup;let s=await Et(e).catch(()=>null),{setup:l}=me({manifest:i,appId:n,gatewayNames:s,secretNames:t,lookup:r});if(l.ready||!l.command)return l;let m=Nt(l),g=l.unmet.find(f=>f.why);return a.emit({type:"warning",code:"APP_NEEDS_SETUP",step:"app.secrets",message:[`${n} won't open until ${pe(m)} ${m.length===1?"is":"are"} set`,...g?[St(g)[0]]:[]].join(`
28
+ `),data:{setup:l}}),o.push({command:l.command.command,note:`asks for each; ${n} opens once they are set`}),l}function pn(e,i,n){let t=Object.keys(e.capabilities??{}).filter(a=>!i.get(a));if(t.length>0){let a=Ke(i);throw new d("CAPABILITY_UNKNOWN",[`${e.id} lists ${pe(t)} under capabilities, which ${n.replace(/^https:\/\//,"")} doesn't offer`,`Neither the built-in catalog nor the providers registered on this Gateway ${t.length===1?"has it":"have them"}. It offers: ${a.join(", ")}.`].join(`
29
+ `),{fix:`register ${t.length===1?"it":"each"} with ${N} provider add <spec.json or https URL> (or fix the id in everyapp.config.ts), then deploy again`,data:{unknown:t,offered:a}})}He(e,{capabilities:i})}function cn(e){if(e.migrations?.dialect==="postgresql")throw new d("RELEASE_MIGRATIONS_UNSUPPORTED",`${e.id} can't deploy from a release: its Postgres migrations need the source`,{fix:`clone it, then run pnpm install in it and this checkout's ${N} deploy from its directory`})}function ln(e,i,n){let t=new Map((i.resources?.durableObjects??[]).map(o=>[o.className,o.worker]));for(let o of e.previousManifest?.resources?.durableObjects??[]){let r=String(o.className),s=o.worker?String(o.worker):void 0;if(t.has(r)&&t.get(r)!==s)throw new d("DURABLE_OBJECT_MOVED",`${r} can't move to another Worker
30
+ A Durable Object's data can't follow it.`,{fix:"give the class a new name in everyapp.config.ts"});if(!t.has(r)&&s)throw new d("HELPER_DURABLE_OBJECT_REMOVED",`The helper Worker ${s} still defines ${r}
31
+ Removing a helper Worker's Durable Object class isn't supported yet.`,{fix:`keep declaring ${r} in everyapp.config.ts`})}let a=(e.previousManifest?.resources?.durableObjects??[]).map(o=>String(o.className)).filter(o=>!t.has(o));if(a.length>0&&!n){let o=a.length===1;throw new d("DURABLE_OBJECT_REMOVED",`Deploying would delete ${o?`${a[0]}'s data`:`the data of ${a.join(", ")}`} for good
32
+ everyapp.config.ts no longer declares the Durable Object class${o?"":"es"} ${a.join(", ")}.`)}return a}async function dn({cf:e,plan:i,workerName:n,manifest:t,allowDelete:a}){let o=await Ir({cf:e,workerName:n,previousManifest:i.previousManifest,names:Ae(n,t).map(r=>r.name)});if(o.length>0&&!a){let r=o.length===1;throw new d("WORKFLOW_REMOVED",`Deploying would delete the Workflow${r?"":"s"} ${o.map(s=>s.binding).join(", ")} and ${r?"its":"their"} instances
33
+ everyapp.config.ts no longer declares ${r?"it":"them"}. Renaming a binding renames its Workflow.`)}return o}async function mn({cf:e,out:i,cwd:n,manifest:t,resources:a,accountId:o,registry:r,workerName:s,restoreCommand:l,appSecrets:m,drizzleKit:g,prisma:f}){if(t.migrations?.dialect==="postgresql")return await fn({out:i,cwd:n,manifest:t,appSecrets:m,drizzleKit:g,prisma:f}),null;let u=t.resources?.d1??[];if(u.length===0)return null;let p=Pt(u,t.migrations),w=a.d1?.[p]?.id,v=Or.resolve(n,ue(t));if(!w||!await ce(v))return Cr(i),null;i.emit({type:"step",step:"app.migrations",status:"start",message:"Migrating the database..."});let R=await xt({cf:e,databaseId:w,accountId:o,dir:v,registry:r,target:Lt(s),restoreCommand:l});return i.emit({type:"step",step:"app.migrations",status:"ok",message:R.applied.length>0?`Applied ${R.applied.join(", ")}.${Ut(R.rollback)}`:"The app's database is up to date.",data:Wt(R)}),R.rollback}async function fn({out:e,cwd:i,manifest:n,appSecrets:t,drizzleKit:a,prisma:o}){let r=n.migrations?.engine==="prisma"?"prisma":"drizzle",s=r==="drizzle"?ue(n):n.migrations?.dir;if(s!==void 0&&!await ce(Or.resolve(i,s))){Cr(e);return}e.emit({type:"step",step:"app.migrations",status:"start",message:"Migrating the Postgres database...",data:{dialect:"postgresql",engine:r}});let l={cwd:i,databaseUrl:t[A],config:n.migrations?.config},m;r==="prisma"?m=await Nr({...l,...o?{run:o}:{}}):await Sr({...l,...a?{run:a}:{}}),e.emit({type:"step",step:"app.migrations",status:"ok",message:`Migrated the app's Postgres database (${r==="prisma"?"prisma migrate deploy":"drizzle-kit migrate"}).`,data:{dialect:"postgresql",engine:r,...m?{applied:m}:{}}})}function Cr(e){e.emit({type:"step",step:"app.migrations",status:"skip",message:"No migrations to apply."})}async function uo(e){await vt(e,async i=>{let n=process.cwd(),t=await $r({cwd:n,manifest:await Y(n),gateway:bt(e.gateway),accountId:e["account-id"],out:i,json:e.json,verbose:e.verbose,allowDeleteDurableObjectData:e["allow-delete-durable-object-data"],allowDeleteWorkflows:e["allow-delete-workflows"],forceDns:e["force-dns"],enableEmailRouting:e["enable-email-routing"],waitForLive:!e["no-wait"],offerInstall:{yes:e.yes}});i.emit({type:"done",...un(t)})})}function un(e){return{data:{...Ht(e),organization:e.organizationName,publicRoutes:e.publicRoutes,mcp:e.mcp,...e.next.length>0?{next:e.next}:{}}}}export{$r as a,uo as b,un as c};
@@ -0,0 +1 @@
1
+ import{Qb as e,fb as o,tb as s}from"./chunk-SAT3PGZU.js";import p from"node:fs/promises";import a from"node:path";import{pathToFileURL as c}from"node:url";import{createJiti as m}from"jiti";async function y(r){return g(a.join(r,"everyapp.config.ts"),{message:"No everyapp.config.ts in this directory",fix:"run this from the app's directory"})}async function w(r){try{await p.access(a.join(r,"everyapp.config.ts"))}catch(i){if(e(i))return null;throw i}return y(r)}async function g(r,i={message:`No manifest at ${r}`}){try{await p.access(r)}catch(n){throw e(n)?new s("MANIFEST_NOT_FOUND",i.message,{fix:i.fix}):n}let f=await m(c(r).href).import(r,{default:!0});return o(f,l)}var l={unknownCapabilities:"accept"};function h(r,i){let t=i?.binding??r[0];if(!r.includes(t))throw new Error(`Manifest migrations binding "${t}" is not declared in resources.d1.`);return t}function N(r){return r.migrations?.dir??"drizzle"}export{y as a,w as b,g as c,l as d,h as e,N as f};
@@ -0,0 +1,7 @@
1
+ import{b as I,d as R}from"./chunk-F6IH47GT.js";import{k as C,l as b}from"./chunk-JYKRUS5C.js";import{Fb as w,Hb as v,Vb as h,Wb as k,d as f,tb as g,ub as d,xb as p,yb as y,zb as m}from"./chunk-SAT3PGZU.js";var P={perPage:100,maxPages:50};function O(e){return k(e,["workers","list"],b,P)}async function $(e,r){return((await O(e)).find(t=>t.name===r)?.references?.domains??[]).map(t=>t.hostname.toLowerCase())}async function l(e,r){let n;try{n=await h(e,{plane:"account",args:["workers","deployments","list","--worker",r,"--per-page","10"]},C)}catch(o){if(m(o,"not_found"))return null;throw o}let t=[...n].sort((o,i)=>(i.created_on??"").localeCompare(o.created_on??""))[0];return{versionId:[...t?.versions??[]].sort((o,i)=>i.percentage-o.percentage)[0]?.version_id??null,deployedAt:t?.created_on?Date.parse(t.created_on):null}}async function L(e,r,{withReferences:n=!1}={}){await e.run({plane:"account",mode:"json",args:["workers","delete",r,"--force",...n?["--delete-with-references"]:[]]})}var W=9e5;async function B(e){let r=e.secrets&&Object.keys(e.secrets).length>0?e.secrets:void 0,n=e.dryRun?null:await l(e.cf,e.workerName),t=!1,s=e.onUploaded&&!e.dryRun?v({async:()=>D(e,n,t)}):void 0;try{return await A(e,r,n,()=>{t=!0})}catch(o){throw s&&!w()&&await D(e,n,t).catch(i=>{e.out?.emit({type:"warning",code:"UPLOAD_UNRECORDED",step:e.step,message:`The version cf uploaded of ${e.workerName} couldn't be recorded
2
+ ${p(i)}`,data:{workerName:e.workerName,error:p(i)}})}),o}finally{w()||s?.()}}async function D(e,r,n){let t=await l(e.cf,e.workerName);t?.versionId&&t.versionId!==r?.versionId&&await e.onUploaded?.(t.versionId,n)}async function A(e,r,n,t){let s=e.interactive&&e.attach&&!e.dryRun,o=u=>e.cf.run({plane:"project",cwd:e.cwd,cliCf:e.cliCf,mode:u,timeoutMs:W,...r?{files:{"secrets.json":r}}:{},args:c=>["deploy","--prebuilt","--mode","production","--message",e.message,...e.buildOutputWorker?["--worker",e.buildOutputWorker]:[],...r?["--secrets-file",c["secrets.json"]]:[],...e.dryRun?["--dry-run"]:[]]}),i;try{i=(await o(s?"interactive":"text").catch(c=>{if(e.interactive&&m(c,"strict_conflict"))return o("interactive");throw c})).stdout}catch(u){throw N(u,e)}if(t(),e.dryRun)return{versionId:null,output:i};let a=await l(e.cf,e.workerName);if(!a?.versionId||a.versionId===n?.versionId)throw new g("DEPLOY_NOT_UPLOADED",`cf finished without uploading a new version of ${e.workerName}
3
+ Was one of its questions answered no? The version that was serving still is.`,{rerun:f(),rerunNote:"to deploy again"});return await e.onUploaded?.(a.versionId,!0),{versionId:a.versionId,output:i}}async function G({cf:e,workerName:r,shownAs:n,recordedVersionIds:t,interactive:s,confirm:o=I,change:i}){let a=await l(e,r);if(a&&!(a.versionId&&t.includes(a.versionId))){if(!s)throw new d("rerun_interactive",`${_(n)} was changed outside everyapp; confirm in a terminal
4
+ Its live version wasn't deployed by everyapp, and Cloudflare won't replace it unattended. Nothing changed.`,void 0,{rerun:f([],{terminal:!0}),rerunNote:"in a terminal",data:{workerName:r,versionId:a.versionId,needsTerminal:!0}});await R(o,i.question,{context:[`${_(n)}'s live version wasn't deployed by everyapp (dashboard, API, or an interrupted deploy).`,[i.effect,"Cloudflare may ask to confirm again."].filter(Boolean).join(" ")]})}}function E(e){return`https://dash.cloudflare.com/${e}/workers/plans`}var _=e=>e.replace(/^the /,"The ");function N(e,{workerName:r,accountId:n}){return e instanceof y?e.kind==="strict_conflict"?new d("rerun_interactive",`${r} was changed outside everyapp; confirm in a terminal
5
+ It was last changed in the Cloudflare dashboard or through the API, so cf won't overwrite it unattended.`,void 0,{rerun:f([],{terminal:!0}),rerunNote:"in a terminal, and confirm cf's prompt",data:{needsTerminal:!0}}):e.kind==="subdomain_missing"?new d("register_workers_subdomain",`Choose a workers.dev subdomain for this Cloudflare account
6
+ Cloudflare needs one before an account's first Worker. Apps never use it.`,e.message.match(/https:\/\/dash\.cloudflare\.com\/\S+/)?.[0]??`https://dash.cloudflare.com/${n}/workers/onboarding`):e.kind==="free_plan"?new d("upgrade_workers_paid",`Subscribe this account to Workers Paid
7
+ Cloudflare refused the upload on the Free plan. Every App needs Workers Paid ($5 a month, then usage).`,E(n),{data:{workerName:r,cloudflare:e.message}}):e:e}export{O as a,$ as b,l as c,L as d,B as e,G as f,E as g};
@@ -0,0 +1,10 @@
1
+ import{$ as C,B as U,Z as D,na as P,y as L}from"./chunk-ZYL2ZHCF.js";import{D as h,E as _,Ra as E,Sa as N,Ua as T,Va as O,Wa as $,Xa as A,c as w,d as R,k as m,ra as S,tb as i}from"./chunk-SAT3PGZU.js";var V=new WeakMap;function b(t){let e=V.get(t);return e||(e=t.run([{sql:"SELECT name FROM sqlite_master WHERE type = 'table' AND name = 'providers'"}]).then(([a=[]])=>a.length>0),V.set(t,e)),e}async function f(t){if(!await b(t))return[];let[e=[]]=await t.run([{sql:"SELECT id, spec, added_by, added_at, bound_to FROM providers ORDER BY added_at, id"}]);return e.map(a=>({id:String(a.id),spec:String(a.spec),addedBy:D(a.added_by),addedAt:a.added_at==null?null:Number(a.added_at),boundTo:D(a.bound_to)}))}function x(t){return e=>O(e,{gatewayHost:t.gatewayHost,appBaseDomain:t.appBaseDomain})}function I(t,e){return A(t,{refuseHost:x(e)})}async function Q(t,e){return I(await f(t),e)}function F(t,e){return t.rows().filter(a=>h(a.capability).some(r=>e.includes(r)))}function G(){return new i("GATEWAY_OUTDATED",`This Gateway predates the provider registry
2
+ Its database has no providers table until the Gateway is updated. Nothing was changed.`,{rerun:`${w} update`,rerunNote:"then run this again"})}function M(t){return t==="everyapp"||_.includes(t)}async function Z(t,e){let a=E(e.spec);if(!a.ok)throw new i("PROVIDER_SPEC_INVALID",`The spec isn't one this Gateway takes
3
+ ${N(a.problems)}`,{fix:"fix each field named above, then add it again"});let{id:r,capability:n}=a;if(!await b(t))throw G();let c=await f(t),s=I(c.filter(p=>p.id!==r),e.install),o=$(r,n,{rowSettings:new Set(s.rows().flatMap(p=>h(p.capability))),refuseHost:x(e.install)});if(o)switch(o.code){case"PROVIDER_BUILTIN":throw new i("PROVIDER_BUILTIN",`${r} is built in
4
+ A registered provider can't take a built-in provider's id.`,{fix:`give the provider another id in its spec; ${w} provider show ${r} prints the built-in one`});case"PROVIDER_SECRET_TAKEN":throw new i("PROVIDER_SECRET_TAKEN",`${r} can't use that setting: ${o.message}`,{fix:`name the provider's settings after its id, ${r.toUpperCase().replace(/-/g,"_")}_\u2026, and none another provider or the Gateway reads`});case"PROVIDER_HOST_REFUSED":throw new i("PROVIDER_HOST_REFUSED",`${r}'s key can't be sent there: ${o.message}`,{fix:"list only the provider's own public API hosts under hosts"});default:throw new i("PROVIDER_SPEC_INVALID",`The spec isn't one this Gateway takes
5
+ ${o.message}`,{fix:"fix the spec, then add it again"})}let l=h(n);for(let p of await P(t)){if(!p.manifest)continue;let q=S(p.manifest).map(v=>v.toUpperCase()),g=l.filter(v=>q.includes(v));if(g.length>0)throw new i("PROVIDER_SECRET_TAKEN",`${m(g)} ${g.length===1?"is":"are"} ${p.appSlug}'s own secret
6
+ ${p.appSlug}'s deployed manifest lists ${g.length===1?"it":"them"} under secrets, so a provider can't read ${g.length===1?"it":"them"} from the Gateway.`,{fix:`name the provider's settings otherwise, or drop ${m(g)} from ${p.appSlug}'s secrets and deploy it again`})}let u=c.find(p=>p.id===r);if(u&&!e.replace)throw new i("PROVIDER_EXISTS",`${r} is registered on this Gateway already
7
+ Replacing it writes the new spec; its key must then be set again before the Gateway sends it.`,{rerun:R(["--replace"]),rerunNote:"replaces it",authorize:!0});let d=e.now??Date.now(),y=JSON.stringify(e.spec),k=await H(t,"provider.added",{id:r,name:n.label},e.deployer,d,{sql:"EXISTS (SELECT 1 FROM providers WHERE id = ? AND spec = ? AND updated_at = ?)",params:[r,y,d]}),[B=[]]=await t.run([u?{sql:"UPDATE providers SET spec = ?, updated_at = ?, bound_to = NULL, bound_at = NULL WHERE id = ? RETURNING id",params:[y,d,r]}:{sql:`INSERT INTO providers (id, spec, added_by, added_at, updated_at, bound_to, bound_at)
8
+ VALUES (?1, ?2, ?3, ?4, ?4, NULL, NULL) ON CONFLICT(id) DO NOTHING RETURNING id`,params:[r,y,e.deployer.actor,d]},...k]);if(B.length===0)throw new i("PROVIDER_EXISTS",`${r} changed on this Gateway while this ran`,{rerun:`${w} provider list`,rerunNote:"shows it as it is now"});return{id:r,capability:n,replaced:!!u}}async function ee(t,e,a,{force:r=!1,now:n=Date.now()}={}){if(M(e))throw new i("PROVIDER_BUILTIN",`${e} is built in
9
+ Only a provider registered with ${w} provider add can be removed.`,{rerun:`${w} provider list`,rerunNote:"shows which are registered"});if(!await b(t))throw G();let c=(await f(t)).find(d=>d.id===e);if(!c)throw new i("PROVIDER_NOT_FOUND",`No provider ${e} is registered on this Gateway`,{rerun:`${w} provider list`,rerunNote:"shows which are"});let s=E(W(c.spec)),o=(await P(t)).filter(d=>d.manifest?.capabilities&&Object.hasOwn(d.manifest.capabilities,e)).map(d=>d.appSlug);if(o.length>0&&!r)throw new i("PROVIDER_IN_USE",`${m(o)} ${o.length===1?"lists":"list"} ${e} under capabilities
10
+ Removing it stops ${o.length===1?"its":"their"} calls to it at once: the Gateway answers that it doesn't offer ${e}.`,{rerun:R(["--force"]),rerunNote:"removes it anyway",authorize:!0});let l=s.ok?s.capability.label:e,u=await H(t,"provider.removed",{id:e,name:l},a,n,{sql:"EXISTS (SELECT 1 FROM providers WHERE id = ?)",params:[e]});return await t.run([...u,{sql:"DELETE FROM providers WHERE id = ?",params:[e]}]),{id:e,name:l,settings:s.ok?[...h(s.capability)]:[],apps:o}}async function H(t,e,a,r,n,c){let s=await C(t);return s?U(t,{organizationId:s.organization.id,type:e,actor:L(r),data:{provider:{id:a.id,name:a.name}},onlyIf:c,now:n}):[]}function W(t){try{return JSON.parse(t)}catch{return null}}async function te(t,e,a,r=Date.now()){let n=await f(t);if(n.length===0)return[];let c=I(n,e),s=F(c,a);return s.length===0?[]:(await t.run(s.map(l=>({sql:"UPDATE providers SET bound_to = ?, bound_at = ? WHERE id = ? AND spec = ? RETURNING id",params:[T(l.capability),r,l.id,n.find(u=>u.id===l.id).spec]})))).flatMap(l=>l.map(u=>String(u.id)))}export{Q as a,F as b,Z as c,ee as d,te as e};
@@ -0,0 +1,45 @@
1
+ import{a as Me,b as Lt,e as Ut}from"./chunk-IA534DGW.js";import{a as se,b as be,c as Ie,d as j,e as bt,f as ue,g as It,h as vt,j as me,k as Mt,l as ve,o as Ot}from"./chunk-MDORVBPD.js";import{c as Ct,f as Pt}from"./chunk-GRFPP4UW.js";import{a as ce,c as ot}from"./chunk-Y3VIFPN5.js";import{b as Dt,e as De}from"./chunk-PL6EORDJ.js";import{g as lt,h as dt}from"./chunk-EUNGJMJ6.js";import{$ as $e,B as V,W as te,X as Te,Y as ne,Z as b,_ as re,aa as ht,ca as Et,da as Rt,ea as ke,ha as At,ia as le,k as ut,l as mt,la as _t,na as Nt,qa as Tt,sa as $t,y as q,z as Ne}from"./chunk-ZYL2ZHCF.js";import{a as gt,e as v,o as ee,p as B,q as ft,r as wt,s as yt,t as St}from"./chunk-SPPR6WCI.js";import{b as Oe}from"./chunk-GD2JZMD3.js";import{a as W,f as it,g as pt,i as ct}from"./chunk-F6IH47GT.js";import{C as Be,D as ie,I as qe,N as H,O as pe,P as Se,Q as J,Qa as st,R as Ve,S as he,T as Ee,U as je,V as G,W as O,X as Ye,Y as Re,Z as Ae,_ as Ke,c as f,ea as Je,eb as at,hc as kt,ib as Z,k as D,ka as X,ma as Xe,na as Qe,oc as de,qa as Ze,ra as Q,sa as et,ta as tt,tb as E,ua as nt,va as _e,xb as C,ya as rt}from"./chunk-SAT3PGZU.js";import{stripVTControlCharacters as zn}from"node:util";import M from"chalk";function xt(e){if(!/^[A-Za-z_][A-Za-z0-9_]*$/.test(e))throw new E("SECRET_NAME_INVALID",`"${e}" isn't a valid secret name`,{fix:"use letters, digits and underscores, starting with a letter, e.g. GITHUB_TOKEN"});if(G(e))throw new E("SECRET_NAME_RESERVED",`${e} is a reserved name
2
+ everyapp manages ${je}.`,{fix:"pick another name"})}function wn(e){return e.ready?e.settings.some(n=>n.set===null&&n.names.length>0&&n.need.kind!=="optional")?null:"ready":"needs_setup"}function yn(e){return[...new Set(e.unmet.flatMap(t=>t.names))]}var Gt="id, organization_id, app_slug, name, status, setup_state",zt=e=>({id:String(e.id),organizationId:String(e.organization_id),appSlug:String(e.app_slug),name:String(e.name),status:String(e.status),setupState:e.setup_state==null?null:String(e.setup_state)});async function Ft(e,t){if(!await Ne(e))return null;let n=wn(t.setup);if(!n)return null;let r=t.row??await Sn(e,t.appRowId);if(!r||r.status===v)return null;let s=r.setupState==="ready"||r.setupState==="needs_setup"?r.setupState:null;if(s===n)return{state:n,previous:s,event:null};let a=n==="needs_setup"?"app.needs_setup":s==="needs_setup"?"app.ready":null,i={id:r.appSlug,rowId:r.id,name:r.name},o=a?await V(e,{organizationId:r.organizationId,type:a,actor:q(t.deployer),data:a==="app.needs_setup"?{app:i,unmet:yn(t.setup)}:{app:i},appRowId:r.id,onlyIf:{sql:"changes() > 0",params:[]},now:t.now}):[];return await e.run([{sql:"UPDATE apps SET setup_state = ? WHERE id = ? AND setup_state IS ?",params:[n,r.id,s]},...o]),{state:n,previous:s,event:a}}async function Sn(e,t){let[n=[]]=await e.run([{sql:`SELECT ${Gt} FROM apps WHERE id = ?`,params:[t]}]);return n[0]?zt(n[0]):null}async function Ht(e,t,n){try{let{cf:r,db:s,deployer:a}=e;if(t.gateway.length===0&&t.appRowId===null||!await Ne(s))return;let[i=[]]=await s.run([{sql:`SELECT ${Gt}, tier, manifest, secret_names FROM apps
3
+ WHERE status NOT IN ('${v}', 'pending') AND tier NOT IN ('${O}', 'dispatch')`}]),o=i.flatMap(c=>{let d=hn(c.manifest);return!d||typeof d!="object"||c.id===t.except?[]:c.id===t.appRowId||ue(d).some(l=>t.gateway.includes(l))?[{row:zt(c),manifest:d,secretNames:gt(b(c.secret_names))}]:[]});if(o.length===0)return;let p=await se(r);for(let c of o){let{setup:d}=j({manifest:c.manifest,appId:c.row.appSlug,gatewayNames:p,secretNames:c.secretNames});await Ft(s,{appRowId:c.row.id,setup:d,deployer:a,row:c.row})}}catch(r){n.emit({type:"progress",step:"app.setup_state",message:`Couldn't record whether the apps are set up (${C(r).split(`
4
+ `)[0]}); the Gateway records it when it next lists them`})}}function hn(e){if(typeof e!="string")return null;try{return JSON.parse(e)}catch{return null}}async function dr(e,t,n){try{await Ft(e,t)}catch(r){n.emit({type:"progress",step:"app.setup_state",message:`Couldn't record whether the app is set up (${C(r).split(`
5
+ `)[0]}); the Gateway records it when it next lists it`})}}var Wt=new WeakMap;function z(e){let t=Wt.get(e);return t||(t=e.run([{sql:"SELECT name FROM sqlite_master WHERE type = 'table' AND name IN ('remote_mcp_credentials', 'remote_mcp_tools')"}]).then(([n=[]])=>{let r=new Set(n.map(s=>String(s.name)));return{credentials:r.has("remote_mcp_credentials"),tools:r.has("remote_mcp_tools")}}),Wt.set(e,t)),t}function Bt(e){return{app:{id:e.appSlug,rowId:e.id,name:e.name},kind:ee(e)?"remote":"builtin"}}function En(e){return B(e)?.url??null}async function qt(e,t,n){let[r=[]]=await e.run([{sql:`SELECT ${await ne(e)} FROM apps WHERE organization_id = ? AND app_slug = ?`,params:[t,n]}]);return r[0]?re(r[0]):null}async function Rn(e,t){let[n=[]]=await e.run([{sql:`SELECT ${await ne(e)} FROM apps WHERE organization_id = ? AND tier = ? AND status != '${v}' ORDER BY app_slug`,params:[t,O]}]);return n.map(re).filter(ee).map(r=>r.appSlug)}async function hr(e,t){let r=(await $e(e))?.organization??null,s=r?await qt(e,r.id,t):null;if(Ae(t))return{kind:"builtin",id:t,organization:r,app:s&&s.tier===O?s:null};if(s&&ee(s))return{kind:"remote",id:t,organization:r,app:s};if(s&&s.tier!==O&&s.status!==v)throw new E("PROVIDER_APP_UNKNOWN",`"${t}" is an app deployed to this Gateway, not an MCP app
6
+ ${f} delete ${t} removes a deployed app.`,{rerun:`${f} mcp list`,rerunNote:"lists the MCP apps"});let a=r?await Rn(e,r.id):[],i=/^[a-z][a-z0-9+.-]*:\/\//i.test(t);throw new E("PROVIDER_APP_UNKNOWN",[`"${t}" is not an MCP app on this Gateway`,`Built in: ${Re.join(", ")}. Added: ${a.length>0?a.join(", "):"none yet"}.`].join(`
7
+ `),i?{rerun:`${f} mcp add ${t}`,rerunNote:"adds the server at that address"}:{rerun:`${f} mcp list`,rerunNote:"lists the MCP apps"})}function Er(e){let t=e.app?En(e.app):null;return new E("APP_NOT_FOUND",`${e.id} was removed from this Gateway
8
+ Adding it again starts fresh: nobody's access or tools are kept.`,t?{rerun:`${f} mcp add ${t} --name ${e.id}`,rerunNote:"adds it again"}:{rerun:`${f} mcp list`,rerunNote:"lists the MCP apps"})}async function Vt(e){let[t=[]]=await e.run([{sql:`SELECT tier, manifest FROM apps WHERE tier = ? AND status != '${v}'`,params:[O]}]),n=new Map;for(let r of t){let s=B({tier:String(r.tier),manifest:b(r.manifest)}),a=s?X(s.auth):null;if(!s||!a)continue;let i;try{i=new URL(s.url).origin}catch{continue}let o=n.get(a)??new Set;o.add(i),n.set(a,o)}return n}function An(e,t,n){let{app:r}=e,s=e.grants.map(a=>({sql:`INSERT INTO user_app_access (id, user_id, app_row_id, organization_id, granted_by)
9
+ VALUES (?, ?, ?, ?, NULL) ON CONFLICT DO NOTHING`,params:[a.id,a.userId,a.appRowId,a.organizationId]}));return e.kind==="new"?[{sql:`INSERT INTO apps (id, organization_id, app_slug, name, description, hostname,
10
+ worker_name, tier, manifest, status, version_id, deployed_at, deployed_by_actor,
11
+ is_default, created_at, updated_at, scope)
12
+ VALUES (?1, ?2, ?3, ?4, ?5, NULL, NULL, ?6, ?7, ?8, NULL, ?9, ?10, 0, ?11, ?11, ?12)`,params:[r.id,r.organizationId,r.appSlug,r.name,r.description,r.tier,r.manifest,r.status,r.deployedAt,r.deployedByActor,t,r.scope]},...s]:[{sql:`UPDATE apps SET name = ?, description = ?, manifest = ?, status = ?, is_default = 0,
13
+ deployed_at = ?, deployed_by_actor = ?, updated_at = ?
14
+ WHERE id = ? AND status = '${v}'`,params:[r.name,r.description,r.manifest,r.status,r.deployedAt,r.deployedByActor,t,r.id]},...ke(r,t,{secretNames:n.secretNames}),...n.remoteTools?[jt(r)]:[],...s]}function jt(e){return{sql:"DELETE FROM remote_mcp_tools WHERE app_row_id = ? AND organization_id = ?",params:[e.id,e.organizationId]}}function Rr(e,t){return te(async()=>{let n=t.now??Date.now(),r=t.url.trim(),s=(t.id??"").trim()||Je(r)||"",{organization:a,hasOwner:i}=await ht(e,t.organizationName,n),[o=[],p=[],c=[]]=await e.run([{sql:`SELECT ${await ne(e)} FROM apps WHERE organization_id = ? AND app_slug = ?`,params:[a.id,s]},...Et(a.id,t.deployer.email)]),d=o[0]?re(o[0]):null,m=await Vt(e),l=b(c[0]?.id),S=ft({organizationId:a.id,url:r,id:t.id,name:t.name,description:t.description,auth:t.auth,risk:t.risk,env:t.env,existingApp:R=>{if(R!==s)throw new Error(`The rules asked for "${R}", not "${s}".`);return d},secretUsedAt:R=>{let A=[...m.get(R)??[]],y=new URL(r).origin;return A.find(g=>g!==y)??A[0]??null},members:Rt(p),actorUserId:l,actor:t.deployer.actor,now:n}),h=await z(e),w=await V(e,{organizationId:a.id,type:"mcp_app.added",actor:q(t.deployer),data:{app:{id:S.app.appSlug,rowId:S.app.id,name:S.app.name},kind:"remote"},appRowId:S.app.id,onlyIf:{sql:"EXISTS (SELECT 1 FROM apps WHERE id = ? AND status = ? AND updated_at = ?)",params:[S.app.id,S.app.status,n]},now:n});return await e.run([...An(S,n,{secretNames:await Te(e),remoteTools:h.tools}),...w]),{plan:S,organization:a,hasOwner:i,actorGranted:l!==null&&S.grants.some(R=>R.userId===l)}})}function Ar(e,t,n,r,s=Date.now()){return te(async()=>{let a=yt(t,n);if(!a)return{changed:!1};let i=await V(e,{organizationId:t.organizationId,type:a.status==="active"?"mcp_app.enabled":"mcp_app.disabled",actor:q(r),data:Bt(t),appRowId:t.id,onlyIf:{sql:"EXISTS (SELECT 1 FROM apps WHERE id = ? AND status = ? AND updated_at = ?)",params:[t.id,a.status,s]},now:s}),[o=[]]=await e.run([{sql:"UPDATE apps SET status = ?, updated_at = ? WHERE id = ? AND status = ? RETURNING id",params:[a.status,s,t.id,t.status]},...i]);if(o.length===0)throw new E("APP_CHANGING",`${t.appSlug} changed while this ran
15
+ Nothing was written; run it again.`,{retryable:!0});return{changed:!0}})}function _r(e,t,n,r=Date.now()){return te(async()=>{let s=St(t);if(!t||!s)return{removed:!1};let a=await z(e);return await e.run([{sql:"UPDATE apps SET status = ?, is_default = ?, updated_at = ? WHERE id = ?",params:[s.status,s.isDefault?1:0,r,t.id]},...ke(t,r,{secretNames:await Te(e)}),...a.tools?[jt(t)]:[],...await V(e,{organizationId:t.organizationId,type:"mcp_app.removed",actor:q(n),data:Bt(t),appRowId:t.id,now:r})]),{removed:!0}})}function Ce(e){return e?{status:String(e.status),toolCount:Number(e.tool_count??0),listedAt:e.fetched_at==null?null:Number(e.fetched_at),lastError:b(e.last_error)}:null}async function Nr(e,t){let n=[t.id,t.organizationId],[r=[]]=await e.run([{sql:"SELECT status, tool_count, fetched_at, last_error FROM app_tool_catalogs WHERE app_row_id = ? AND organization_id = ?",params:n},{sql:"DELETE FROM app_tools WHERE app_row_id = ? AND organization_id = ?",params:n},{sql:"DELETE FROM app_tool_catalogs WHERE app_row_id = ? AND organization_id = ?",params:n}]);return Ce(r[0])}async function _n(e){if(!(await z(e)).credentials)return new Map;let[t=[]]=await e.run([{sql:"SELECT name, origin, bound_by, bound_at FROM remote_mcp_credentials ORDER BY name"}]);return new Map(t.map(n=>[String(n.name),{origin:String(n.origin),boundBy:b(n.bound_by),boundAt:n.bound_at==null?null:Number(n.bound_at)}]))}async function Tr(e){let t=await $e(e),n=[],r=new Map;if(t){let[o=[],p=[]]=await e.run([{sql:`SELECT ${await ne(e)} FROM apps WHERE organization_id = ? AND tier = ? AND status != '${v}' ORDER BY app_slug`,params:[t.organization.id,O]},{sql:"SELECT app_row_id, status, tool_count, fetched_at, last_error FROM app_tool_catalogs WHERE organization_id = ?",params:[t.organization.id]}]);n.push(...o.map(re));for(let c of p)r.set(String(c.app_row_id),Ce(c))}let s=new Map(n.map(o=>[o.appSlug,o])),a=Re.map(o=>{let p=s.get(o)??null;return{id:o,name:Ye[o].name,kind:"builtin",app:p,remote:null,keyName:Ke(o),snapshot:p?r.get(p.id)??null:null}}),i=n.filter(o=>!Ae(o.appSlug)&&ee(o)).map(o=>{let p=B(o);return{id:o.appSlug,name:o.name,kind:"remote",app:o,remote:p,keyName:p?X(p.auth):null,snapshot:r.get(o.id)??null}});return[...a,...i]}function $r(e,t,n){if(!e.app||e.app.status===v)return"not added";if(e.app.status!=="active")return"off";if(e.kind==="remote"&&!e.remote||e.keyName&&!t.includes(e.keyName))return"needs setup";if(e.kind==="remote"&&e.keyName&&e.remote){let r=n.get(e.keyName);if(r&&r.origin!==Nn(e.remote.url))return"needs setup"}return"on"}function Nn(e){try{return new URL(e).origin}catch{return""}}function Tn(e){return e==="read"?{readOnlyHint:!0}:e==="destructive"?{destructiveHint:!0}:{}}function $n(e,t,n,r){return n.map(s=>{let a=String(s.upstream_name),i=String(s.risk_hint),o=b(s.local_name),p=Xe(Tn(i),t,a),c=p.source==="default"&&i==="write"?"hint":p.source,d=o?r.get(o):void 0,m=Qe(t,a),l=!!Number(s.listed);return{name:o?`${e}_${o}`:null,serverName:a,title:b(s.title),risk:d??p.risk,source:c,on:m&&l,problem:m?l?null:b(s.problem)??"not listed":l?"turned off; leaves the catalog at the next listing":"turned off"}})}async function kr(e,t,n){let r=[t.app.id,t.app.organizationId],s=await z(e),a=n?X(n.auth):null,[i=[],o=[],p=[],c=[]]=await e.run([{sql:"SELECT status, tool_count, fetched_at, last_error FROM app_tool_catalogs WHERE app_row_id = ? AND organization_id = ?",params:r},{sql:"SELECT name, title, risk FROM app_tools WHERE app_row_id = ? AND organization_id = ? ORDER BY name",params:r},...s.tools&&n?[{sql:`SELECT upstream_name, local_name, title, risk_hint, listed, problem, listed_at FROM remote_mcp_tools
16
+ WHERE app_row_id = ? AND organization_id = ? ORDER BY upstream_name`,params:r}]:[{sql:"SELECT 1 WHERE 0"}],...s.credentials&&a?[{sql:"SELECT origin, bound_by, bound_at FROM remote_mcp_credentials WHERE name = ?",params:[a]}]:[{sql:"SELECT 1 WHERE 0"}]]),d=new Map(o.map(l=>[String(l.name),String(l.risk)])),m=c[0];return{snapshot:Ce(i[0]),remoteTools:n?$n(t.id,n,p,d):[],catalogTools:o.map(l=>({name:`${t.id}_${String(l.name)}`,title:b(l.title),risk:String(l.risk)})),binding:m?{origin:String(m.origin),boundBy:b(m.bound_by),boundAt:m.bound_at==null?null:Number(m.bound_at)}:null,listingKnown:s.tools}}var kn=3;function Dr(e,t,n,r,s=Date.now()){return te(async()=>{let a=await z(e),[i=[]]=await e.run([a.tools?{sql:`SELECT upstream_name, local_name FROM remote_mcp_tools
17
+ WHERE app_row_id = ?1 AND (upstream_name = ?2 OR local_name = ?2 OR ?3 || local_name = ?2)
18
+ ORDER BY (upstream_name = ?2) DESC, upstream_name LIMIT 1`,params:[t.app.id,n,`${t.id}_`]}:{sql:"SELECT 1 WHERE 0"}]),o=i[0],p=o?String(o.upstream_name):n,c=o?b(o.local_name):null,d={};r.risk==="annotations"?d.risk=void 0:r.risk&&(d.risk=r.risk),r.enabled!==void 0&&(d.enabled=r.enabled);let m=t.app;for(let l=1;;l+=1){let S=B(m)?.tools[p]??null,h=wt(m,{tool:{name:p,override:d}}),[w=[]]=await e.run([{sql:`UPDATE apps SET manifest = ?, name = ?, description = ?, updated_at = ?
19
+ WHERE id = ? AND manifest = ? AND status != '${v}' RETURNING id`,params:[h.manifest,h.name,h.description,s,m.id,m.manifest]}]);if(w.length>0)return{serverName:p,listedName:c?`${t.id}_${c}`:null,inListing:!!o,before:S,after:h.remote.tools[p]??null,rev:h.remote.rev};let R=await qt(e,m.organizationId,m.appSlug);if(!R||l>=kn)throw new E("APP_CHANGING",`${t.id} keeps changing while this writes its tool settings
20
+ Nothing was written; run it again.`,{retryable:!0});m=R}})}async function Yt(e,t,n,r=Date.now()){let s={bound:[],undeclared:[],ambiguous:[]},a=t.filter(Se);if(a.length===0||!(await z(e)).credentials)return s;let i=await Vt(e),o=await _n(e),p=[];for(let c of a){let d=[...i.get(c)??[]].sort();d.length===0?s.undeclared.push({name:c,kept:o.get(c)?.origin??null}):d.length>1?s.ambiguous.push({name:c,origins:d}):(s.bound.push({name:c,origin:d[0]}),p.push({sql:`INSERT INTO remote_mcp_credentials (name, origin, bound_by, bound_at) VALUES (?, ?, ?, ?)
21
+ ON CONFLICT(name) DO UPDATE SET origin = excluded.origin, bound_by = excluded.bound_by, bound_at = excluded.bound_at`,params:[c,d[0],n,r]}))}return p.length>0&&await e.run(p),s}async function Kt(e,t){let n=t.filter(Se);if(n.length===0||!(await z(e)).credentials)return[];let[r=[]]=await e.run([{sql:`DELETE FROM remote_mcp_credentials WHERE name IN (${n.map(()=>"?").join(", ")}) RETURNING name`,params:n}]);return r.map(s=>String(s.name))}async function Jt(e){let[t=[]]=await e.run([{sql:`SELECT app_slug, tier, manifest FROM apps WHERE tier = ? AND status != '${v}' ORDER BY app_slug`,params:[O]}]),n=new Map;for(let r of t){let s=B({tier:String(r.tier),manifest:b(r.manifest)}),a=s?X(s.auth):null;a&&n.set(a,[...n.get(a)??[],String(r.app_slug)])}return n}import{text as Dn}from"node:stream/consumers";function Zt(e){return e?"env":process.stdin.isTTY?"prompt":"stdin"}function en(e,t){let n=Zt(t);if(!(n==="prompt"||e.length<2))throw new E("SECRET_SEVERAL_NAMES",`${n==="env"?"--from-env":"A piped value"} sets one secret at a time, and you named ${e.length}`,{fix:`run it once per name, e.g. ${n==="env"?`${f} secret set ${e[0]} --from-env ${t}`:`echo "$${e[0]}" | ${f} secret set ${e[0]}`}`})}function tn(e){return e.length<2?e[0]??"":`${e.slice(0,-1).join(", ")} or ${e.at(-1)}`}function U(e,{exact:t=!1}={}){return n=>e.includes(t?n:n.toLowerCase())?null:`Not ${e.length>2?"one of ":""}${tn(e)}.`}function ae(e,t){return n=>{let r=n.split(/[\s,]+/).filter(Boolean),s=r.find(a=>!e(a));return s!==void 0?`"${s}" isn't ${t}.`:r.length>0?null:`Name ${t}.`}}var Pe=["true","false","1","0","on","off","yes","no"],bn=/^[^\s@<>]+@[^\s@<>]+\.[^\s@<>]+$/,In=/^(?=.{1,253}$)(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.)+[a-z0-9-]{2,63}$/,vn=/^(?=.{1,253}$)(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$/,Mn=/^[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.cloudflareaccess\.com$/,Xt=/^[A-Za-z0-9._:-]{1,256}$/,On=/^\/v1(\/[a-z0-9_-]+)+$/,Le=3650,Cn=e=>In.test(e.toLowerCase().replace(/^@/,"")),Pn=e=>vn.test(e.toLowerCase().replace(/\.$/,""));function Ln(e){try{let t=new URL(e);return t.protocol==="http:"||t.protocol==="https:"?t:null}catch{return null}}function nn(e){let t;try{t=new URL(e)}catch{return null}return t.username||t.password||t.search||t.hash?null:t.protocol==="https:"&&Mn.test(t.hostname.toLowerCase())?t:null}function Un(e){let t=nn(/^[a-z]+:\/\//i.test(e)?e:`https://${e}`);return t!==null&&(t.pathname==="/"||t.pathname==="")}var xn={EMAIL_FROM:{takes:"an address, or Name <address> (with EMAIL_FROM_NAME set, unless the name is in it)",check:e=>{let t=rt(e,"sender");return t&&bn.test(t.address)?null:`"${e}" isn't an address or Name <address>.`}},EMAIL_FROM_NAME:{takes:"the sender's display name, e.g. Acme Support"},EMAIL_PROVIDER:{takes:`${tn(_e)}: which provider sends when both are set up`,check:U(_e)},EMAIL_PASSWORD_SIGN_IN:{takes:"true or false; false turns password sign-in off (only while Cloudflare Access sign-in is on)",check:U(Pe)},MASTODON_URL:{takes:"the Mastodon instance's https origin, e.g. https://mastodon.social",check:e=>qe(Be.mastodon,{MASTODON_URL:e})?null:`"${e}" isn't an https origin (no path).`},AI_PROXY_EXTRA_ROUTES:{takes:"/v1 paths beyond inference the AI proxy may forward, comma separated, e.g. /v1/files",check:ae(e=>On.test(e),"a /v1/... path")},MCP_OAUTH_ENABLED:{takes:"true or false; false turns the OAuth server for MCP clients off",check:U(Pe)},MCP_DCR_ENABLED:{takes:"true or false; false turns dynamic client registration off",check:U(Pe)},MCP_ALLOWED_ORIGINS:{takes:"browser origins allowed to call /mcp, comma separated, e.g. http://localhost:6274",check:ae(e=>Ln(e)!==null,"an http or https URL")},MCP_AUDIT_RETENTION_DAYS:{takes:`days of MCP tool-call audit rows to keep: a whole number from 1 to ${Le}`,check:e=>/^\d+$/.test(e)&&Number(e)>=1&&Number(e)<=Le?null:`Not a whole number from 1 to ${Le}.`},CLOUDFLARE_ACCESS_OIDC_ISSUER:{takes:"https://<team>.cloudflareaccess.com/cdn-cgi/access/sso/oidc/<client id>",check:e=>{let t=nn(e);return t&&/^\/cdn-cgi\/access\/sso\/oidc\/[^/]+\/?$/.test(t.pathname)?null:`"${e}" isn't an Access for SaaS issuer URL.`}},CLOUDFLARE_ACCESS_OIDC_CLIENT_ID:{takes:"the Access for SaaS application's client id"},CLOUDFLARE_ACCESS_OIDC_LABEL:{takes:`the sign-in button's label ("Continue with <label>"), at most 40 characters`},CLOUDFLARE_ACCESS_TEAM_DOMAIN:{takes:"<team>.cloudflareaccess.com",check:e=>Un(e)?null:`"${e}" isn't <team>.cloudflareaccess.com.`},CLOUDFLARE_ACCESS_AUD:{takes:"the AUD tag of the Access application on the Gateway's host (several: comma separated)",check:ae(e=>Xt.test(e),"an AUD tag")},CLOUDFLARE_ACCESS_APPS_AUD:{takes:"the AUD tag of the Access application on the apps' hosts (several: comma separated)",check:ae(e=>Xt.test(e),"an AUD tag")},CLOUDFLARE_ACCESS_AUTO_JOIN_DOMAINS:{takes:"email domains whose people join without an invitation, comma separated, e.g. example.com",check:ae(Cn,"a domain like example.com")},CLOUDFLARE_ACCESS_OUTER_RING_AUTO_JOIN:{takes:`everyone (anyone the outer ring admits joins); to turn it off: ${f} secret unset CLOUDFLARE_ACCESS_OUTER_RING_AUTO_JOIN`,check:U(["everyone"])},HOSTED_OPEN_SIGNUP:{takes:"true or false; false keeps a hosted Gateway's sign-up invite-only",check:U(["true","false"])},BROWSER_APP_INSTALLS:{takes:"on or off, in lowercase; off turns browser app installs off",check:U(["on","off"],{exact:!0})},EVENTS_ALLOW_PRIVATE_TARGETS:{takes:"true or false, in lowercase; true lets event webhooks reach http: URLs and private host names",check:U(["true","false"],{exact:!0})},DISPATCH_NAMESPACE:{takes:"the Workers for Platforms namespace third-party Workers go into (hosted Gateway only)"},THIRD_PARTY_DOMAIN:{takes:"the registrable domain third-party apps are named on (hosted Gateway only)",check:e=>Pn(e)?null:`"${e}" isn't a domain like example.com.`}};function Ue(e){return xn[e]}function Gn(e){let t=Ue(e);return t?[`Takes ${t.takes}`]:[]}function rn(e,t){return t.trim()?Ue(e)?.check?.(t.trim())??null:"Enter a value."}function Qt(e,t){let n=t.trim(),r=rn(e,n);if(r===null)return n;let s=Ue(e),a=n.replace(/\s+/g," ").slice(0,64);throw new E("SETTING_VALUE_INVALID",`${e} can't be "${a}"
22
+ ${r}`,{...s?{fix:`use ${s.takes}`}:{},data:{name:e}})}async function sn(e,t){let n=Ve(e),r=t.fromEnv,s=Zt(r);if(s==="env"){let a=process.env[r],i=n?a?.trim():a;if(!i)throw new E("SECRET_EMPTY",`$${r} is empty or not set`,{fix:`export ${r} first, or name another variable with --from-env`});return n?Qt(e,i):i}if(s==="stdin"){let a=(await Dn(process.stdin)).replace(/\r?\n$/,""),i=n?a.trim():a;if(i)return n?Qt(e,i):i}if(s==="stdin"||!W(t.json??!1))throw new E("SECRET_VALUE_REQUIRED",`Can't ask for ${e}'s value without a terminal
23
+ Or pipe it in: echo "$${e}" | ${f} secret set ${e}`,{rerun:`${f} secret set ${e} --from-env ${e}`});return n?(await it(e,{context:Gn(e),validate:i=>rn(e,i)})).trim():(await pt(`Value for ${e}`)).trim()}async function ps(e,...t){await de(e,async n=>{en(t,e["from-env"]),await Fn({flags:e,out:n,names:t,readValue:r=>sn(r,{fromEnv:e["from-env"],json:e.json})})})}async function cs(e,...t){await de(e,n=>qn({flags:e,out:n,names:t}))}async function ls(e,t){await de(e,n=>Vn({flags:e,out:n,appId:t}))}async function Fn(e){let{applied:t,gatewayHost:n}=await Hn(e),r=(t.gateway?.pinned??[]).map(({name:s,origin:a})=>`${s} is sent to ${a} and nowhere else.`);e.out.emit({type:"done",message:[`Set ${Ge(t,"on")}`,...r].join(`
24
+ `),display:[...r,M.dim(t.app?"Live now. No deploy needed.":`Live now on ${n}. No deploy needed.`)].join(`
25
+ `),data:Fe(t)})}async function Hn(e){let t=await ln(e.names,e,"set");Bn(t.providers,e.names,e.out);let n={};for(let s of e.names)n[s]=await e.readValue(s);return{applied:await fe(t,n,e,"set"),gatewayHost:t.gatewayHost}}function Wn(e){return D([...e.hosts,...e.hostSetting?[`the host ${e.hostSetting} names`]:[]])}function Bn(e,t,n){for(let r of e){let{capability:s}=r;for(let a of ie(s).filter(i=>t.includes(i))){let i=r.addedAt?` on ${new Date(r.addedAt).toISOString().slice(0,10)}`:"",o=r.addedBy?` by ${r.addedBy}`:"";n.emit({type:"step",step:"secrets.provider",status:"ok",message:`${a} is ${s.label}'s, registered${o}${i}; the key is sent to ${Wn(s)}.`,data:{name:a,provider:r.id,addedBy:r.addedBy,addedAt:r.addedAt,hosts:[...s.hosts],...s.hostSetting?{hostSetting:s.hostSetting}:{}}})}}}async function ds(e,t,n){let r=Object.keys(t),s=Object.values(t).every(i=>i===null);for(let i of r)if(!J(i))throw new Error(`${i} isn't a Gateway setting`);let a={route:{gateway:r,app:null,undeclared:[]},cf:e.cf,db:e.db,deployer:e.deployer,accountName:e.accountName,gatewayHost:e.gatewayUrl.replace(/^https:\/\//,""),app:null,providers:[]};return fe(a,t,n,s?"unset":"set")}async function us(e,t,n,r){let s=Object.keys(n),a=await xe(s,t.manifest,e,"set"),i=ge(s,t.manifest,t.source,"set",a.names);if(i.app&&!t.app)throw new E("APP_NOT_FOUND",`${t.manifest.id} isn't deployed yet
26
+ Its own ${D(i.app.names)} can be set after its first deploy. Nothing was changed.`,{rerun:`${f} deploy`});let o={route:i,cf:e.cf,db:e.db,deployer:e.deployer,accountName:e.accountName,gatewayHost:e.gatewayUrl.replace(/^https:\/\//,""),app:i.app&&t.app?{...i.app,...t.app}:null,providers:a.providers};return await fe(o,n,r,"set")}async function qn(e){let{names:t,out:n}=e,r=await ln(t,e,"unset"),{route:s}=r,a=()=>{let p=`${D(t)} ${t.length===1?"isn't":"aren't"} set on ${Kn(s).join(" or ")}. Nothing changed.`;n.emit({type:"done",message:p,display:M.dim(p),data:{removed:!1}})};if(!await Qn(r)){a();return}await ct({yes:e.flags.yes,interactive:e.interactive??W(e.flags.json??!1),confirm:e.confirm,question:`Remove ${Ge({...s.gateway.length>0?{gateway:{names:s.gateway,versions:{}}}:{},...s.app?{app:{id:s.app.manifest.id,workerName:"",names:s.app.names,versions:{}}}:{}},"from")}?`,unattended:"Removing secrets needs confirmation, and there's no terminal to ask in",context:s.undeclared.map(p=>s.app?.source==="registry"?`${p} isn't listed in ${s.app.manifest.id}'s deployed manifest.`:`${p} isn't listed in everyapp.config.ts.`)});let i=Object.fromEntries(t.map(p=>[p,null])),o=await fe(r,i,e,"unset");if(!o){a();return}n.emit({type:"done",message:`Removed ${Ge(o,"from")}`,display:M.dim("Live now. No deploy needed."),data:Fe(o)})}async function Vn(e){let{out:t}=e,n=e.appId?null:await Oe(e.cwd??process.cwd()),{cf:r,db:s,gatewayUrl:a,install:i}=await on(e),[o,p]=await Promise.all([se(r),Me(s,i)]),c=[...pe,...p.rows().flatMap(N=>ie(N.capability))],d=(N,$)=>t.emit({type:"done",message:zn(N),display:N,data:$});if(!e.appId&&!n){let N=o.filter(u=>!H(u)),$=o.filter(u=>H(u)),T=await Nt(s),k=new Set(T.flatMap(u=>u.manifest?ue(u.manifest,p):[])),x=i.deploymentMode==="hosted",F=c.filter(u=>x||!he(u)).filter(u=>!o.includes(u)),P=await Jt(s),L=[...F.filter(u=>k.has(u)||x&&he(u)),...[...P.keys()].filter(u=>!o.includes(u))],He=F.filter(u=>!L.includes(u)).length,oe=[],ye=[];for(let u of T){if(!u.manifest||!bt(u.manifest,p)||u.tier==="dispatch")continue;if(u.tier===O){let K=tt(et(u.manifest),(gn,fn)=>gn==="gateway"?o.includes(fn):null);if(K.ready)continue;let mn=nt(K,{cli:f,appId:u.appSlug,provider:!0});oe.push({id:u.appSlug,setup:mn,rows:me(u.appSlug,K.settings)});continue}let Y=u.status==="pending"?null:await be(r,u.workerName).catch(K=>(ye.push({id:u.appSlug,reason:C(K).split(`
27
+ `)[0]}),null)),{report:dn,setup:un}=j({manifest:u.manifest,appId:u.appSlug,gatewayNames:o,secretNames:Y,lookup:p});oe.push({id:u.appSlug,setup:un,rows:me(u.appSlug,dn.settings)})}let We=oe.flatMap(u=>u.rows);d([M.dim(`Gateway secrets \xB7 ${a.replace(/^https:\/\//,"")}`),"",...kt(["NAME","SET BY"],[...N.map(u=>[u,"you"]),...$.map(u=>[u,M.dim("setup")]),...L.map(u=>[u,M.dim("not set")])]),...He>0?[M.dim(`${He} more can be set; see docs/capabilities.md`)]:[],...We.length>0?["",...ve(We)]:[],...ye.length>0?[M.dim(jn(ye))]:[]].join(`
28
+ `),{gateway:{workerName:Z,names:o,settable:c,mcpCredentials:[...P].map(([u,Y])=>({name:u,apps:Y,set:o.includes(u)}))},apps:oe.map(({id:u,setup:Y})=>({id:u,setup:Y}))});return}let m=e.appId?await At(s,e.appId):await le(s,n.id),l=e.appId?pn(m):n,S=m&&m.status!=="pending"?m.workerName:null,h=Q(l),w=[];if(S){let N=(await ze(s,S)).filter($=>$.binding!=="").map($=>$.name);for(let $ of[S,...N]){let T=await ce(r,$);w.push({workerName:$,names:T,missing:h.filter(k=>!T.includes(k))})}}let R=w[0]?w[0].names.filter(N=>!G(N)):null,{report:A,setup:y}=j({manifest:l,appId:l.id,gatewayNames:o,secretNames:R,lookup:p}),g=me(l.id,A.settings).map(N=>!S&&N.where===l.id?{...N,status:M.dim("after first deploy")}:N);for(let N of w.slice(1)){let $=N.names.filter(k=>!G(k)),{report:T}=j({manifest:l,appId:l.id,gatewayNames:o,secretNames:$,lookup:p});g.push(...Mt(l.id,N.workerName.split("--").at(-1),T.settings))}let _=`${M.green("\u2713")} set`;if(e.flags.verbose&&w[0])for(let N of w[0].names.filter(G))g.push({app:l.id,setting:N,where:l.id,status:_});let I=S?y.command?[y.command.command]:[]:[...y.command?[{command:`${f} configure`,note:"in the app's directory"}]:[],`${f} deploy`];d(g.length>0?[...ve(g,{app:!1}),...y.unmet.length>0?["",...Ot(y.unmet)]:[],...!S&&h.length>0?["",M.dim(`${l.id} isn't deployed yet; its own secrets can be set after that.`)]:[]].join(`
29
+ `):M.dim(`${l.id} declares no secrets and needs no Gateway settings.`),{app:{id:l.id,deployed:S!==null,workerName:S,declared:h,workers:w,secretNames:R,settings:A.settings,setup:y},gateway:{workerName:Z,names:o,needed:It(A.settings,Ie(o,p)),missing:vt(A.settings,Ie(o,p)),settable:c},...g.length>0&&I.length>0?{next:I}:{}})}function jn(e){return`Couldn't list ${D(e.map(n=>`${n.id}'s`))} secrets. Cloudflare said: ${e[0].reason}. They show as not recorded.`}var Yn=(n=>(n.Directory="directory",n.Registry="registry",n))(Yn||{});function Kn(e){return[...e.gateway.length>0?["the Gateway"]:[],...e.app?[e.app.manifest.id]:[]]}function ge(e,t,n,r,s=new Set){let a=d=>J(d)||s.has(d),i=e.filter(a),o=e.filter(d=>!a(d));if(o.length===0)return{gateway:i,app:null,undeclared:[]};let p=t?Q(t):[],c=[];for(let d of o){let m=Jn(d,e,t,n,r);if(m)throw m;p.includes(d)||c.push(d)}return{gateway:i,app:{manifest:t,names:o,source:n},undeclared:c}}function Jn(e,t,n,r,s){let a=n?Q(n):[];if(n&&a.includes(e))return null;let i=r==="registry"&&n?` --app ${n.id}`:"",o=an(e,[...pe,...a]);return o?new E("SECRET_NOT_DECLARED",`${e} isn't a Gateway setting${n?` or one of ${n.id}'s secrets`:""}`,{rerun:`${f} secret ${s} ${t.map(p=>p===e?o:p).join(" ")}${i}`,data:{didYouMean:o}}):H(e)&&!n?new E("SECRET_NOT_SETTABLE",`${e} can't be changed with secret ${s}
30
+ ${e==="THIRD_PARTY_DEPLOYS"?"It's the hosted Gateway's launch gate, opened by hand.":"It's one of the Gateway's own keys, written once by setup."}`):Ee(e)?new E("SECRET_NOT_SETTABLE",`${e} only works in local development
31
+ A deployed Gateway doesn't read it.`,{fix:"set it in the Gateway's .dev.vars"}):(xt(e),n?s==="unset"?null:new E("SECRET_NOT_DECLARED",[`${n.id} doesn't list ${e} as a secret`,r==="registry"?`Its deployed manifest (what --app ${n.id} reads) doesn't list it, and it isn't a Gateway setting either.`:H(e)?`It's one of the Gateway's own keys; listing it under secrets gives ${n.id} a secret of its own.`:"It isn't a Gateway setting either."].join(`
32
+ `),{fix:`add it to secrets in everyapp.config.ts: ${Xn(n,e)}${r==="registry"?` and deploy ${n.id} again`:""}`,rerun:`${f} secret set ${e}${i}`}):new E("SECRET_NOT_DECLARED",`${e} isn't a Gateway setting, and there's no app here
33
+ An app's own secrets are ${s==="set"?"set":"removed"} from the app's directory (where everyapp.config.ts is), or from anywhere with --app <id>.
34
+ Gateway settings: ${f} secret list`,{fix:"cd into the app's directory and run this again, or add --app <id>"}))}function Xn(e,t){let n=e.secrets??[],r=a=>typeof a=="string"?JSON.stringify(a):`{ ${Object.entries(a).map(([i,o])=>`${i}: ${JSON.stringify(o)}`).join(", ")} }`,s=n.every(a=>typeof a=="string")?JSON.stringify(t):`{ name: ${JSON.stringify(t)} }`;return`secrets: [${[...n.map(r),s].join(", ")}],`}function an(e,t){let n=r=>r.toUpperCase().replace(/_/g,"");return t.find(r=>r!==e&&n(r)===n(e))}function on({flags:e,out:t,createCf:n}){return $t({gateway:Tt(e.gateway),accountId:e["account-id"],interactive:W(e.json??!1),login:{json:e.json,out:t,step:"login"},createCf:n})}async function ze(e,t){return(await Dt(e,t)).filter(n=>n.kind==="worker")}function pn(e){if(!e.manifest)throw new E("MANIFEST_NOT_FOUND",`${e.appSlug}'s registry row holds no manifest
35
+ Deploying it again stores one.`,{rerun:`${f} deploy`,rerunNote:"in the app's directory"});try{return at(e.manifest)}catch(t){throw new E("INVALID_MANIFEST",`${e.appSlug}'s deployed manifest can't be read
36
+ ${C(t)}`,{rerun:`${f} deploy`,rerunNote:"in the app's directory"})}}function cn(e,t){let n=t?Q(t):[];return e.filter(r=>!J(r)&&!n.includes(r)&&st.test(r)&&!H(r)&&!Ee(r)&&!G(r)&&!an(r,[...pe,...n]))}async function xe(e,t,n,r){let s=cn(e,t);if(s.length===0)return{names:new Set,providers:[]};let a=await Me(n.db,n.install),i=Lt(a,s),o=new Set(i.flatMap(c=>ie(c.capability)).filter(c=>s.includes(c))),p=s.filter(c=>!o.has(c));if(r==="unset"&&p.length>0){let c=await se(n.cf);for(let d of p)c.includes(d)&&o.add(d)}return{names:o,providers:i}}async function ln(e,t,n){let r=e.every(h=>J(h)),s=t.flags.app,a,i=async()=>a??=await on(t),o=(h,w,R,A=[])=>({route:w,cf:h.cf,db:h.db,deployer:h.deployer,accountName:h.accountName,gatewayHost:h.gatewayUrl.replace(/^https:\/\//,""),app:R,providers:A});if(r)return o(await i(),ge(e,null,"directory",n),null);if(s){let h=await i(),w=await le(h.db,s);if(!w)throw new E("APP_NOT_FOUND",`${s} isn't deployed to this Gateway
37
+ An app's secrets can be set after its first deploy. Nothing was changed.`,{rerun:`${f} status`,rerunNote:"lists its apps"});let R=pn(w),A={id:R.id,secrets:Ze(R)},y=await xe(e,A,h,n),g=ge(e,A,"registry",n,y.names);return o(h,g,g.app?{...g.app,workerName:w.workerName,rowId:w.id}:null,y.providers)}let p=await Oe(t.cwd??process.cwd()),c=cn(e,p).length>0?await xe(e,p,await i(),n):{names:new Set,providers:[]},d=ge(e,p,"directory",n,c.names);if(!d.app)return o(await i(),d,null,c.providers);let m=await i(),{id:l}=d.app.manifest,S=await le(m.db,l);if(!S)throw new E("APP_NOT_FOUND",`${l} isn't deployed yet
38
+ Its secrets can be set after its first deploy. Nothing was changed.`,{rerun:`${f} deploy`});return o(m,d,{...d.app,workerName:S.workerName,rowId:S.id},c.providers)}async function Qn({cf:e,db:t,route:n,app:r}){let s=[...n.gateway.length>0?[{workerName:Z,names:n.gateway}]:[],...r?(await ze(t,r.workerName)).map(a=>({workerName:a.name,names:r.names})):[]];for(let{workerName:a,names:i}of s){let o=await ce(e,a);if(i.some(p=>o.includes(p)))return!0}return!1}async function fe(e,t,n,r){let{out:s}=n,{cf:a,db:i,route:o,app:p,deployer:c}=e,d=W(n.flags.json??!1),m=h=>Object.fromEntries(h.map(w=>[w,t[w]??null])),l=r==="unset",S=o.gateway.length>0?await dt({db:i,out:s},"gateway.secrets"):null;try{let h=p?await lt({db:i,out:s},{workerName:p.workerName,appId:p.manifest.id,purpose:"app.secrets"}):null;try{let w=[],R=null;if(S){let y=await ut(i);if(R=y,!y)throw new E("GATEWAY_NOT_INSTALLED",`The Gateway${e.accountName?` in ${e.accountName}`:""} isn't fully installed`,{rerun:`${f} setup`});w.push({step:"secrets.gateway",shownAs:"the Gateway",names:o.gateway,targets:[{workerName:Z,changes:m(o.gateway),recordedVersionIds:[y.liveVersionId],record:g=>mt(i,{...y,liveVersionId:g,updatedAt:Date.now(),updatedBy:c.actor})}]})}if(p){let y=await ze(i,p.workerName),g=y.map(_=>_.versionId);w.push({step:"secrets.app",shownAs:p.manifest.id,names:p.names,targets:[{workerName:p.workerName,changes:m(p.names),recordedVersionIds:g,record:_=>De(i,p.workerName,_)},...y.filter(_=>_.binding!=="").map(_=>({workerName:_.name,changes:m(p.names),recordedVersionIds:g,record:I=>De(i,p.workerName,I,_.binding)}))]})}for(let y of w)for(let g of y.names)s.emit({type:"progress",step:"secrets.route",message:`${g} is ${y.step==="secrets.gateway"?"a Gateway setting":`${y.shownAs}'s secret`} \u2192 Worker ${y.targets.map(_=>_.workerName).join(", ")}`});for(let y of w)for(let g of y.targets){let _=D(Object.keys(g.changes));await Pt({cf:a,workerName:g.workerName,shownAs:y.shownAs,recordedVersionIds:g.recordedVersionIds,interactive:d,change:l?{question:`Remove ${_} from it anyway?`,effect:`Removing ${_} creates a new version from it.`}:{question:`Set ${_} on it anyway?`,effect:`Setting ${_} creates a new version from it.`}})}if(l&&!await tr(a,w,s))return null;let A={};for(let[y,g]of w.entries()){let _=g.targets.filter(T=>Object.keys(T.changes).length>0);if(_.length===0)continue;let I=g.names.filter(T=>_.some(k=>Object.hasOwn(k.changes,T))),N=`${l?"Removed":"Set"} ${D(I)} ${l?"from":"on"} ${g.shownAs}`;s.emit({type:"step",step:g.step,status:"start",message:l?"Removing...":`Updating ${g.shownAs}...`});let $={};for(let T of _){try{await ot(a,T.workerName,T.changes)}catch(we){let F=Object.values(A).flatMap(L=>L.names);if(F.length===0)throw we;let P=w.slice(y).flatMap(L=>L.names);throw new E("SECRETS_PARTIALLY_APPLIED",[`Couldn't ${l?"remove":"set"} ${D(g.names)} ${l?"from":"on"} ${g.shownAs}`,`Cloudflare said: ${C(we).split(`
39
+ `)[0]}`,`${D(F)} ${F.length===1?"is":"are"} ${l?"removed":"set"}; only ${D(P)} ${P.length===1?"is":"are"} left.`].join(`
40
+ `),{rerun:`${f} secret ${r} ${P.join(" ")}${p&&o.app?.source==="registry"&&P.some(L=>p.names.includes(L))?` --app ${p.manifest.id}`:""}`,retryable:!0,data:{applied:Fe(A),left:P}})}let x=(await Ct(a,T.workerName))?.versionId??null;x&&await T.record(x),$[T.workerName]=x,s.emit({type:"progress",step:"secrets.version",message:`${T.workerName} is now at version ${x??"unknown"}`})}if(g.step==="secrets.gateway"){let T=await Zn(i,I,l,c.actor,s).catch(k=>(s.emit({type:"progress",step:"secrets.pin",message:`Couldn't record which origin ${D(I)} ${I.length===1?"is":"are"} pinned to (${C(k).split(`
41
+ `)[0]}); the Gateway pins it on first use`}),[]));if(A.gateway={names:I,versions:$,...T.length>0?{pinned:T}:{}},!l&&e.providers.length>0&&R){let k=await Ut(i,R,I);k.length>0&&(A.gateway.bound=k,s.emit({type:"progress",step:"secrets.bind",message:`Bound ${D(k)}'s key to the hosts ${k.length===1?"its row names":"their rows name"}`,data:{providers:k}}))}}else A.app={id:p.manifest.id,workerName:p.workerName,names:I,versions:$},await er(a,i,p,s);s.emit({type:"step",step:g.step,status:"ok",message:N,data:{action:r,names:I,versions:$}})}return await Ht({cf:a,db:i,deployer:c},{gateway:A.gateway?.names??[],appRowId:A.app&&p?p.rowId:null,except:n.setupRecordedBy},s),A}finally{await h?.release()}}finally{await S?.release()}}async function Zn(e,t,n,r,s){if(n){for(let i of await Kt(e,t))s.emit({type:"progress",step:"secrets.pin",message:`${i}'s pin to its MCP server's origin is gone`});return[]}let a=await Yt(e,t,r);for(let{name:i,origin:o}of a.bound)s.emit({type:"progress",step:"secrets.pin",message:`${i} is pinned to ${o}`});for(let{name:i,kept:o}of a.undeclared)s.emit({type:"warning",code:"REMOTE_MCP_SECRET_UNDECLARED",step:"secrets.gateway",message:o?`No MCP app declares ${i} now
42
+ It stays pinned to ${o}, where it was set before; the Gateway sends it nowhere else.`:`No MCP app declares ${i}
43
+ The Gateway pins it to the first MCP app that uses it.`,data:{name:i,pinnedTo:o,fix:`${f} mcp add <url> --secret ${i}`}});for(let{name:i,origins:o}of a.ambiguous)s.emit({type:"warning",code:"REMOTE_MCP_SECRET_AMBIGUOUS",step:"secrets.gateway",message:`MCP apps at ${D(o)} all declare ${i}
44
+ It isn't pinned to any of them, so the Gateway sends it to none until one is removed.`,data:{name:i,origins:o,rerun:`${f} mcp list`,rerunNote:"names the apps"}});return a.bound}async function er(e,t,n,r){try{await _t(t,n.rowId,await be(e,n.workerName))}catch(s){r.emit({type:"progress",step:"secrets.record",message:`Couldn't record ${n.manifest.id}'s secret names (${C(s).split(`
45
+ `)[0]}); ${f} status records them`})}}async function tr(e,t,n){let r=!1;for(let s of t.flatMap(a=>a.targets)){let a=await ce(e,s.workerName);for(let i of Object.keys(s.changes)){if(a.includes(i)){r=!0;continue}delete s.changes[i],n.emit({type:"progress",step:"secrets.held",message:`${i} isn't set on ${s.workerName}`})}}return r}function Ge(e,t){return[...e.gateway?[`${D(e.gateway.names)} ${t} the Gateway`]:[],...e.app?[`${D(e.app.names)} ${t} ${e.app.id}`]:[]].join(", and ")}function Fe(e){return{...e.gateway?{gateway:e.gateway}:{},...e.app?{app:e.app}:{}}}export{Ht as a,dr as b,z as c,hr as d,Er as e,Rr as f,Ar as g,_r as h,Nr as i,_n as j,Tr as k,$r as l,Nn as m,kr as n,Dr as o,Yt as p,Gn as q,rn as r,Qt as s,sn as t,ps as u,cs as v,ls as w,Fn as x,Hn as y,ds as z,us as A,qn as B,Vn as C,Yn as D,pn as E,Fe as F};
@@ -0,0 +1,6 @@
1
+ import{h as M,i as G,o as z}from"./chunk-KMAOZRV4.js";import{i as _}from"./chunk-PMPIMHKG.js";import{c as x,d as W}from"./chunk-RFVMR32Y.js";import{c as S}from"./chunk-GRFPP4UW.js";import{b as I}from"./chunk-Y3VIFPN5.js";import{h as O}from"./chunk-EUNGJMJ6.js";import{a as L,j as P,k,l as C}from"./chunk-ZYL2ZHCF.js";import{ib as y,xb as v}from"./chunk-SAT3PGZU.js";async function Oe(e){let{cf:n,out:r,databaseId:a}=e,s=L(n,a),d=await k(s);if(!d)throw P();if(!e.force&&!e.stagedSecrets&&!e.unsetSecrets){let{inSync:g,desired:f}=await Z(n,s,d);if(g)return r.emit({type:"step",step:"gateway.reconcile",status:"skip",message:`The gateway already binds ${f.appWorkers.length===1?"the 1 app":`all ${f.appWorkers.length} apps`} its registry lists.`}),{versionId:d.liveVersionId,firstDeploy:!1,appWorkers:f.appWorkers,domains:d.liveDomains,newHosts:[],changed:!1}}let w=await e.openRelease();try{_(w.manifest,e.cliVersion);let g=await O({db:s,out:r,leaseWaitMs:e.leaseWaitMs,sleep:e.sleep},"gateway.reconcile");try{let f=await k(s)??d;return e.unsetSecrets?.length&&(await g.check(),f=await ee(n,s,f,e.unsetSecrets)),{...await z({cf:n,out:r,reason:"reconcile",release:w,accountId:e.accountId,gatewayHost:f.gatewayHost,zone:{id:f.zoneId,name:f.zoneName},appBaseDomain:f.appBaseDomain,forceDns:e.forceDns,resources:{d1Id:a,oauthKvId:f.oauthKvId,created:[]},db:s,interactive:e.interactive,confirm:e.confirm,cliVersion:e.cliVersion,stagedSecrets:e.stagedSecrets,heldLease:g,sleep:e.sleep}),changed:!0}}finally{await g.release()}}finally{await w.cleanup()}}async function Z(e,n,r){let a=await G(n,M(e));if(!([...r.liveAppWorkers].sort().join(`
2
+ `)===a.appWorkers.join(`
3
+ `))||!X(r,a.appHosts))return{inSync:!1,desired:a};let d=await S(e,y);return{inSync:!!d?.versionId&&d?.versionId===r.liveVersionId,desired:a}}function X(e,n){if(!e.liveDomains.includes(e.gatewayHost))return!1;let r=e.liveDomains.filter(s=>s!==e.gatewayHost),a=x(n,e.appBaseDomain);return[...r].sort().join(`
4
+ `)===[...a].sort().join(`
5
+ `)}async function ee(e,n,r,a){for(let w of a)await I(e,y,w);let s=await S(e,y);if(!s?.versionId||s.versionId===r.liveVersionId)return r;let d={...r,liveVersionId:s.versionId,updatedAt:Date.now()};return await C(n,d),d}import{Agent as ae,fetch as ie}from"undici";import $ from"node:dns";import{isIP as H}from"node:net";var te=["1.1.1.1","1.0.0.1"],ne=2e3,se=2,F=3e3,D=new Set(["ENODATA","ENOTFOUND"]),re={createResolver:e=>{let n=new $.promises.Resolver({timeout:ne,tries:se});return n.setServers(e),n},osLookup:e=>$.promises.lookup(e,{all:!0})};function E(e){return e?.code}function b(e,n){return Object.assign(new Error(n),{code:"ENOTFOUND",hostname:e})}function oe(e=re){let n=new Map,r=new Set,a=new Set,s=new Map,d=new Map,w=te.join(",");function g(t,o){return o.then(i=>(r.add(t),i),i=>{throw D.has(E(i)??"")&&r.add(t),i})}function f(t){if(a.has(t))throw new Error(`${t} didn't answer earlier in this run.`);let o=n.get(t);if(o)return o;let i=e.createResolver(t.split(",")),l={resolveNs:c=>g(t,i.resolveNs(c)),resolve4:c=>g(t,i.resolve4(c)),resolve6:c=>g(t,i.resolve6(c)),resolveSoa:c=>g(t,i.resolveSoa(c)),cancel:()=>i.cancel()};return n.set(t,l),l}async function A(t){let o=d.get(t);if(o)return o;let i=f(w);for(let l of W(t)){if(!s.has(l)){let c;try{c=await i.resolveNs(l)}catch(u){if(D.has(E(u)??""))continue;throw u}if(c.length===0)continue;let m=(await Promise.allSettled(c.map(u=>i.resolve4(u)))).flatMap(u=>u.status==="fulfilled"?u.value:[]);if(m.length===0)throw new Error(`No address for ${l}'s nameservers.`);s.set(l,[...new Set(m)])}return d.set(t,l),l}throw new Error(`No zone found for ${t}.`)}function R(t){let o=d.get(t),i=o&&s.get(o)?.join(",");return i?[w,i]:[w]}async function N(t,o){let i,l=new Promise((p,m)=>{i=setTimeout(()=>{for(let u of R(t))n.get(u)?.cancel();m(new Error(`No answer for ${t} within ${F/1e3} s.`))},F)}),c=(async()=>{let p=await A(t);return o(p,f(s.get(p).join(",")))})();try{return await Promise.race([c,l])}catch(p){for(let m of R(t))r.has(m)||a.add(m);throw p}finally{clearTimeout(i)}}async function J(t,o){let i=await Promise.allSettled([o.resolve4(t),o.resolve6(t)]),l=i.flatMap((p,m)=>p.status==="fulfilled"?p.value.map(u=>({address:u,family:m===0?4:6})):[]);if(l.length>0)return l;let c=i.find(p=>p.status==="rejected"&&!D.has(E(p.reason)??""));if(c?.status==="rejected")throw c.reason;return l}async function K(t){if(H(t))return[{address:t,family:H(t)}];let o;try{o=await N(t,(i,l)=>J(t,l))}catch{return e.osLookup(t)}if(o.length===0)throw b(t,`${t} has no address at its zone's nameservers yet`);return o}let q=(t,o,i)=>{let l=typeof o=="function"?o:i,c=typeof o=="function"?{}:typeof o=="number"?{family:o}:o??{},p=c.family==="IPv4"?4:c.family==="IPv6"?6:c.family??0,m=(...u)=>process.nextTick(()=>l(...u));K(t).then(u=>{let T=p?u.filter(Q=>Q.family===p):u,h=T[0];h?c.all?m(null,T):m(null,h.address,h.family):m(b(t,`${t} has no IPv${p} address`),"")},u=>m(u instanceof Error?u:b(t,String(u)),""))};async function Y(t){try{let o=await N(t,async(i,l)=>(await l.resolveSoa(i)).minttl);return Number.isFinite(o)?o:null}catch{return null}}return{lookup:q,negativeCacheTtlSeconds:Y}}var j=oe(),U=j.lookup,V=j.negativeCacheTtlSeconds;var ce=1e4;function le(e){return/cloudflareaccess\.com|\/cdn-cgi\/access\//i.test(e??"")}var ue=new Set(["ENOTFOUND","EAI_AGAIN","ENODATA"]),de=new Set(["EPROTO","ECONNRESET"]);function pe(e){let n=[];for(let r=e;r!==void 0&&n.length<5;)n.push(r),r=r instanceof Error?r.cause:void 0;return n}function fe(e){let n=pe(e),r=n.map(s=>String(s?.code??"")),a=n.map(v).join(`
6
+ `);return r.some(s=>ue.has(s))||/\b(ENOTFOUND|EAI_AGAIN|ENODATA)\b/.test(a)?"dns":r.some(s=>s.startsWith("ERR_SSL_")||s.startsWith("ERR_TLS_")||de.has(s))||/handshake|alert|certificate/i.test(a)?"tls":"other"}var B,me=(e,n)=>(B??=new ae({connect:{lookup:U}}),ie(e,{...n,dispatcher:B}));function we(e){let n=e instanceof Error&&e.cause instanceof Error?e.cause:e;return v(n)}async function ze(e,n=me,r=ce){try{let a=await n(e,{method:"GET",redirect:"manual",signal:AbortSignal.timeout(r),headers:{"user-agent":"everyapp-cli"}});await a.body?.cancel().catch(()=>{});let s=a.headers.get("location");return{answered:!0,status:a.status,access:a.status>=300&&a.status<400&&le(s)}}catch(a){return{answered:!1,reason:we(a),kind:fe(a)}}}import ge from"node:dns";var je={lookup:e=>ge.promises.lookup(e,{all:!0}),negativeCacheTtlSeconds:V};function ye(e){let n=e?.code??"";return n==="ENOTFOUND"||n==="ENODATA"||n.startsWith("EAI_")}function he(e){if(e===null)return"half an hour";let n=Math.max(1,Math.ceil(e/60));return n===1?"a minute":`${n} minutes`}async function Ue({host:e,lead:n,out:r,step:a,localDns:s}){try{return await s.lookup(e),!1}catch(w){if(!ye(w))return!1}let d=await s.negativeCacheTtlSeconds(e).catch(()=>null);return r.emit({type:"warning",code:"LOCAL_DNS_STALE",step:a,message:`${n}, but this computer's DNS resolver, or this network's, still remembers ${e} as missing from before it existed. That clears by itself within ${he(d)}; a browser with its own DNS, such as Chrome, works now. On macOS, \`sudo dscacheutil -flushcache; sudo killall -HUP mDNSResponder\` clears this computer's own cache, but not the network's.`,data:{host:e,negativeCacheTtlSeconds:d}}),!0}export{Oe as a,Z as b,ze as c,je as d,Ue as e};
@@ -0,0 +1 @@
1
+ import{z as t}from"zod";var a=t.array(t.looseObject({name:t.string(),status:t.string()})),c=t.looseObject({authenticated:t.boolean(),authSource:t.string().nullish(),tokenValid:t.boolean().nullish(),email:t.string().nullish(),accounts:t.array(t.looseObject({id:t.string(),name:t.string().nullish()})).nullish()}),o=t.looseObject({uuid:t.string(),name:t.string()}),p=t.array(o),g=t.array(t.looseObject({Name:t.string()})),e=t.looseObject({duration:t.number().nullish(),changes:t.number().nullish()}).nullish(),O=t.array(t.looseObject({results:t.array(t.record(t.string(),t.unknown())).nullish(),success:t.boolean().nullish(),meta:e})),h=t.looseObject({bookmark:t.string()}),y=t.looseObject({previous_bookmark:t.string().nullish()}),n=t.looseObject({id:t.string(),title:t.string()}),b=t.array(n),r=t.looseObject({id:t.string().nullish(),created_on:t.string().nullish(),versions:t.array(t.looseObject({version_id:t.string(),percentage:t.number()}))}),m=t.union([t.looseObject({deployments:t.array(r)}),t.array(r)]).transform(s=>Array.isArray(s)?s:s.deployments),d=t.array(t.looseObject({id:t.string().nullish(),name:t.string(),references:t.looseObject({domains:t.array(t.looseObject({id:t.string().nullish(),hostname:t.string(),zone_id:t.string().nullish(),zone_name:t.string().nullish()})).nullish()}).nullish()})),j=t.looseObject({buckets:t.array(t.looseObject({name:t.string()})).nullish()}).transform(s=>s.buckets??[]),x=t.union([t.looseObject({result:t.array(t.looseObject({name:t.string()}))}),t.array(t.looseObject({name:t.string()}))]).transform(s=>Array.isArray(s)?s:s.result),f=t.array(t.looseObject({id:t.string(),name:t.string(),status:t.string().nullish()})),k=t.array(t.looseObject({id:t.string(),name:t.string(),type:t.string(),content:t.string().nullish()})),D=t.array(t.looseObject({id:t.string(),type:t.string().nullish(),hosts:t.array(t.string()).nullish(),status:t.string().nullish()})),i=t.looseObject({name:t.string(),script_name:t.string().nullish(),class_name:t.string().nullish(),instances:t.record(t.string(),t.number()).nullish()}),L=t.array(i),W=t.array(t.looseObject({results:t.looseObject({columns:t.array(t.string()).nullish(),rows:t.array(t.array(t.unknown())).nullish()}).nullish(),meta:e})),l=t.looseObject({id:t.string(),name:t.string(),origin:t.looseObject({host:t.string().nullish(),port:t.number().nullish(),database:t.string().nullish(),user:t.string().nullish(),scheme:t.string().nullish()}).nullish(),caching:t.looseObject({disabled:t.boolean().nullish()}).nullish()}),w=t.array(l);export{a,c as b,o as c,p as d,g as e,O as f,h as g,y as h,n as i,b as j,m as k,d as l,j as m,x as n,f as o,k as p,D as q,i as r,L as s,W as t,l as u,w as v};