everyapp 0.3.0-rc.2 → 0.3.0-rc.4
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.
- package/README.md +1 -1
- package/dist/access-YWM4BSBD.js +1 -0
- package/dist/activity-RTCAUMQS.js +14 -0
- package/dist/ai-UOYQFTAX.js +5 -0
- package/dist/apps-PEOBCDNU.js +14 -0
- package/dist/chunk-26KS6TD6.js +1 -0
- package/dist/chunk-3EADVHFN.js +15 -0
- package/dist/chunk-4LKLQOM7.js +7 -0
- package/dist/{chunk-PNLU5U3P.js → chunk-5IC3ZN52.js} +1 -1
- package/dist/{chunk-H7PDL3X5.js → chunk-AMCNAKYU.js} +1 -1
- package/dist/{chunk-23HJ5I2A.js → chunk-ASCNE7GS.js} +1 -1
- package/dist/{chunk-6OGVO7QK.js → chunk-BCTEWNN4.js} +1 -1
- package/dist/{chunk-W3JCQHHU.js → chunk-BK4NK34C.js} +1 -1
- package/dist/chunk-BWNZ6F4F.js +2 -0
- package/dist/chunk-DCFHBCCW.js +9 -0
- package/dist/{chunk-2Y5Q6A5K.js → chunk-DWTJ4OLZ.js} +1 -1
- package/dist/chunk-EP3IQ354.js +20 -0
- package/dist/{chunk-OP4DYXYI.js → chunk-EP4HRYXP.js} +1 -1
- package/dist/{chunk-HOUHG236.js → chunk-EQLY5I46.js} +1 -1
- package/dist/{chunk-YHJZMJYZ.js → chunk-F5XK23HV.js} +1 -1
- package/dist/{chunk-5PTNYZK6.js → chunk-FB2OC32C.js} +3 -3
- package/dist/chunk-FQ2A7YAP.js +57 -0
- package/dist/{chunk-OM2HDWVP.js → chunk-GAPQSINH.js} +1 -1
- package/dist/chunk-GJK6GAWO.js +1 -0
- package/dist/chunk-H4EZTXIK.js +1 -0
- package/dist/chunk-HJGZGZFE.js +32 -0
- package/dist/{chunk-CCWBPAKH.js → chunk-I7FNTTUY.js} +3 -3
- package/dist/chunk-KOBKGQ27.js +91 -0
- package/dist/{chunk-PS7S74DG.js → chunk-KQM6ZUX5.js} +1 -1
- package/dist/chunk-KVCL64LI.js +1 -0
- package/dist/{chunk-4JRIS6S6.js → chunk-LEEUODYR.js} +1 -1
- package/dist/{chunk-6PGUCTJ6.js → chunk-LI3YLKLC.js} +1 -1
- package/dist/chunk-MEIWV7FJ.js +20 -0
- package/dist/{configure-F7UZCJUG.js → chunk-MLTNW3AM.js} +2 -2
- package/dist/chunk-NDOEON54.js +4 -0
- package/dist/chunk-NW7SJPSP.js +37 -0
- package/dist/chunk-O64FPLGX.js +1 -0
- package/dist/chunk-ORGV2NNT.js +8 -0
- package/dist/chunk-PDPUGYJW.js +47 -0
- package/dist/chunk-QFTBDXLF.js +146 -0
- package/dist/{chunk-E3EPK27P.js → chunk-QJRZFIYC.js} +2 -2
- package/dist/chunk-QKHLRLK3.js +15 -0
- package/dist/{chunk-CZXHKPRZ.js → chunk-R2DF3ENZ.js} +1 -1
- package/dist/{chunk-IUOBIB5M.js → chunk-R7JOHK7Y.js} +2 -2
- package/dist/chunk-RL72BUT4.js +1 -0
- package/dist/chunk-RQBSTNL7.js +1 -0
- package/dist/{chunk-H6QQMY7B.js → chunk-S2G4G73L.js} +1 -1
- package/dist/{chunk-LXYMDZER.js → chunk-SGRGD7L4.js} +1 -1
- package/dist/{chunk-T2GD7RHS.js → chunk-TIYSZWP5.js} +1 -1
- package/dist/chunk-TUXKBLLJ.js +10 -0
- package/dist/chunk-U4ATZJEU.js +6 -0
- package/dist/chunk-V7BWZOSZ.js +26 -0
- package/dist/{chunk-J35DDCNU.js → chunk-VVKQJSF3.js} +1 -1
- package/dist/chunk-WVHJIYQ3.js +14 -0
- package/dist/{chunk-ZEXVHB22.js → chunk-XBD7PQN5.js} +1 -1
- package/dist/{chunk-N5GQLGEC.js → chunk-YAZHTVUV.js} +1 -1
- package/dist/configure-CAWCTPYY.js +1 -0
- package/dist/{create-2E5HVWYK.js → create-3ZWJQXPK.js} +2 -2
- package/dist/{db-HEQVTDTM.js → db-B7KO37SV.js} +1 -1
- package/dist/delete-CB3EPOU4.js +3 -0
- package/dist/deploy-5O7LV5OX.js +1 -0
- package/dist/dev-4JYCVVOZ.js +86 -0
- package/dist/{email-RLZFUFUN.js → email-SWJQXEUR.js} +1 -1
- package/dist/{events-2V5VRBWP.js → events-GJV2KVIU.js} +13 -13
- package/dist/{groups-HDG5DVFY.js → groups-NNTLSXMK.js} +1 -1
- package/dist/index.js +104 -95
- package/dist/install-UAG3CNYW.js +1 -0
- package/dist/{login-KHJBC64Z.js → login-QEKMLMUB.js} +1 -1
- package/dist/mcp-AFGVOM5D.js +1 -0
- package/dist/provider-622VM7UZ.js +29 -0
- package/dist/release-CXEX6O7F.js +1 -0
- package/dist/{restore-FFGYV7NO.js → restore-PGIVEA5P.js} +1 -1
- package/dist/secret-3LUDEDUW.js +1 -0
- package/dist/setup-PUD375AM.js +1 -0
- package/dist/{signin-AP3D4XM4.js → signin-EP5JLAT5.js} +2 -2
- package/dist/status-LK6DNLCI.js +5 -0
- package/dist/teardown-6RURRSME.js +22 -0
- package/dist/update-YJFTOZEV.js +1 -0
- package/dist/{workspace-CJC5I66L.js → workspace-VW7ZZRFP.js} +3 -3
- package/package.json +5 -5
- package/skills/build-every-app/SKILL.md +22 -13
- package/skills/build-every-app/patterns.md +16 -3
- package/skills/everyapp/SKILL.md +33 -18
- package/skills/everyapp/mcp.md +22 -8
- package/skills/everyapp/security-review.md +1 -1
- package/skills/everyapp/setup/README.md +18 -1
- package/skills/everyapp/setup/access.md +11 -7
- package/skills/everyapp/setup/ai-gateway.md +117 -0
- package/skills/everyapp/setup/ai.md +139 -0
- package/skills/everyapp/setup/context.md +2 -2
- package/skills/everyapp/setup/dataforseo.md +3 -3
- package/skills/everyapp/setup/email.md +1 -1
- package/skills/everyapp/setup/gateway.md +3 -3
- package/skills/everyapp/setup/google.md +8 -6
- package/skills/everyapp/setup/microsoft-365.md +4 -2
- package/skills/everyapp/setup/providers.md +27 -9
- package/skills/everyapp/setup/remote-mcp.md +1 -1
- package/skills/everyapp/setup/signin-apple.md +3 -3
- package/skills/everyapp/setup/signin-cloudflare.md +1 -1
- package/skills/everyapp/setup/signin-github.md +1 -1
- package/skills/everyapp/setup/signin-google.md +2 -2
- package/skills/everyapp/setup/signin-microsoft.md +1 -1
- package/skills/everyapp/setup/slack.md +2 -0
- package/dist/access-LGEN3ABJ.js +0 -1
- package/dist/activity-RSD4D66F.js +0 -12
- package/dist/apps-4RCFXT74.js +0 -13
- package/dist/chunk-AGTCKFRB.js +0 -22
- package/dist/chunk-BHMRY53V.js +0 -2
- package/dist/chunk-CB4U7H2G.js +0 -4
- package/dist/chunk-CZTEDWZ2.js +0 -22
- package/dist/chunk-EGEWRFVY.js +0 -1
- package/dist/chunk-ELK7QZ2M.js +0 -1
- package/dist/chunk-FJJSSVET.js +0 -33
- package/dist/chunk-GKBPYVP3.js +0 -25
- package/dist/chunk-IFCPALVC.js +0 -46
- package/dist/chunk-J455FAEN.js +0 -7
- package/dist/chunk-JYKRUS5C.js +0 -1
- package/dist/chunk-LYNBZ7RV.js +0 -57
- package/dist/chunk-M2QQ2UD7.js +0 -132
- package/dist/chunk-NFU4YFXB.js +0 -1
- package/dist/chunk-ONLNJXVQ.js +0 -32
- package/dist/chunk-RMF4YGD6.js +0 -98
- package/dist/chunk-TLRM3P7V.js +0 -15
- package/dist/chunk-WOVS3GV5.js +0 -10
- package/dist/chunk-ZECBN24L.js +0 -15
- package/dist/chunk-ZFCUH5PK.js +0 -7
- package/dist/delete-XCSIQIRS.js +0 -3
- package/dist/deploy-3QOZEZHC.js +0 -1
- package/dist/dev-JL3ZP5BT.js +0 -86
- package/dist/install-Z5FYXUYM.js +0 -1
- package/dist/mcp-EFDUKJ5V.js +0 -1
- package/dist/provider-EOI5PTFH.js +0 -13
- package/dist/release-74J5ZIL3.js +0 -1
- package/dist/secret-7FKKTLHB.js +0 -1
- package/dist/setup-PAKRCAFO.js +0 -1
- package/dist/status-RMWNHOEK.js +0 -4
- package/dist/teardown-E4JNKAZJ.js +0 -22
- package/dist/update-DWVZFNPS.js +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
import{a as d}from"./chunk-
|
|
1
|
+
import{a as d}from"./chunk-LEEUODYR.js";import{Fa as u,G as p,Ga as g,Ha as S,Hb as m,Rc as c,c as l,ga as f}from"./chunk-FQ2A7YAP.js";import a from"chalk";function $(e){return d(e,m)}async function C(e,n){return(await d(e,n)).filter(t=>!f(t))}function w(e,n=p){let t=n.unboundSettings?.();return t&&t.size>0?e.filter(r=>!t.has(r)):[...e]}function I(e){let n=e.lookup??p,t=e.gatewayNames===null?null:w(e.gatewayNames,n),r=g(u(e.manifest,n),(o,i)=>{let s=o==="gateway"?t:e.secretNames;return s===null?null:s.includes(i)});return{report:r,setup:S(r,{cli:l,appId:e.appId})}}function M(e,n=p){return u(e,n).some(t=>t.names.length>0)}function P(e,n=p){let t=new Set;for(let r of u(e,n))if(r.holder==="gateway")for(let o of[...r.names,...r.alsoReads])t.add(o);return[...t]}function O(e,n){let t=new Map,r=(o,i)=>{let s=t.get(o);s?s.required||=i:t.set(o,{name:o,required:i,set:n.includes(o)})};for(let o of e)if(o.holder==="gateway"){for(let i of o.names)r(i,o.need.kind!=="optional");for(let i of o.alsoReads)r(i,!1)}return[...t.values()]}function W(e,n){return e.filter(t=>t.holder==="gateway"&&t.blocking).flatMap(t=>t.names).filter((t,r,o)=>!n.includes(t)&&o.indexOf(t)===r)}var y=`${a.yellow("!")} not set`;function k(e){if(e.set===!0)return`${a.green("\u2713")} set`;if(e.set===null)return e.holder==="app"?`${a.yellow("!")} not recorded`:`${a.yellow("!")} couldn't check`;switch(e.need.kind){case"required":return y;case"optional":return a.dim("not set (optional)");case"anyOf":return e.blocking?y:a.dim(`not set (one of: ${e.need.group})`)}}function h(e){return e.names.join("+")}function A(e,n){return n.filter(t=>t.names.length>0).map(t=>({app:e,setting:h(t),where:t.holder==="gateway"?"Gateway":e,status:k(t)}))}function U(e,n,t){return A(e,t.filter(r=>r.holder==="app")).map(r=>({...r,where:`${n} helper`}))}function _(e,{app:n=!0}={}){return n?c(["APP","SETTING","WHERE","STATUS"],e.map(t=>[t.app,t.setting,t.where,t.status])):c(["SETTING","WHERE","STATUS"],e.map(t=>[t.setting,t.where,t.status]))}function b(e){let n=e.names.join(" and "),t=e.why??(e.label===n?void 0:n);return[t?`${e.label}: ${t}`:e.label,...e.hint?[e.hint]:[],...e.docs?[`Get it at ${e.docs}`]:[]]}var R=".claude/skills/everyapp";function N(e){return e.setup?`Guide: ${R}/${e.setup}`:e.kind==="capability"||e.kind==="provider"?`Guide: ${l} provider show ${e.id}`:null}function q(e){let n=new Set;return e.flatMap(t=>{let r=b(t),o=N(t);return!o||n.has(o)?r:(n.add(o),[...r,o])})}function j(e){let n=[],t=r=>{for(let o of r.names)n.includes(o)||n.push(o)};for(let r of e.unmet)r.need.kind==="required"&&t(r);for(let r of e.groups){if(r.met)continue;let o=e.unmet.find(i=>i.id===r.members[0]);o&&t(o)}return n}export{$ as a,C as b,w as c,I as d,M as e,P as f,O as g,W as h,k as i,A as j,U as k,_ as l,b as m,R as n,N as o,q as p,j as q};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{C as x,D as l,r as g,s as m,u as f,v as y,w as p,x as C,y as d,z as S}from"./chunk-RQBSTNL7.js";import{Dc as n,Ec as c,hc as u}from"./chunk-FQ2A7YAP.js";var v=20,w=10;async function P(e){let r=new Map;for(let t=1;t<=w;t+=1){let o=await n(e,{plane:"account",args:["hyperdrive","list","--per-page",String(v),"--page",String(t)]},y),i=r.size;for(let s of o)r.set(s.id,s);if(o.length<v||r.size===i)break}return[...r.values()]}async function O(e,r){return(await P(e)).find(t=>t.name===r)??null}async function Q(e,r,t,o="off"){return(await n(e,{plane:"account",files:{"hyperdrive.json":{name:r,origin:t,...o==="off"?{caching:{disabled:!0}}:{}}},args:s=>["hyperdrive","create","--body",`@${s["hyperdrive.json"]}`]},f)).id}async function j(e,r,t){let o={...t.origin?{origin:t.origin}:{},...t.caching?{caching:{disabled:t.caching==="off"}}:{}};await n(e,{plane:"account",files:{"hyperdrive.json":o},args:i=>["hyperdrive","update",r,"--body",`@${i["hyperdrive.json"]}`]},f)}async function k(e,r){await e.run({plane:"account",mode:"json",args:["hyperdrive","delete",r,"--force"]})}function I(e,r){return e.caching?.disabled===!0==(r==="off")}function q(e,r){let t=e.origin;return t?.host===r.host&&(t.port??null)===r.port&&t.database===r.database&&t.user===r.user}function J(e){return n(e,{plane:"account",args:["queues","list"]},C)}async function G(e,r){try{return await n(e,{plane:"account",args:["queues","get",r]},p)}catch(t){if(u(t,"not_found"))return null;throw t}}async function M(e,r){return(await n(e,{plane:"account",args:["queues","create","--queue-name",r]},p)).queue_id}async function T(e,r){await e.run({plane:"account",mode:"json",args:["queues","delete",r,"--force"]})}async function X(e,r,t){await e.run({plane:"account",mode:"json",args:["queues","consumers","delete",t,"--queue-id",r,"--force"]})}var R="everyapp";function N(e){return c(e,["secrets-store","stores","list"],x,{perPage:100,maxPages:10})}function B(e){return e.find(r=>r.name===R)??e[0]??null}function h(e,r,t){return c(e,["secrets-store","secrets","list","--store-id",r,"--search",t],l,{perPage:100,maxPages:10})}async function K(e,r,t){return(await h(e,r,t)).find(o=>o.name===t&&o.status!=="deleted")??null}async function U(e,r,t,o){let i=await n(e,{plane:"account",files:{"secret.json":[{name:t,value:o,scopes:["workers"],comment:"Created by everyapp deploy"}]},args:a=>["secrets-store","secrets","create",r,"--body",`@${a["secret.json"]}`]},l),s=i.find(a=>a.name===t)??i[0];if(!s)throw new Error(`cf created no Secrets Store secret named ${t}`);return s.id}async function Y(e,r,t){await e.run({plane:"account",mode:"json",args:["secrets-store","secrets","delete",t,"--store-id",r,"--force"]})}async function oe(e,r){try{return await n(e,{plane:"account",args:["vectorize","get",r]},d)}catch(t){if(u(t,"not_found"))return null;throw t}}function ie(e){return n(e,{plane:"account",args:["vectorize","list"]},S)}async function se(e,r,t){return n(e,{plane:"account",files:{"vectorize.json":{name:r,config:t}},args:o=>["vectorize","create","--body",`@${o["vectorize.json"]}`]},d)}async function ue(e,r){await e.run({plane:"account",mode:"json",args:["vectorize","delete",r,"--force"]})}function ce(e,r){let t=e.config??{};return"preset"in r?t.preset===r.preset:t.dimensions===r.dimensions&&t.metric===r.metric}function ae(e){if("preset"in e&&e.preset)return`the preset ${e.preset}`;let r="dimensions"in e?e.dimensions:void 0,t="metric"in e?e.metric:void 0;return`${r??"?"} dimensions, ${t??"no metric"}`}var z=100,b=50;async function ge(e,r){try{return await n(e,{plane:"account",args:["workflows","get",r]},g)}catch(t){if(u(t,"not_found"))return null;throw t}}function me(e,r){return c(e,["workflows","list","--search",r],m,{perPage:z,maxPages:b})}async function H(e,r){await e.run({plane:"account",mode:"json",args:["workflows","delete",r,"--force"]})}async function ye(e,r){try{return await H(e,r),!0}catch(t){if(u(t,"not_found"))return!1;throw t}}export{P as a,O as b,Q as c,j as d,k as e,I as f,q as g,J as h,G as i,M as j,T as k,X as l,N as m,B as n,h as o,K as p,U as q,Y as r,oe as s,ie as t,se as u,ue as v,ce as w,ae as x,ge as y,me as z,ye as A};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{j as m,k as d}from"./chunk-QFTBDXLF.js";import{c as l,e as p}from"./chunk-DCFHBCCW.js";import{a as i}from"./chunk-I7FNTTUY.js";import{bc as o}from"./chunk-FQ2A7YAP.js";import s from"chalk";async function b(e){let{flags:t,out:r,createCf:n}=e,a=await p({gateway:l(t.gateway),accountId:t["account-id"],interactive:i(t.json??!1),login:{json:t.json,out:r,step:"login"},createCf:n}),g=await m(a.db,a.deployer,{org:t.org,now:e.now?.()});return{gateway:a,ws:g,gatewayUrl:a.gatewayUrl}}function x(e){return e.interactive??i(e.flags.json??!1)}async function W(e,t){try{let r=await d(e,t);return{id:r.id,email:r.email,member:!0}}catch(r){if(!(r instanceof o)||r.code!=="USER_NOT_FOUND"||t.includes("@"))throw r;return{id:t.trim(),email:null,member:!1}}}var v=e=>e.member?e.email??e.id:`${e.id} (no longer a member)`;function F(e){return e===null?s.dim("never"):new Date(e).toISOString().slice(0,16).replace("T"," ")}var c=e=>e===null?null:new Date(e).toISOString();function C(e){return e.deactivated?s.yellow("deactivated"):s.green("active")}function h(e){return{id:e.id,email:e.email,name:e.name,role:e.primaryRole??e.role,deactivated:e.deactivated,createdAt:c(e.createdAt)}}function O(e){return{id:e.id,email:e.email,role:e.role,status:e.status,expiresAt:c(e.expiresAt),expired:!e.live&&e.status==="pending",createdAt:c(e.createdAt)}}function A(e){let{add:t,remove:r,set:n}=e;if(n&&(t||r))throw new o("FLAGS_CONFLICT","--set replaces the whole list: give it alone, or --add and --remove without it");return!t&&!r&&!n?{change:null}:{change:{add:t,remove:r,set:n}}}export{b as a,x as b,W as c,v as d,F as e,c as f,C as g,h,O as i,A as j};
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import{createHash as l,createHmac as N}from"node:crypto";var u="https://gateway.dev.localhost";var m=`-----BEGIN PRIVATE KEY-----
|
|
2
|
+
MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQCHjTNZ/5Aresl0
|
|
3
|
+
xM2jL5cX2LJ1XmtpZJ4S3gNfJ5j3xzwhkdGPLZRdpph6PB55tGy/0DP5tm4vdx8n
|
|
4
|
+
QTuk4Z3hUI6JIbUGMmCWZMLXCFXgx3qqEsNU4/qLO1QlLEPCeVHzlS07I0ngbl1h
|
|
5
|
+
jpGsBaU8wxc9Jh0ZaoA/iflBcDD7u5MWYkx1bLVbwottOP/81IafcMKb4RkkgLyr
|
|
6
|
+
3IOExJwzR6MmcFUKiW+nhPyTx23aRga7ZZ3t0Iyse/+XFSioPnxq+l0w7Ntpm3Cx
|
|
7
|
+
DsEBohqYh5DUArGacKPWenbe5a9hCahpmhy+6ktIAsrt9YZTJUNn5Fbge03kqrNn
|
|
8
|
+
Kl+LJnyRAgMBAAECggEABCi9GAB3URw3APgWarDHwS2vGRqU72KM1p2dCx8FCqpA
|
|
9
|
+
cjO+Ezd171Mwp8R/N2MFuLN32sxCEH8GU88kuDwLevm8q+C+xBJI5ChykYRCFU/t
|
|
10
|
+
l7kUaP8HRZ0kCXF0oUuVbATKYt+D8WjVgOwt1FJGhgki5geMukZKKdjvDtbVS+4D
|
|
11
|
+
qGRBV4/XT4Y5JDNrjnITwSV2xfMD6Yd92/NN375+V9vWFI4kaESPbE/YQ7yF1o66
|
|
12
|
+
DfhjRMSMmTgWEeoVDwFMlnXppo1nkdEXY8MXlgho0mDGre4PurAvQmZRYlU6VJ63
|
|
13
|
+
x7/NTaNPnQEJ7+FkUXvtOz8sCBjLzgtilGnBNwGqeQKBgQC7zA7kojSPYvlm7nbC
|
|
14
|
+
L2kO8iAL3p/B1vtS6XLTFiV0Wv2kT6Cy51ulVteUijwGMrDuCMdBqXfIocQvYhls
|
|
15
|
+
JzPR/DaFcE2qClCei9L4wxvdBLcqoQH7LsllGA9oHSoZNnzT0muNech0xuL75X6B
|
|
16
|
+
LLMpVtOyb/prd8N6hhBlcGElCQKBgQC4x8A9aDnFlcyztcutW2YQMfEyDEK+PcuC
|
|
17
|
+
n6cnSJ8MjmFEyulKZuklqKkhwMiNBm8xNhI6UdUtrFPfKmGqYifjEUX4D6xGLL8b
|
|
18
|
+
LNOZojkMAI3jtuD+IGzlpkSCy2TWXVb53TTi82LUD7Sbb5siYhL5uW0IRzbJt1aR
|
|
19
|
+
n2JNphvFSQKBgA1NPNjQ7GwjlIrH5T2H4ice20o78JDoS1DqHCn7bZe6QjD7OuSx
|
|
20
|
+
Inqplgd9axb9TC7wDD0IZeWeH6lDh41zkWYUOUBmXfnnVSKFwOHB4B1dkiPA18UU
|
|
21
|
+
4Ur5002Kk0rJ4zmVs+yHbb1nwPgan0VDB0WsUr5W1CP8jaoGCO9GcHsRAoGAX6Xm
|
|
22
|
+
eOLupLx6DbxZBg99sXxoocN++QL7yU3jNI5+5fz9lKKESCMlJH09r18fcQCXph2b
|
|
23
|
+
Kd0aQF4nvCkwDQZqJzvVwCY8wsZ+1g5KKgizBudyiyErLeCS/f0nEZ0/QUdnskcz
|
|
24
|
+
DRd3XNYUYzFOWGnz8JhvPA3A6oGgqhiaxh7p2SECgYA+7s6WRfQLSad3dXuDNajQ
|
|
25
|
+
sBwG4E6M/yUbgdbNjnv+AuVYS8Uyvf6x/xaWH3zssluIXhod0Two22bjtkPGJ2nx
|
|
26
|
+
1ZXmbxSdWVGwLZn3GYRoRu6X6VGTbFAaK1mb7KDfwjoaauV7G3A2mw6M5xxg4zx/
|
|
27
|
+
hsbx0DA4sMMIUEniw9W/YA==
|
|
28
|
+
-----END PRIVATE KEY-----
|
|
29
|
+
`;var s=Object.freeze({workerName:"every-hosted--sentinel",organizationId:"everyapp-hosted-deploy-sentinel",accountId:"every-hosted--sentinel-account",gatewayUrl:"https://every-hosted--sentinel.invalid",publicKey:`-----BEGIN PUBLIC KEY-----
|
|
30
|
+
EVERYAPPHOSTEDDEPLOYSENTINEL
|
|
31
|
+
-----END PUBLIC KEY-----
|
|
32
|
+
`});function i(n){return`${s.workerName}--${n}`}function a(n,r){return`https://gateway.ai.cloudflare.com/v1/${n}/${r}`}function E(n){let r=(e,d)=>Object.fromEntries((e??[]).map(o=>[o,d(i(o))])),{resources:t}=n;return{workerName:s.workerName,organizationId:s.organizationId,accountId:s.accountId,gatewayUrl:s.gatewayUrl,identityPublicKeys:[s.publicKey],resources:{d1:r(t?.d1,e=>({name:e,id:e})),kv:r(t?.kv,e=>({id:e})),hyperdrive:r(t?.hyperdrive?.map(e=>e.name),e=>({id:e})),r2:r(t?.r2,e=>({name:e})),...t?.queues?.length?{queues:r(t.queues.map(e=>e.name),e=>({name:e,id:e}))}:{},vectorize:r(t?.vectorize?.map(e=>e.name),e=>({name:e})),aiGateway:r(t?.aiGateway?.map(e=>e.name),e=>({id:e,accountId:s.accountId,url:a(s.accountId,e)})),secretsStore:r(t?.secretsStore?.map(e=>e.name),e=>({storeId:e,secretName:e}))}}}var _=Object.freeze({enabled:!0,headSamplingRate:1,redactQueryString:!0,logs:Object.freeze({enabled:!0,invocationLogs:!0,persist:!0,headSamplingRate:1}),traces:Object.freeze({enabled:!0,persist:!0,headSamplingRate:.1}),issues:Object.freeze({enabled:!0})});var c=63;function I(n,r){let t=`${n}--${r}`;if(t.length>c)throw new Error(`Helper Worker ${t} is longer than Cloudflare's ${c} characters; shorten its name in everyapp.config.ts.`);return t}function A(n,r){return`${n}--${r.toLowerCase().replaceAll("_","-")}`}function f(n,r){return l("sha256").update(`${n}:${r}`).digest("hex").slice(0,32)}export{u as a,m as b,s as c,i as d,a as e,E as f,_ as g,I as h,A as i,f as j};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{
|
|
1
|
+
import{bc as g,dc as m,lc as d}from"./chunk-FQ2A7YAP.js";import{confirm as p,input as u,password as y,select as h}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
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=>
|
|
4
|
-
`)}async function R({yes:e,interactive:r,confirm:n=T,question:s,unattended:i,context:o,cancelled:
|
|
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=>p({message:e,default:!1,theme:a},n)),C=(e,r)=>l({context:r},n=>p({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=>h({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=>y({message:e,mask:"\u2022",toggleMask:!1,validate:i=>(n=i,i.trim()||r.optional?!0:"Enter a value."),theme:{...a,style:{...a.style,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:f,data:c}){if(!e){if(!r)throw new g("CONFIRMATION_REQUIRED",i,c?{data:c}:{});await w(n,s,{context:o,cancelled:f})}}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,91 @@
|
|
|
1
|
+
import{a as ve,b as q,e as _,f as A,g as Se,h as Ae,i as Ie,j as Oe,k as ke,l as Le}from"./chunk-RL72BUT4.js";import{a as _e,c as Ee,d as fe,e as ye,f as we,g as De,h as be,i as he,j as Te}from"./chunk-RQBSTNL7.js";import{$a as M,Dc as g,Ec as ge,Jc as Ne,Ka as C,Lc as Re,Ma as b,Xa as P,Za as oe,_a as x,ab as z,bb as U,bc as o,c as p,db as $,e as ie,eb as W,gb as le,ha as se,hc as ce,i as N,ib as de,jb as pe,kb as ue,tc as me}from"./chunk-FQ2A7YAP.js";import Ce from"node:path";function sn(e,t){return{run:async(a,n)=>(await _t(e,t,a,n)).map(r=>r.rows)}}var gt=6e5;function on(e){let[,t=e,a]=/^([\s\S]*?)(?::\s*(SQLITE_[A-Z_]+))?(?:\s*\[code: \d+\])?$/.exec(e.trim())??[];return{problem:t,...a?{sqliteCode:a}:{}}}async function _t(e,t,a,{timeoutMs:n}={}){let r=a.length===1?a[0]:{batch:a};return(await g(e,{plane:"account",...n?{timeoutMs:n}:{},args:s=>["d1","query",t,"--body",`@${s["query.json"]}`],files:{"query.json":r}},we)).map(s=>({rows:s.results??[],duration:s.meta?.duration??0,changes:s.meta?.changes??0}))}async function ln(e,t){let{bookmark:a}=await g(e,{plane:"account",args:["d1","time-travel","get-bookmark",t]},De);return a}async function dn(e,t,a){await g(e,{plane:"account",args:["d1","time-travel","restore",t,"--bookmark",a,"--force"]},be)}function pn(e,t,a,{platform:n=process.platform,shell:r=process.env.SHELL}={}){let i=`npx cf@${me} d1 time-travel restore ${e} --bookmark ${t} --force`;return a?n==="win32"&&!r?`$env:CLOUDFLARE_ACCOUNT_ID="${a}"; ${i}`:`CLOUDFLARE_ACCOUNT_ID=${a} ${i}`:i}function Pe(e,t){let a=Ce.resolve(e);return["--dir",a,...t?["--pattern",Ce.join(a,"*","migration.sql")]:[]]}async function un({cf:e,databaseId:t,dir:a,nested:n=!1}){return(await g(e,{plane:"account",args:["d1","migrations","list",t,...Pe(a,n)]},ye)).map(i=>i.Name)}async function cn({cf:e,databaseId:t,dir:a,nested:n=!1}){let r=await g(e,{plane:"account",timeoutMs:gt,args:["d1","migrations","apply",t,...Pe(a,n)]},_e),i=r.filter(s=>s.status!=="\u2705");if(i.length>0)throw new Error(`cf reported ${i.map(s=>`${s.name} ${s.status}`).join(", ")} (applying ${r.map(s=>s.name).join(", ")}).`);return r.map(s=>s.name)}import{generateKeyPairSync as Et,randomBytes as ft}from"node:crypto";var xe=["self_hosted","hosted"];function _n({gatewayUrl:e,accountId:t,deploymentMode:a}){let{privateKey:n,publicKey:r}=Et("rsa",{modulusLength:2048,publicKeyEncoding:{type:"spki",format:"pem"},privateKeyEncoding:{type:"pkcs8",format:"pem"}});return{secrets:{GATEWAY_URL:e,BETTER_AUTH_SECRET:ft(32).toString("base64"),JWT_PRIVATE_KEY:n,JWT_PUBLIC_KEY:r,GATEWAY_DEPLOYMENT_MODE:a,CLOUDFLARE_ACCOUNT_ID:t},jwtPublicKey:r}}var yt=`CREATE TABLE IF NOT EXISTS _everyapp_install (
|
|
2
|
+
id TEXT PRIMARY KEY CHECK (id = 'install'),
|
|
3
|
+
account_id TEXT NOT NULL,
|
|
4
|
+
zone_id TEXT NOT NULL,
|
|
5
|
+
zone_name TEXT NOT NULL,
|
|
6
|
+
gateway_host TEXT NOT NULL,
|
|
7
|
+
app_base_domain TEXT NOT NULL,
|
|
8
|
+
oauth_kv_id TEXT NOT NULL,
|
|
9
|
+
release_version TEXT NOT NULL,
|
|
10
|
+
release_sha256 TEXT NOT NULL,
|
|
11
|
+
release_schema INTEGER NOT NULL,
|
|
12
|
+
release_committed_at INTEGER NOT NULL,
|
|
13
|
+
source_tree_sha256 TEXT,
|
|
14
|
+
live_version_id TEXT,
|
|
15
|
+
live_domains TEXT NOT NULL DEFAULT '[]',
|
|
16
|
+
live_app_workers TEXT NOT NULL DEFAULT '[]',
|
|
17
|
+
updated_at INTEGER NOT NULL,
|
|
18
|
+
updated_by TEXT,
|
|
19
|
+
jwt_public_key TEXT,
|
|
20
|
+
deployment_mode TEXT
|
|
21
|
+
)`;function Me(e){try{let t=JSON.parse(String(e??"[]"));return Array.isArray(t)?t.map(String):[]}catch{return[]}}var wt=e=>xe.includes(e)?e:null;function bn(){return new o("GATEWAY_NOT_INSTALLED",`The Gateway's install didn't finish
|
|
22
|
+
Setup stopped before it recorded the install.`,{rerun:`${p} setup`,rerunNote:"asks for the hostname again"})}async function hn(e){let[t=[]]=await e.run([{sql:"SELECT name FROM sqlite_master WHERE type = 'table' AND name = '_everyapp_install'"}]);if(t.length===0)return null;let[a=[]]=await e.run([{sql:"SELECT * FROM _everyapp_install WHERE id = 'install'"}]),n=a[0];return n?{accountId:String(n.account_id),zoneId:String(n.zone_id),zoneName:String(n.zone_name),gatewayHost:String(n.gateway_host),appBaseDomain:String(n.app_base_domain),oauthKvId:String(n.oauth_kv_id),releaseVersion:String(n.release_version),releaseSha256:String(n.release_sha256),releaseOrder:{schema:Number(n.release_schema),committedAt:Number(n.release_committed_at)},sourceTreeSha256:N(n.source_tree_sha256),liveVersionId:N(n.live_version_id),liveDomains:Me(n.live_domains),liveAppWorkers:Me(n.live_app_workers),updatedAt:Number(n.updated_at),updatedBy:N(n.updated_by),jwtPublicKey:N(n.jwt_public_key),deploymentMode:wt(n.deployment_mode)}:null}async function Tn(e,t){let a=[t.accountId,t.zoneId,t.zoneName,t.gatewayHost,t.appBaseDomain,t.oauthKvId,t.releaseVersion,t.releaseSha256,t.releaseOrder.schema,t.releaseOrder.committedAt,t.sourceTreeSha256,t.liveVersionId,JSON.stringify(t.liveDomains),JSON.stringify(t.liveAppWorkers),t.updatedAt,t.updatedBy,t.jwtPublicKey,t.deploymentMode];await e.run([{sql:yt},{sql:`INSERT INTO _everyapp_install (id, account_id, zone_id, zone_name, gateway_host,
|
|
23
|
+
app_base_domain, oauth_kv_id, release_version, release_sha256, release_schema,
|
|
24
|
+
release_committed_at, source_tree_sha256, live_version_id, live_domains,
|
|
25
|
+
live_app_workers, updated_at, updated_by, jwt_public_key, deployment_mode)
|
|
26
|
+
VALUES ('install', ?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9, ?10, ?11, ?12, ?13, ?14, ?15, ?16, ?17, ?18)
|
|
27
|
+
ON CONFLICT(id) DO UPDATE SET account_id = excluded.account_id,
|
|
28
|
+
zone_id = excluded.zone_id, zone_name = excluded.zone_name,
|
|
29
|
+
gateway_host = excluded.gateway_host, app_base_domain = excluded.app_base_domain,
|
|
30
|
+
oauth_kv_id = excluded.oauth_kv_id, release_version = excluded.release_version,
|
|
31
|
+
release_sha256 = excluded.release_sha256, release_schema = excluded.release_schema,
|
|
32
|
+
release_committed_at = excluded.release_committed_at,
|
|
33
|
+
source_tree_sha256 = excluded.source_tree_sha256,
|
|
34
|
+
live_version_id = excluded.live_version_id, live_domains = excluded.live_domains,
|
|
35
|
+
live_app_workers = excluded.live_app_workers, updated_at = excluded.updated_at,
|
|
36
|
+
updated_by = excluded.updated_by,
|
|
37
|
+
jwt_public_key = COALESCE(excluded.jwt_public_key, _everyapp_install.jwt_public_key),
|
|
38
|
+
deployment_mode = COALESCE(excluded.deployment_mode, _everyapp_install.deployment_mode)`,params:a}])}var Dt=100,bt=50;async function ze(e,t){let a=await e();if(a)return{id:a,created:!1};try{return{id:await t(),created:!0}}catch(n){let r=ce(n,"already_exists")?await e():null;if(r)return{id:r,created:!1};throw n}}async function H(e,t){return(await g(e,{plane:"account",args:["d1","list","--name",t,"--per-page","100"]},fe)).find(n=>n.name===t)?.uuid??null}async function ht(e,t){return(await g(e,{plane:"account",args:["d1","create","--name",t]},Ee)).uuid}function Ue(e,t){return ze(()=>H(e,t),()=>ht(e,t))}async function Tt(e,t){return(await ge(e,["kv","namespaces","list"],Te,{perPage:Dt,maxPages:bt})).find(n=>n.title===t)?.id??null}async function Nt(e,t){return(await g(e,{plane:"account",args:["kv","namespaces","create","--title",t]},he)).id}function $e(e,t){return ze(()=>Tt(e,t),()=>Nt(e,t))}async function An(e,t){await e.run({plane:"account",mode:"json",args:["d1","delete",t,"--force"]})}async function In(e,t){await e.run({plane:"account",mode:"json",args:["kv","namespaces","delete",t,"--force"]})}import{randomBytes as It}from"node:crypto";import{randomBytes as F}from"node:crypto";var We="0123456789ABCDEFGHJKMNPQRSTVWXYZ",Rt=10,vt=16;function St(e=Date.now()){let t="",a=Math.max(0,Math.floor(e));for(let r=0;r<Rt;r+=1)t=We[a%32]+t,a=Math.floor(a/32);let n=[...F(vt)].map(r=>We[r%32]).join("");return`${t}${n}`}var G=e=>`evt_${St(e)}`,B=()=>`sub_${F(12).toString("hex")}`,V=()=>`dlv_${F(12).toString("hex")}`;var At=/^\d{1,3}(\.\d{1,3}){3}$/,K=e=>e.trim().toLowerCase().replace(/\.$/,""),qe=(e,t)=>t!==""&&(e===t||e.endsWith(`.${t}`)),E=(e,t=!1)=>({ok:!1,reason:e,private:t});function He(e,t){let a=e.trim();if(a.length>$)return E(`A webhook URL is at most ${$.toLocaleString("en-US")} characters.`);let n;try{n=new URL(a)}catch{return E("It isn't a URL: give the whole address, like https://hooks.example.com/everyapp.")}if(n.protocol==="http:"){if(!t.allowPrivate)return E("A webhook URL starts with https://: the event and its signature would cross the internet in the clear.",!0)}else if(n.protocol!=="https:")return E(`A webhook URL starts with https://, not ${n.protocol}//.`);if(n.username||n.password)return E("A webhook URL carries no user name or password: the subscription's secret signs each delivery instead.");if(n.hash||a.includes("#"))return E("A webhook URL has no fragment (#\u2026): it is never sent to the receiver.");let r=K(n.hostname),i=K(t.gatewayHost),s=K(t.appBaseDomain);return qe(r,i)||qe(r,s)?E(`${r} is the Gateway's own host, or under its apps' domain ${s}: a delivery there would loop back into the Gateway.`):r.startsWith("[")||At.test(r)?t.allowPrivate?{ok:!0,url:n.toString()}:E("A webhook URL names its host, not an IP address.",!0):le(r)&&!t.allowPrivate?E(`${r} is a local or internal name, which the Gateway's Worker can't reach.`,!0):{ok:!0,url:n.toString()}}function Pn(e){try{let t=new URL(e),a=t.pathname==="/"?"":t.pathname;return`${t.protocol==="http:"?"http://":""}${t.host}${a}`}catch{return"(unreadable URL)"}}function xn(e){try{return new URL(e).hostname}catch{return"Webhook"}}function w(e){return{kind:"operator",id:e.actor,...e.email?{email:e.email}:{}}}var Fe=new WeakMap;function Ge(e){let t=Fe.get(e);return t||(t=e.run([{sql:"PRAGMA table_info(events)"}]).then(([a=[]])=>new Set(a.map(n=>String(n.name)))),Fe.set(e,t)),t}async function Y(e){return(await Ge(e)).size>0}async function Be(e){return(await Ge(e)).has("actor_id")}async function Fn(e){if(!await Be(e))throw new o("GATEWAY_OUTDATED",`The Gateway predates the audit log
|
|
39
|
+
Its events table has no actor columns until the Gateway is updated to a release that has them.`,{rerun:`${p} update`,rerunNote:"then run this again"})}async function T(e){if(!await Y(e))throw new o("GATEWAY_OUTDATED",`The Gateway predates events
|
|
40
|
+
Its database has no event tables until the Gateway is updated to a release that has them.`,{rerun:`${p} update`,rerunNote:"then run this again"})}async function D(e,t){if(!await Y(e))return[];let a=P(t.type);if(!a)throw new Error(`${t.type} isn't in the event catalogue`);let n=ue(t.data,oe);if(!n.ok)throw new Error(`${t.type}'s data: ${n.message}`);let r=t.now??Date.now(),i=G(r),[s=[]]=await e.run([{sql:"SELECT id, events FROM event_subscriptions WHERE organization_id = ? AND enabled = 1",params:[t.organizationId]}]),l=s.filter(m=>de(Ve(m.events),t.type)).map(m=>String(m.id)),d=t.onlyIf?` AND (${t.onlyIf.sql})`:"",c=await Be(e);return[{sql:`INSERT INTO events (id, organization_id, type, version, time, actor, ${c?"actor_kind, actor_id, ":""}data, app_row_id, dedupe_key, created_at)
|
|
41
|
+
SELECT ?, ?, ?, ?, ?, ?, ${c?"?, ?, ":""}?, ?, ?, ? WHERE 1${d}
|
|
42
|
+
ON CONFLICT DO NOTHING`,params:[i,t.organizationId,t.type,a.version,r,JSON.stringify(t.actor),...c?[t.actor.kind,t.actor.id]:[],JSON.stringify(t.data),t.appRowId??null,t.dedupeKey??null,r,...t.onlyIf?.params??[]]},...l.map(m=>Ot(i,m,t.organizationId,r))]}function Ot(e,t,a,n){return{sql:`INSERT INTO event_deliveries (id, event_id, subscription_id, organization_id, status, attempts, next_attempt_at, created_at)
|
|
43
|
+
SELECT ?1, ?2, ?3, ?4, 'pending', 0, ?5, ?5
|
|
44
|
+
WHERE EXISTS (SELECT 1 FROM events WHERE id = ?2)
|
|
45
|
+
AND EXISTS (SELECT 1 FROM event_subscriptions WHERE id = ?3 AND organization_id = ?4 AND enabled = 1)`,params:[V(),e,t,a,n]}}var kt="cap_alerts",Lt="Cap alerts",Ct=["cap.warning","cap.reached"];async function Gn(e,t){return await Y(e)?{sql:`INSERT INTO event_subscriptions (id, organization_id, name, sink, url, secret, recipients, events, enabled,
|
|
46
|
+
builtin, description, created_at, updated_at, created_by, consecutive_failures)
|
|
47
|
+
SELECT ?1, ?2, ?3, 'email', NULL, NULL, 'admins', ?4, 1, ?5, ?6, ?7, ?7, ?8, 0
|
|
48
|
+
WHERE NOT EXISTS (SELECT 1 FROM event_subscriptions WHERE organization_id = ?2 AND builtin = ?5)
|
|
49
|
+
RETURNING id`,params:[B(),t.organizationId,Lt,JSON.stringify(Ct),kt,"Owners and admins get an email at 80% and at the cap.",t.now,`operator:${t.deployer.actor}`]}:null}function Ve(e){try{let t=JSON.parse(String(e));if(Array.isArray(t)&&t.every(a=>typeof a=="string"))return t}catch{}return[]}var j="id, name, sink, url, recipients, events, enabled, builtin, description, created_at, created_by, last_delivery_at, last_delivery_status, consecutive_failures",h=e=>e==null?null:Number(e),y=e=>e==null?null:String(e);function J(e){return{id:String(e.id),name:String(e.name),sink:e.sink==="email"?"email":"webhook",url:y(e.url),recipients:e.recipients==="owners"||e.recipients==="admins"?e.recipients:null,events:Ve(e.events),enabled:Number(e.enabled)===1,builtin:y(e.builtin),description:y(e.description),createdAt:Number(e.created_at),createdBy:y(e.created_by),lastDeliveryAt:h(e.last_delivery_at),lastDeliveryStatus:y(e.last_delivery_status),consecutiveFailures:Number(e.consecutive_failures??0)}}async function Bn(e,t){await T(e);let[a=[]]=await e.run([{sql:`SELECT ${j} FROM event_subscriptions WHERE organization_id = ? ORDER BY created_at, id`,params:[t]}]);return a.map(J)}function Pt(e,t){return new o("EVENT_SUBSCRIPTION_NOT_FOUND",`No subscription ${e} in ${t}
|
|
50
|
+
Subscriptions belong to one organization; --org names another.`,{rerun:`${p} events list`,rerunNote:"lists them"})}async function Z(e,t,a){await T(e);let[n=[]]=await e.run([{sql:`SELECT ${j} FROM event_subscriptions WHERE id = ? AND organization_id = ?`,params:[a.trim(),t.id]}]);if(!n[0])throw Pt(a.trim(),t.name);return J(n[0])}function Vn(e){let t=[...new Set((e??[]).flatMap(n=>n.split(",")).map(n=>n.trim()).filter(Boolean))];if(t.length===0)return["*"];let a=t.flatMap(n=>{let r=pe(n);return r?[{pattern:n,problem:r}]:[]});if(a.length>0)throw new o("EVENT_TYPE_UNKNOWN",[a.length===1?`${a[0].pattern} isn't an event type`:`${a.length} of --events aren't event types`,...a.map(n=>n.problem)].join(`
|
|
51
|
+
`),{fix:"name types (member.joined), prefixes (member.*), an app's own events (app.crm.*) or * for everything",rerun:`${p} events types`,rerunNote:"lists the types",data:{patterns:a.map(n=>n.pattern)}});return t.includes("*")?["*"]:t}function Kn(e,t){let a=He(e,t);if(a.ok)return a.url;throw new o("EVENT_TARGET_REFUSED",`The Gateway won't deliver to that URL
|
|
52
|
+
${a.reason}`,{...a.private?{fix:`use a public https:// receiver; for one on a private network, set EVENTS_ALLOW_PRIVATE_TARGETS on the Gateway (${p} secret set EVENTS_ALLOW_PRIVATE_TARGETS, value true; self-host only)`}:{fix:"give the receiver's full https:// URL (Slack's, Zapier's, n8n's, your own)"}})}var xt=/^[\x21-\x7e]+$/;function Xn(e){let t=e.length<M||e.length>z?`A signing secret is ${M} to ${z} characters (this one is ${e.length}).`:xt.test(e)?null:"A signing secret is printable ASCII with no spaces, so every receiver's HMAC reads the same bytes.";if(!t)return e;throw new o("EVENT_SECRET_INVALID",`That signing secret won't do
|
|
53
|
+
${t}`,{fix:"leave --secret out and the CLI makes one, or give one of 16 to 128 printable characters"})}var Yn=()=>`whsec_${It(32).toString("base64url")}`;function jn(e){let t=e?.replace(/\s+/g," ").trim()??"";return t===""?null:t.length>W?t.slice(0,W):t}async function Jn(e,t){await T(e);let a=t.now??Date.now(),n=B(),{target:r}=t,[i=[]]=await e.run([{sql:`INSERT INTO event_subscriptions (id, organization_id, name, sink, url, secret, recipients, events, enabled,
|
|
54
|
+
builtin, description, created_at, updated_at, created_by, consecutive_failures)
|
|
55
|
+
SELECT ?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, 1, NULL, NULL, ?9, ?9, ?10, 0
|
|
56
|
+
WHERE (SELECT COUNT(*) FROM event_subscriptions WHERE organization_id = ?2) < ?11
|
|
57
|
+
RETURNING ${j}`,params:[n,t.organization.id,t.name,r.sink,r.sink==="webhook"?r.url:null,r.sink==="webhook"?r.secret:null,r.sink==="email"?r.recipients:null,JSON.stringify(t.events),a,`operator:${t.deployer.actor}`,x]}]);if(i[0]&&await e.run(await D(e,{organizationId:t.organization.id,type:"subscription.created",actor:w(t.deployer),data:{subscription:{id:n,name:t.name,sink:r.sink},events:t.events,...r.sink==="webhook"?{host:new URL(r.url).host}:{recipients:r.recipients}},now:a})),!i[0])throw new o("EVENT_SUBSCRIPTIONS_LIMIT",`${t.organization.name} has ${x} subscriptions, the most an organization may have
|
|
58
|
+
Nothing was added.`,{fix:`remove one you no longer need (${p} events remove <id>), or widen one's --events instead of adding another`,rerun:`${p} events list`,rerunNote:"lists them"});return J(i[0])}async function Zn(e,t,a,n=Date.now(),r){let i=await Z(e,t,a),s=l=>r?D(e,{organizationId:t.id,type:"subscription.removed",actor:w(r),data:{subscription:Q(i),disabled:l},now:n}):Promise.resolve([]);return i.builtin?(await e.run([{sql:"UPDATE event_subscriptions SET enabled = 0, updated_at = ? WHERE id = ? AND organization_id = ?",params:[n,i.id,t.id]},...await s(!0)]),{subscription:{...i,enabled:!1},outcome:"disabled"}):(await e.run([{sql:"DELETE FROM event_subscriptions WHERE id = ? AND organization_id = ?",params:[i.id,t.id]},...await s(!1)]),{subscription:i,outcome:"removed"})}var Q=e=>({id:e.id,name:e.name,sink:e.sink});async function Qn(e,t,a,n,r=Date.now(),i){let s=await Z(e,t,a);return s.enabled===n?{subscription:s,changed:!1}:(await e.run([{sql:"UPDATE event_subscriptions SET enabled = ?, updated_at = ? WHERE id = ? AND organization_id = ?",params:[n?1:0,r,s.id,t.id]},...i?await D(e,{organizationId:t.id,type:"subscription.updated",actor:w(i),data:{subscription:Q(s),changed:["enabled"],enabled:n},onlyIf:{sql:"changes() > 0",params:[]},now:r}):[]]),{subscription:{...s,enabled:n},changed:!0})}function Mt(e,t){return new o("EVENT_SUBSCRIPTION_DISABLED",`${e.name} (${e.id}) is disabled
|
|
59
|
+
The Gateway drops what is queued for a disabled subscription, so ${t} would go nowhere.`,{rerun:`${p} events enable ${e.id}`,rerunNote:"then run this again"})}var Ke=`d.id, d.event_id, e.type, d.subscription_id, s.name AS subscription_name, s.sink, d.status, d.attempts,
|
|
60
|
+
d.next_attempt_at, d.claimed_until, d.last_attempt_at, d.last_status_code, d.last_error, d.delivered_at,
|
|
61
|
+
d.redelivered_at, d.created_at`,Xe=`FROM event_deliveries d
|
|
62
|
+
LEFT JOIN events e ON e.id = d.event_id
|
|
63
|
+
LEFT JOIN event_subscriptions s ON s.id = d.subscription_id AND s.organization_id = d.organization_id`;function Ye(e){let t=String(e.status);return{id:String(e.id),eventId:String(e.event_id),type:y(e.type),subscriptionId:String(e.subscription_id),subscriptionName:y(e.subscription_name),sink:e.sink==="email"?"email":e.sink==="webhook"?"webhook":null,status:t==="delivered"||t==="dead"?t:"pending",attempts:Number(e.attempts??0),nextAttemptAt:h(e.next_attempt_at),claimedUntil:h(e.claimed_until),lastAttemptAt:h(e.last_attempt_at),lastStatusCode:h(e.last_status_code),lastError:y(e.last_error),deliveredAt:h(e.delivered_at),redeliveredAt:h(e.redelivered_at),createdAt:Number(e.created_at)}}function zt(e,t=Date.now()){if(e.status!=="pending")return e.status;let a=e.claimedUntil!==null&&e.claimedUntil>t;return e.attempts>0&&e.lastError!==null&&!a?"failed":"pending"}var Ut=200;async function ea(e,t){await T(e);let a=(t.now??Date.now())-U*24*60*60*1e3,n=["d.organization_id = ?","d.created_at >= ?",...t.subscriptionId?["d.subscription_id = ?"]:[],...t.dead?["d.status = 'dead'"]:[]],[r=[]]=await e.run([{sql:`SELECT ${Ke} ${Xe} WHERE ${n.join(" AND ")} ORDER BY d.created_at DESC, d.id DESC LIMIT ?`,params:[t.organizationId,a,...t.subscriptionId?[t.subscriptionId]:[],Math.min(Math.max(1,Math.floor(t.limit)),Ut)]}]);return r.map(Ye)}async function X(e,t,a){let[n=[]]=await e.run([{sql:`SELECT ${Ke} ${Xe} WHERE d.id = ? AND d.organization_id = ?`,params:[a,t]}]);return n[0]?Ye(n[0]):null}async function ta(e,t,a,n=Date.now(),r){await T(e);let i=await X(e,t.id,a.trim());if(!i)throw new o("EVENT_DELIVERY_NOT_FOUND",`No delivery ${a.trim()} in ${t.name}
|
|
64
|
+
Deliveries are kept ${U} days, under the organization of their subscription.`,{rerun:`${p} events deliveries`,rerunNote:"lists the last ones"});let s=await Z(e,t,i.subscriptionId).catch(m=>{throw m instanceof o&&m.code==="EVENT_SUBSCRIPTION_NOT_FOUND"?new o("EVENT_SUBSCRIPTION_NOT_FOUND",`${i.id} was for ${i.subscriptionId}, which is removed
|
|
65
|
+
There is nowhere to send it again.`,{rerun:`${p} events list`,rerunNote:"lists the subscriptions there are"}):m});if(!s.enabled)throw Mt(s,"sending it again");let[l=[]]=await e.run([{sql:`UPDATE event_deliveries SET status = 'pending', attempts = 0, next_attempt_at = ?1, redelivered_at = ?1, claimed_until = NULL
|
|
66
|
+
WHERE id = ?2 AND organization_id = ?3 AND status IN ('pending', 'dead') AND (claimed_until IS NULL OR claimed_until <= ?1)
|
|
67
|
+
RETURNING id`,params:[n,i.id,t.id]},...r?await D(e,{organizationId:t.id,type:"subscription.redelivered",actor:w(r),data:{subscription:Q(s),delivery:{id:i.id,eventId:i.eventId,eventType:i.type??"unknown"}},onlyIf:{sql:"changes() > 0",params:[]},now:n}):[]]),d=await X(e,t.id,i.id)??i,c=l.length>0?"queued":d.status==="delivered"?"delivered":"attempting";return{delivery:d,previous:i,outcome:c}}async function na(e,t){await T(e);let a=t.now??Date.now(),n=G(a),r=V(),i={subscription:{id:t.subscription.id,name:t.subscription.name},message:"A test event from everyapp events test. A signed delivery like this one means the subscription works."};return await e.run([{sql:`INSERT INTO events (id, organization_id, type, version, time, actor, data, app_row_id, dedupe_key, created_at)
|
|
68
|
+
VALUES (?1, ?2, 'ping', ?3, ?4, ?5, ?6, NULL, NULL, ?4)`,params:[n,t.organizationId,P("ping").version,a,JSON.stringify(t.actor),JSON.stringify(i)]},{sql:`INSERT INTO event_deliveries (id, event_id, subscription_id, organization_id, status, attempts, next_attempt_at, created_at)
|
|
69
|
+
VALUES (?1, ?2, ?3, ?4, 'pending', 0, ?5, ?5)`,params:[r,n,t.subscription.id,t.organizationId,a]}]),{eventId:n,deliveryId:r}}var $t=9e4;async function aa(e,t,a,n={}){let r=n.sleep??(l=>new Promise(d=>setTimeout(d,l))),i=n.now??Date.now,s=i()+(n.timeoutMs??$t);for(;;){let l=await X(e,t,a);if(l&&zt(l,i())!=="pending")return l;if(i()>=s)return null;await r(Math.min(n.intervalMs??3e3,Math.max(0,s-i())))}}import{randomUUID as Wt}from"node:crypto";function ca(e,t,a=process.env){return a.CLOUDFLARE_API_TOKEN||!e?{actor:`api-token:${t}`,email:null}:{actor:e,email:e}}function qt(e){return e instanceof A?new o(e.code,e.message,{retryable:e.status>=500}):e}async function te(e){try{return await e()}catch(t){throw qt(t)}}var Qe="id, organization_id, app_slug, name, description, hostname, worker_name, tier, scope, manifest, status, version_id, deployed_at, deployed_by_actor, is_default, email_senders, email_inbound",Ht=`${Qe}, secret_names`,je=new WeakMap;function R(e){let t=je.get(e);return t||(t=e.run([{sql:"PRAGMA table_info(apps)"}]).then(([a=[]])=>a.some(n=>n.name==="secret_names")),je.set(e,t)),t}async function O(e){return await R(e)?Ht:Qe}var u=e=>e==null?null:String(e);function k(e){return{id:String(e.id),organizationId:String(e.organization_id),appSlug:String(e.app_slug),name:String(e.name),description:String(e.description),hostname:u(e.hostname),workerName:u(e.worker_name),tier:String(e.tier),scope:String(e.scope),manifest:u(e.manifest),status:String(e.status),versionId:u(e.version_id),deployedAt:e.deployed_at==null?null:Number(e.deployed_at),deployedByActor:u(e.deployed_by_actor),isDefault:!!Number(e.is_default),emailSenders:u(e.email_senders),emailInbound:u(e.email_inbound),secretNames:u(e.secret_names)}}function Je(e){return e?{organizationId:String(e.organization_id),appSlug:String(e.app_slug),hostname:u(e.hostname),workerName:u(e.worker_name)}:null}function Ze(e){return e?{id:String(e.id),name:String(e.name),slug:String(e.slug)}:null}var et={sql:`SELECT id, name, slug FROM organizations
|
|
70
|
+
WHERE EXISTS (SELECT 1 FROM members WHERE members.organization_id = organizations.id AND members.role = 'owner')
|
|
71
|
+
ORDER BY created_at, id LIMIT 1`},tt={sql:"SELECT id, name, slug FROM organizations ORDER BY created_at, id LIMIT 1"};async function nt(e){let[t=[],a=[]]=await e.run([et,tt]);return at(t,a)}function at(e,t){let a=Ze(e[0]);if(a)return{organization:a,hasOwner:!0};let n=Ze(t[0]);return n?{organization:n,hasOwner:!1}:null}function Ft(e){return e.trim().toLowerCase().replace(/[^a-z0-9\s-]/g,"").replace(/\s+/g,"-").replace(/-+/g,"-").replace(/^-|-$/g,"").slice(0,48)}async function Gt(e,t,a){let n=await nt(e);if(n)return n;let r=t.trim()||"My Organization",[,i=[],s=[]]=await e.run([{sql:`INSERT INTO organizations (id, name, slug, created_at)
|
|
72
|
+
SELECT ?1, ?2, ?3, ?4 WHERE NOT EXISTS (SELECT 1 FROM organizations)`,params:[Wt(),r,Ft(r)||"default",a]},et,tt]),l=at(i,s);if(!l)throw new Error("The gateway's database has no organization.");return l}function Bt(e,t){let a=Se(t);return{sql:`WITH candidates(rank, candidate) AS (VALUES ${a.map((r,i)=>`(${i}, ?${i+2})`).join(", ")})
|
|
73
|
+
INSERT OR IGNORE INTO organization_keys (organization_id, org_key)
|
|
74
|
+
SELECT ?1, candidate FROM candidates
|
|
75
|
+
WHERE NOT EXISTS (SELECT 1 FROM organization_keys WHERE organization_id = ?1)
|
|
76
|
+
AND candidate NOT IN (SELECT org_key FROM organization_keys)
|
|
77
|
+
ORDER BY rank LIMIT 1`,params:[e,...a]}}function ma(e,t){return te(()=>Vt(e,t))}async function Vt(e,t){let a=t.now??Date.now(),{organization:n,hasOwner:r}=await Gt(e,t.organizationName,a),[,i=[],s=[],l=[],d=[]]=await e.run([Bt(n.id,n.slug),{sql:"SELECT org_key FROM organization_keys WHERE organization_id = ?",params:[n.id]},{sql:`SELECT ${await O(e)} FROM apps WHERE organization_id = ? AND app_slug = ?`,params:[n.id,t.appSlug]},...rt(n.id,t.deployer.email)]),c=u(i[0]?.org_key);if(!c)throw new A({status:409,code:"ORG_KEY_UNAVAILABLE",message:`Every key for organization "${n.slug}" is taken by another organization on this gateway.`});let m=s[0]?k(s[0]):null,v=Ae({appSlug:t.appSlug,orgKey:c,isInstallOrganization:!0,appBaseDomain:t.appBaseDomain,existingApp:m}),[ut=[],ct=[]]=await e.run([{sql:"SELECT organization_id, app_slug, hostname, worker_name FROM apps WHERE hostname = ?",params:[v.hostname]},{sql:"SELECT organization_id, app_slug, hostname, worker_name FROM apps WHERE worker_name = ?",params:[v.workerName]}]),S=u(d[0]?.id),re=it(l),f=Oe({organizationId:n.id,isInstallOrganization:!0,scope:t.scope,appSlug:t.appSlug,name:t.name,description:t.description,manifest:t.manifest,appBaseDomain:t.appBaseDomain,orgKey:c,existingApp:m,hostnameOwner:Je(ut[0]),workerNameOwner:Je(ct[0]),members:re,deployerUserId:S});if(f.app.scope==="shared"&&st(t.deployer,S,re,n,t.expectedWorkerName===void 0?"deploy":"register"),t.expectedWorkerName!==void 0&&f.app.workerName!==t.expectedWorkerName)throw new o("WORKER_NAME_MISMATCH",`${t.appSlug}'s Worker must be named ${f.app.workerName}, not ${t.expectedWorkerName}
|
|
78
|
+
The Gateway binds each app's Worker by that name only.`,{fix:`deploy the Worker as ${f.app.workerName}`,rerun:`${ie("--worker")} --worker ${f.app.workerName}`});return await e.run(Xt(f,a,{secretNames:await R(e)})),{plan:f,organization:n,hasOwner:r,deployerGranted:S!==null&&f.grants.some(mt=>mt.userId===S)}}function rt(e,t){return[{sql:"SELECT user_id, role FROM members WHERE organization_id = ?",params:[e]},{sql:"SELECT id FROM users WHERE lower(email) = lower(?) AND email_verified = 1",params:[t]}]}function it(e){return e.map(t=>({id:String(t.user_id),role:u(t.role)}))}var Kt=e=>(e??"").split(",").some(t=>["owner","admin"].includes(t.trim()));function st(e,t,a,n,r){if(e.email===null)return;let i=a.find(s=>s.id===t);if(!(i&&Kt(i.role)))throw new o("SHARED_APP_FORBIDDEN",`Only ${n.name} owners and admins can ${r} shared apps
|
|
79
|
+
${e.email} isn't an owner or admin of ${n.name}, the platform organization.`,{fix:`ask an owner of ${n.name} to make you an admin, or to do it for you`})}function Xt(e,t,a){let{app:n}=e;if(e.kind==="existing")return[{sql:"UPDATE apps SET name = ?, description = ?, updated_at = ? WHERE id = ?",params:[n.name,n.description,t,n.id]}];let r=e.grants.map(i=>({sql:`INSERT INTO user_app_access (id, user_id, app_row_id, organization_id, granted_by)
|
|
80
|
+
VALUES (?, ?, ?, ?, NULL) ON CONFLICT DO NOTHING`,params:[i.id,i.userId,i.appRowId,i.organizationId]}));return e.kind==="new"?[{sql:`INSERT INTO apps (id, organization_id, app_slug, name, description, hostname,
|
|
81
|
+
worker_name, tier, manifest, status, version_id, deployed_at, deployed_by_actor,
|
|
82
|
+
is_default, created_at, updated_at, scope)
|
|
83
|
+
VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9, ?10, ?11, ?12, ?13, ?14, ?15, ?15, ?16)`,params:[n.id,n.organizationId,n.appSlug,n.name,n.description,n.hostname,n.workerName,n.tier,n.manifest,n.status,n.versionId,n.deployedAt,n.deployedByActor,n.isDefault?1:0,t,n.scope]},...r]:[{sql:`UPDATE apps SET name = ?, description = ?, hostname = ?, worker_name = ?,
|
|
84
|
+
manifest = ?, status = ?, is_default = ?, updated_at = ?
|
|
85
|
+
WHERE id = ? AND status = '${_}'`,params:[n.name,n.description,n.hostname,n.workerName,n.manifest,n.status,n.isDefault?1:0,t,n.id]},...ot(n,t,a),...r]}function ot(e,t,{secretNames:a=!0}={}){let n=[e.id,e.organizationId];return[{sql:`UPDATE apps SET email_senders = NULL, email_inbound = NULL${a?", secret_names = NULL":""} WHERE id = ? AND organization_id = ?`,params:n},{sql:"DELETE FROM user_app_access WHERE app_row_id = ? AND organization_id = ?",params:n},{sql:"DELETE FROM group_app_access WHERE app_row_id = ? AND organization_id = ?",params:n},{sql:`UPDATE user_access_tokens SET revoked_at = ?1, updated_at = ?1
|
|
86
|
+
WHERE app_row_id = ?2 AND organization_id = ?3 AND revoked_at IS NULL`,params:[t,...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},{sql:"DELETE FROM mcp_connection_apps WHERE app_row_id = ?",params:[e.id]},{sql:"DELETE FROM org_app_settings WHERE app_row_id = ?",params:[e.id]}]}async function Yt(e,t){let[a=[]]=await e.run([{sql:`SELECT ${await O(e)} FROM apps WHERE id = ?`,params:[t]}]);return a[0]?k(a[0]):null}var jt=3,I=e=>({id:e.appSlug,rowId:e.id,name:e.name});async function Jt(e,t,a,n){let r=t.status==="pending";return!r&&t.versionId===a.versionId?[]:D(e,{organizationId:t.organizationId,type:r?"app.installed":"app.updated",actor:w({actor:a.actor,email:a.email??null}),data:r?{app:I(t),version:a.versionId,...t.hostname?{hostname:t.hostname}:{},scope:t.scope==="shared"?"shared":"org",source:a.source??"cli"}:{app:I(t),version:a.versionId,...t.versionId?{previousVersion:t.versionId}:{}},appRowId:t.id,onlyIf:{sql:"EXISTS (SELECT 1 FROM apps WHERE id = ? AND version_id = ?)",params:[t.id,a.versionId]},now:n})}function ga(e,t,a){return te(async()=>{let n=await R(e);for(let r=1;;r+=1){let i=await Yt(e,t);if(!i)throw new A({status:404,code:"APP_NOT_FOUND",message:"The app's registry row is gone; deploy it again."});let s=ke(i,a),l=await Jt(e,i,a,s.deployedAt),[d=[]]=await e.run([{sql:`UPDATE apps SET manifest = ?, version_id = ?, deployed_at = ?, deployed_by_actor = ?,
|
|
87
|
+
status = ?, updated_at = ?${n?", secret_names = COALESCE(?, secret_names)":""}
|
|
88
|
+
WHERE id = ? AND status = ? RETURNING status`,params:[s.manifest,s.versionId,s.deployedAt,s.deployedByActor,s.status,s.deployedAt,...n?[a.secretNames?q(a.secretNames):null]:[],t,i.status]},...l]);if(d.length>0)return s.status;if(r>=jt)throw new o("APP_CHANGING",`The app's registry row keeps changing while this deploy records its upload
|
|
89
|
+
The upload is kept.`,{retryable:!0})}})}function L(e){return{id:e.id,appSlug:e.appSlug,organizationId:e.organizationId,status:e.status,workerName:e.workerName??"",hostname:e.hostname??"",resources:Ie(e),email:{senders:b(e.emailSenders),inbound:b(e.emailInbound)},declaresInbound:Qt(e.manifest),publicRoutes:Ne(e.manifest),mcp:Re(e.manifest),manifest:Zt(e.manifest),secretNames:ve(e.secretNames),tier:e.tier}}function Zt(e){if(!e)return null;try{let t=JSON.parse(e);return t&&typeof t=="object"&&!Array.isArray(t)?t:null}catch{return null}}function Qt(e){if(!e)return!1;try{let a=JSON.parse(e)?.email?.inbound;return a===!0||Array.isArray(a)}catch{return!1}}async function ne(e,t){let a=await nt(e);if(!a)return null;let[n=[]]=await e.run([{sql:`SELECT ${await O(e)} FROM apps WHERE organization_id = ? AND app_slug = ?`,params:[a.organization.id,t]}]);return n[0]?{app:k(n[0]),organization:a.organization}:null}async function lt(e,t,a,n){if(t.email===null)return;let[r=[],i=[]]=await e.run(rt(a.id,t.email));st(t,u(i[0]?.id),it(r),a,n)}function ee(e){return new o("APP_NOT_FOUND",`${e} isn't deployed to this Gateway yet`,{rerun:`${p} deploy`,rerunNote:"in the app's directory"})}async function _a(e,t){let a=await en(e,t);if(!a)throw ee(t);return a}async function en(e,t){let a=(await ne(e,t))?.app;return a&&dt(a)?L(a):null}function dt(e){return e.status!==_&&!!e.workerName}async function Ea(e,t){let[a=[]]=await e.run([{sql:"SELECT email_senders, email_inbound FROM apps WHERE id = ?",params:[t]}]),n=a[0];if(!n)throw new o("APP_NOT_FOUND","The app is no longer registered on this Gateway",{rerun:`${p} deploy`,rerunNote:"in the app's directory"});return{senders:b(n.email_senders),inbound:b(n.email_inbound)}}async function fa(e,t,a,n,r=Date.now()){return te(async()=>{let i=await ne(e,t);if(!i||!dt(i.app))throw ee(t);let{app:s,organization:l}=i;s.scope==="shared"&&await lt(e,n,l,"change the email of");let d=C(a.senders),c=C(a.inbound),m=d===s.emailSenders&&c===s.emailInbound,[v=[]]=await e.run([{sql:`UPDATE apps SET email_senders = ?, email_inbound = ?, updated_at = ?
|
|
90
|
+
WHERE id = ? AND status != '${_}' RETURNING id`,params:[d,c,r,s.id]},...m?[]:await D(e,{organizationId:s.organizationId,type:"app.email_changed",actor:w(n),data:{app:I(s),senders:b(d),inbound:b(c)},appRowId:s.id,onlyIf:{sql:"changes() > 0",params:[]},now:r})]);if(v.length===0)throw ee(t);return L({...s,emailSenders:d,emailInbound:c})})}async function ya(e,t,a,n=Date.now()){await R(e)&&await e.run([{sql:`UPDATE apps SET secret_names = ?, updated_at = ?
|
|
91
|
+
WHERE id = ? AND status != '${_}'`,params:[q(a),n,t]}])}async function wa(e,t){let[a=[]]=await e.run([{sql:`SELECT app_slug FROM apps WHERE status != '${_}' AND (worker_name = ? OR substr(?, 1, length(worker_name) + 2) = worker_name || '--')`,params:[t,t]}]);return u(a[0]?.app_slug)}async function Da(e){let[t=[]]=await e.run([{sql:`SELECT ${await O(e)} FROM apps WHERE status != '${_}' ORDER BY app_slug, organization_id`}]);return t.map(k).map(a=>({...L(a),deployedBy:a.deployedByActor,deployedAt:a.deployedAt}))}async function ba(e){let[t=[]]=await e.run([{sql:"SELECT name FROM sqlite_master WHERE type = 'table' AND name = 'apps'"}]);if(t.length===0)return[];let[a=[]]=await e.run([{sql:"SELECT app_slug, hostname, worker_name, status FROM apps ORDER BY app_slug"}]);return a.map(n=>({appSlug:String(n.app_slug),hostname:u(n.hostname),workerName:u(n.worker_name),status:String(n.status)}))}async function ha(e,t,a,n=Date.now(),{purge:r=!1}={}){let i=await ne(e,t);if(i&&i.app.tier===se&&i.app.status!==_)throw new o("APP_NOT_FOUND",`${t} is an MCP app, not an app deployed to this Gateway`,{rerun:`${p} mcp remove ${t}`,rerunNote:"removes an MCP app"});if(!i||!i.app.workerName)throw new o("APP_NOT_FOUND",`No app named ${t} on this Gateway`,{rerun:`${p} status`,rerunNote:"lists its apps"});let{app:s,organization:l}=i;s.scope==="shared"&&await lt(e,a,l,"delete");let d=Le(s);return d&&await e.run([{sql:"UPDATE apps SET status = ?, is_default = ?, updated_at = ? WHERE id = ?",params:[d.status,d.isDefault?1:0,n,s.id]},...ot(s,n,{secretNames:await R(e)}),...await D(e,{organizationId:s.organizationId,type:"app.removed",actor:w(a),data:{app:I(s),purged:r},appRowId:s.id,now:n})]),{...L(s),status:_,alreadyDeleted:d===null}}var ae="every-app-gateway",pt="every-app-gateway-OAUTH_KV";async function Ra(e){let t=await Ue(e,ae),a=await $e(e,pt);return{d1Id:t.id,oauthKvId:a.id,created:[...t.created?[`D1 ${ae}`]:[],...a.created?[`KV ${pt}`]:[]]}}function va(e){return H(e,ae)}export{sn as a,on as b,_t as c,ln as d,dn as e,pn as f,un as g,cn as h,_n as i,bn as j,hn as k,Tn as l,H as m,ht as n,Tt as o,Nt as p,An as q,In as r,Ra as s,va as t,Pn as u,xn as v,w,Y as x,Fn as y,T as z,D as A,Gn as B,Bn as C,Z as D,Vn as E,Kn as F,Xn as G,Yn as H,jn as I,Jn as J,Zn as K,Qn as L,Mt as M,zt as N,Ut as O,ea as P,ta as Q,na as R,$t as S,aa as T,ca as U,te as V,R as W,O as X,u as Y,k as Z,nt as _,Gt as $,ma as aa,rt as ba,it as ca,ot as da,Yt as ea,ga as fa,_a as ga,en as ha,Ea as ia,fa as ja,ya as ka,wa as la,Da as ma,ba as na,ha as oa};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{a as H,b as X,d as P,e as G,f as q,g as J,h as D,i as z,j as N,k as $,l as A}from"./chunk-
|
|
1
|
+
import{a as H,b as X,d as P,e as G,f as q,g as J,h as D,i as z,j as N,k as $,l as A}from"./chunk-F5XK23HV.js";import{a as F,f as x}from"./chunk-YAZHTVUV.js";import{b as B,c as U,f as K,g as j}from"./chunk-3EADVHFN.js";import{la as W}from"./chunk-KOBKGQ27.js";import{b as L,d as Z}from"./chunk-I7FNTTUY.js";import{bc as p,c as _,hc as T}from"./chunk-FQ2A7YAP.js";function M(e){return`everyapp:${e}`}function O(e){if(!e)return null;if(e.startsWith("catch_all:"))return{kind:"catch_all",zoneId:e.slice(10)};let[n,t]=e.split("/");return n&&t?{kind:"rule",zoneId:n,ruleId:t}:null}function w(e){return e.slice(e.lastIndexOf("@")+1)}function b(e){return e.startsWith("*@")}async function ye({cf:e,gatewayDb:n,accountId:t,workerName:l,addresses:a,interactive:i,enableRouting:r=!1,confirm:s=L}){let d=(await B(n,l)).filter(o=>o.kind==="email-route"),m=d.filter(o=>!a.includes(o.binding));if(a.length===0)return d.length>0?{workerName:l,accountId:t,routes:[],enable:[],dropped:m}:null;let E=await U(n,"email-route");for(let o of a){let u=E.find(f=>f.name===o&&f.workerName!==l);if(u){let f=await W(n,u.workerName);throw new p("EMAIL_ADDRESS_TAKEN",`${o} already goes to another app${f?` (${f})`:""}`,{fix:`pick another address, or run ${_} email unset inbound in ${f?`${f}'s`:"that app's"} directory first`,data:{address:o,workerName:u.workerName,appId:f}})}}let R=new Map;for(let o of new Set(a.map(w)))R.set(o,await se(e,o,t));for(let o of a.filter(b)){let u=R.get(w(o));if(u.name!==w(o))throw new p("EMAIL_CATCH_ALL_NOT_APEX",`${o}: catch-alls only work on a zone's apex
|
|
2
2
|
${w(o)} is a subdomain of ${u.name}.`,{fix:`list each address instead, e.g. --inbound support@${w(o)}`,data:{address:o,zone:u.name}})}let y=te(e),g=[];for(let[o,u]of R)await ne(e,u,o,await y.settings(u.id))||g.push({zone:u,domain:o});g.sort((o,u)=>+(o.domain!==o.zone.name)-+(u.domain!==u.zone.name));let S=new Set(d.flatMap(o=>{let u=O(o.resourceId);return u?.kind==="rule"?[u.ruleId]:[]})),k=o=>oe(o,l)||o.id!==null&&S.has(o.id),v=[];for(let o of a){let u=R.get(w(o));if(b(o)){let c=await y.catchAll(u.id),C=c.enabled&&c.actions.some(re=>re.type!=="drop");if(!k(c)&&C)throw new p("EMAIL_CATCH_ALL_TAKEN",`${u.name}'s catch-all already ${Y(c)}
|
|
3
3
|
${o} would take it over.`,{fix:"set the catch-all back to Drop (Email Routing \u2192 Routing rules), or list addresses one by one",data:{address:o,zone:u.name,actions:c.actions}});v.push({address:o,zone:u,existing:k(c)?c:null});continue}let f=(await y.rules(u.id)).filter(c=>A(c)===o),h=f.find(c=>!k(c));if(h)throw new p("EMAIL_ADDRESS_TAKEN",`${o} already ${Y(h)}
|
|
4
4
|
The Email Routing rule ${h.name?`"${h.name}"`:h.id} on ${u.name} delivers it.`,{fix:"remove that rule, or pick another address",data:{address:o,zone:u.name,ruleId:h.id,actions:h.actions}});let I=f.find(c=>c.id!==null&&S.has(c.id))??f[0]??null;v.push({address:o,zone:u,existing:I})}if(g.length>0&&!r){let o=g.map(({domain:c})=>c),u=o.join(", "),h=`Turning it on locks ${o.length===1?"the domain's":"their"} MX and SPF records to Cloudflare.`,I=g.map(({zone:c,domain:C})=>`npx cf email-routing enable -z ${c.name} --name ${C}`);if(!i)throw new p("EMAIL_ROUTING_DISABLED",`Email Routing is off for ${u}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{k as u,l as c}from"./chunk-RQBSTNL7.js";import{Dc as a,Ec as l,hc as i}from"./chunk-FQ2A7YAP.js";var p={perPage:100,maxPages:50};function m(e){return l(e,["workers","list"],c,p)}async function y(e,o){return((await m(e)).find(r=>r.name===o)?.references?.domains??[]).map(r=>r.hostname.toLowerCase())}async function g(e,o){let t;try{t=await a(e,{plane:"account",args:["workers","deployments","list","--worker",o,"--per-page","10"]},u)}catch(n){if(i(n,"not_found"))return null;throw n}let r=[...t].sort((n,s)=>(s.created_on??"").localeCompare(n.created_on??""))[0];return{versionId:[...r?.versions??[]].sort((n,s)=>s.percentage-n.percentage)[0]?.version_id??null,deployedAt:r?.created_on?Date.parse(r.created_on):null}}async function C(e,o,{withReferences:t=!1}={}){await e.run({plane:"account",mode:"json",args:["workers","delete",o,"--force",...t?["--delete-with-references"]:[]]})}export{m as a,y as b,g as c,C as d};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{n as a}from"./chunk-
|
|
1
|
+
import{n as a}from"./chunk-RQBSTNL7.js";import{Dc as i,gc as c}from"./chunk-FQ2A7YAP.js";async function m(e,t){return(await i(e,{plane:"account",args:["workers","secrets","list","--worker",t]},a)).map(r=>r.name).sort()}async function p(e,t,n){try{return await e.run({plane:"account",mode:"json",args:["workers","secrets","delete",n,"--worker",t,"--force"]}),!0}catch(r){if(r instanceof c&&(r.kind==="not_found"||/not[_ ]found/i.test(r.message)))return!1;throw r}}async function d(e,t,n){let r={secrets:Object.fromEntries(Object.entries(n).map(([s,o])=>[s,o===null?null:{name:s,type:"secret_text",text:o}]))};await e.run({plane:"account",mode:"json",files:{"secrets.json":r},args:s=>["workers","secrets","bulk","--worker",t,"--body",`@${s["secrets.json"]}`]})}export{m as a,p as b,d as c};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{d as o,f as s}from"./chunk-
|
|
1
|
+
import{d as o,f as s}from"./chunk-EQLY5I46.js";var r={sql:`CREATE TABLE IF NOT EXISTS _everyapp_restore_points (
|
|
2
2
|
target TEXT PRIMARY KEY,
|
|
3
3
|
database_id TEXT NOT NULL,
|
|
4
4
|
bookmark TEXT NOT NULL,
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import{a as Ee,b as tt,c as nt,d as be,e as Z}from"./chunk-QJRZFIYC.js";import{a as Y,d as Ke,e as Qe,f as et}from"./chunk-TUXKBLLJ.js";import{B as _e}from"./chunk-PDPUGYJW.js";import{A as Ye,B as we,C as J,D as H,E as Ze,F as Be,G as qe,H as Ae,I as $e,J as Se,K as Ce,N as Ve,O as Je,P as pe,Q as Xe,b as ge,c as Te,d as ke,e as he,f as Pe,g as Le,h as fe,i as Re,k as Me,l as oe,n as Ne,o as Ge,p as Ue,s as xe,t as ye,v as re,w as K,y as He,z as de}from"./chunk-QKHLRLK3.js";import{a as ce}from"./chunk-LEEUODYR.js";import{c as We,e as je}from"./chunk-EQLY5I46.js";import{c as ot,e as ct}from"./chunk-DCFHBCCW.js";import{A as at,_ as it,w as st}from"./chunk-KOBKGQ27.js";import{a as le,f as ze,i as Fe}from"./chunk-I7FNTTUY.js";import{Hb as ie,Qc as Ie,Tc as Q,Yc as me,bc as N,c as W,f as x,gc as Oe,k as h}from"./chunk-FQ2A7YAP.js";import l from"chalk";var De="CLOUDFLARE_ACCESS_IDP_IDS",Xt=24*3600,O="access.update";async function Kt(t){await me(t,e=>wt({flags:t,out:e,emails:t.email,emailDomains:t["email-domain"],team:t.team,session:t.session,teamSession:t["team-session"],writeSettings:t["write-settings"]}))}async function Qt(t){await me(t,e=>St({flags:t,out:e,keepApplications:t["keep-applications"]}))}async function en(t){await me(t,e=>Ct({flags:t,out:e}))}var ht=/^[^\s@]+@[^\s@]+\.[^\s@]+$/,ft=/^(?=.{1,253}$)(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.)+[a-z0-9-]{2,63}$/,rt=/^[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$/;function ve({flags:t,out:e,createCf:o}){return ct({gateway:ot(t.gateway),accountId:t["account-id"],interactive:le(t.json??!1),login:{json:t.json,out:e,step:"login"},createCf:o})}function dt(t){if(t.deploymentMode==="hosted")throw new N("ACCESS_HOSTED",`This Gateway can't be put behind Cloudflare Access
|
|
2
|
+
Hosted Gateways ignore the Access settings.`)}function lt(t,e){let o=e.trim(),a=Ve(o);if(a===null||a<=0)throw new N("ACCESS_SESSION_INVALID",`${t} ${e} isn't a duration Access takes
|
|
3
|
+
Use hours and minutes, like 720h or 2h30m.`);return o}async function pt(t,e){let o="(u.banned IS NULL OR u.banned = 0 OR (u.ban_expires IS NOT NULL AND u.ban_expires <= ?1))",[a=[],m=[],w=[]]=await t.run([{sql:`SELECT u.email FROM users u WHERE ${o} ORDER BY u.email`,params:[e]},{sql:"SELECT DISTINCT email FROM invitations WHERE status = 'pending' AND expires_at > ?1 ORDER BY email",params:[e]},{sql:`SELECT u.email FROM users u
|
|
4
|
+
WHERE ${o}
|
|
5
|
+
AND EXISTS (SELECT 1 FROM accounts a WHERE a.user_id = u.id AND a.provider_id = 'credential')
|
|
6
|
+
AND NOT EXISTS (SELECT 1 FROM accounts a WHERE a.user_id = u.id AND a.provider_id = 'cloudflare-access')
|
|
7
|
+
ORDER BY u.email`,params:[e]}]),A=g=>[...new Set(g.map(d=>String(d.email).toLowerCase()))];return{members:A(a),invited:A(m),toLink:A(w)}}function yt(t,e){let o=[],a=[],m=[];for(let w of t){let A=w.trim().toLowerCase();if(!ht.test(A))throw new N("ACCESS_EMAIL_INVALID",`--email ${w} isn't an email address`);o.push(de(A)),a.push(A)}for(let w of e){let A=w.trim().toLowerCase().replace(/^@/,"");if(!ft.test(A))throw new N("ACCESS_DOMAIN_INVALID",`--email-domain ${w} isn't a domain
|
|
8
|
+
Use the part after the @, like example.com.`);o.push(Ye(A)),m.push(A)}return{rules:o,emails:a,domains:m}}async function wt(t){let{out:e}=t,o=t.now??Date.now,a=t.session===void 0?Ke:lt("--session",t.session),m=t.teamSession===void 0?null:lt("--team-session",t.teamSession),w=yt(t.emails??[],t.emailDomains??[]),A=t.interactive??le(t.flags.json??!1);e.emit({type:"step",step:O,status:"start",message:"Checking Cloudflare Access..."});let g=await ve(t),{cf:d,db:E,install:$}=g;dt($);let p=pe($),{gatewayHost:I,appBaseDomain:v}=p,S=await pt(E,o()),u=[...S.members.map(de),...S.invited.map(de),...w.rules],y=await ge(d),f=y?(await fe(d)).find(r=>r.name===Y)??null:null;if(u.length===0&&!f)throw new N("ACCESS_NOBODY_ALLOWED",`Nobody to let in yet
|
|
9
|
+
The Gateway has no members or invitations, and no --email was given, so the Access policy would let nobody in. Claim the Gateway first, or name who will (the setup link is then behind Access too).`,{rerun:`${W} access on --email <your address>`});let _=w.emails.filter(r=>!S.members.includes(r)&&!S.invited.includes(r));_.length>0&&e.emit({type:"warning",code:"ACCESS_EMAIL_NOT_INVITED",step:O,message:`${h(_)} ${_.length===1?"has":"have"} no account on this Gateway
|
|
10
|
+
Access will let ${_.length===1,"them"} through, but the Gateway refuses anyone it doesn't know. Invite ${_.length===1,"them"} in Manage workspace \u2192 Users.`,data:{emails:_}});let C=!1,n=null;if(y)m!==null&&y.session_duration!==m&&(e.emit({type:"progress",step:O,message:`Setting the team's global session to ${m}`}),y=await ke(d,y,m),n=m);else{let r=$.zoneName.split(".")[0].toLowerCase().replace(/[^a-z0-9-]/g,"")||"every-app",M=t.team;if(M===void 0){if(!A)throw new N("ACCESS_TEAM_REQUIRED",`Choose a name for the Zero Trust team with --team
|
|
11
|
+
This Cloudflare account has none yet. Its sign-in page becomes https://<name>.cloudflareaccess.com and can't be changed later.`,{fix:`add --team ${r}, or another name`,data:{suggested:r}});M=await(t.askTeam??At)(r)}if(!rt.test(M))throw new N("ACCESS_TEAM_INVALID",`${t.team===void 0?"":"--team "}${M} can't be a team name
|
|
12
|
+
Use lowercase letters, digits and dashes: it becomes <name>.cloudflareaccess.com.`);e.emit({type:"progress",step:O,message:`Creating the Zero Trust team ${M}.cloudflareaccess.com`});try{y=await Te(d,{name:M,auth_domain:`${M}.cloudflareaccess.com`,session_duration:m??a})}catch(ae){throw!(ae instanceof Oe)||ae.kind==="auth"?ae:new N("ACCESS_TEAM_CREATE_FAILED",`Cloudflare didn't create the Zero Trust team ${M}
|
|
13
|
+
${ae.message.split(`
|
|
14
|
+
`)[0]}`,{fix:"pick another name with --team: team names are shared across Cloudflare",data:{team:M}})}C=!0,n=m??a}let b=y.auth_domain.toLowerCase(),s=await he(d),i=Ae(s),G=!1,L=!1;i.cloudflare&&(e.emit({type:"progress",step:O,message:"Adding Sign in with Cloudflare (members of this Cloudflare account)"}),s=[...s,await Le(d)],G=!0),i.pin&&(e.emit({type:"progress",step:O,message:"Adding the one-time PIN identity provider"}),s=[...s,await Pe(d)],L=!0);let U=Ce(s),B=s.filter(r=>qe.includes(r.type));B.length>0&&e.emit({type:"warning",code:"ACCESS_IDP_UNVERIFIED_EMAILS",step:O,message:`${h(B.map(r=>`${r.name??r.id} (${r.type})`))} ${B.length===1?"is a generic provider, left off the EveryApp applications":"are generic providers, left off the EveryApp applications"}
|
|
15
|
+
The Gateway signs people in as the email Access asserts. A provider that lets people choose their own address would let them choose someone else's; allow only providers that verify addresses (runbook: "Verified emails").`,data:{providers:B.map(r=>({id:r.id,type:r.type,name:r.name??null}))}}),ut(e,s);let T=g.deployer.email?.toLowerCase()??null;T!==null&&!S.members.includes(T)&&!S.invited.includes(T)&&!w.emails.includes(T)&&e.emit({type:"warning",code:"ACCESS_LOGIN_NOT_MEMBER",step:O,message:`Sign in with Cloudflare signs you in as ${T}, which has no account on this Gateway
|
|
16
|
+
Access asserts your Cloudflare login's address, and the Gateway refuses anyone it doesn't know. Sign in with the code Access emails to your Gateway account's address instead, or invite ${T} in Manage workspace \u2192 Users.`,data:{email:T}});let D,q=!1,k=[];if(f){let r=we(f.include??[],u);r.added.length>0?(e.emit({type:"progress",step:O,message:`Adding ${x(r.added.length,"rule")} to the Access policy`}),D=await Me(d,f,r.include),k=r.added):D=f}else{let r=we([],u);e.emit({type:"progress",step:O,message:`Creating the Access policy "${Y}"`}),D=await Re(d,{name:Y,decision:"allow",include:r.include}),q=!0,k=r.include}let z=await We({db:E,id:je,purpose:"access.sync",out:e,step:"gateway.lease"}),P;try{P=await Qe(d,e,E,{scope:p,found:re(await oe(d),p),policyId:D.id,session:a,sessionGiven:t.session!==void 0,allowedIdps:U.map(r=>r.id),create:!0,step:O})}finally{await z.release()}let R=P.apps,V=P.gateway,{combined:ee,plan:te}=P;Xe(e,P.leftovers);let X=await ce(d,ie),ne=Z.filter(r=>!X.includes(r)),j={teamDomain:b,gatewayAud:V.application.aud,appsAud:R.application.aud},se=await Ee(E),c=R.outcome==="created"||V.outcome==="created",F=ne.length>0?"missing":c?"created":se===null?"unrecorded":be(se,j)?t.writeSettings?"asked":null:"changed";if(F){await _e(g,{CLOUDFLARE_ACCESS_TEAM_DOMAIN:j.teamDomain,CLOUDFLARE_ACCESS_APPS_AUD:j.appsAud,CLOUDFLARE_ACCESS_AUD:j.gatewayAud},{flags:t.flags,out:e,announce:!1});let r=F==="asked"?[]:await mt(E,g.deployer,{access:"on",teamDomain:b,...H(D.include??[]).length>0?{emailDomains:H(D.include??[])}:{}});await tt(E,{...j,writtenAt:o()},r)}e.emit({type:"step",step:O,status:"ok"}),$t(e,{teamDomain:b,organization:{created:C,sessionSet:n,globalSession:y.session_duration??null},signInMethods:s,allowedMethods:U,cloudflareAdded:G,pinAdded:L,policy:{id:D.id,name:D.name,created:q,added:[...J(k),...H(k).map(r=>`@${r}`)],emails:J(D.include??[]),domains:H(D.include??[])},gateway:V,apps:R,combined:ee,settings:F?{outcome:"set",reason:F}:{outcome:"kept",reason:null},toLink:S.toLink,emailDomains:w.domains},{gatewayHost:I,base:v,session:a,...et(te)})}async function mt(t,e,o){let a=await it(t);return a?at(t,{organizationId:a.organization.id,type:"access.changed",actor:st(e),data:o}):[]}function ut(t,e){let o=$e(e);o.length!==0&&t.emit({type:"warning",code:"ACCESS_IDP_ANY_CLOUDFLARE_ACCOUNT",step:O,message:`${h(o.map(a=>`${a.name??a.id} (${a.type})`))} ${o.length===1?"is":"are"} open to any Cloudflare account, so left off the EveryApp applications
|
|
17
|
+
Restrict to account members is off, so anyone with a Cloudflare account could sign in there, and Cloudflare doesn't promise the address it asserts is verified: someone who registers a Cloudflare account under a member's address could sign in as that member. Turn Restrict to account members on (Zero Trust \u2192 Settings \u2192 Authentication \u2192 the provider), then run access on again; an application that allowed it before keeps it.`,data:{providers:o.map(a=>({id:a.id,type:a.type,name:a.name??null}))}})}function At(t){return ze("Zero Trust team name",{initial:t,context:["This Cloudflare account has no Zero Trust team yet. People will sign in at","https://<name>.cloudflareaccess.com; the name can't be changed later."],validate:e=>rt.test(e.trim())?null:"Lowercase letters, digits and dashes only."})}function $t(t,e,o){let{gatewayHost:a,base:m}=o,w=[],A=[],g=(i,G)=>{w.push(Q(i,G)),A.push(`${i}${G?` (${G})`:""}.`)},d=i=>{w.push(l.dim(i)),A.push(i)},E=Se(e.allowedMethods);e.organization.created?g(`Zero Trust team ${e.teamDomain}`,`created \xB7 sign-in with ${E}`):e.organization.sessionSet?g(`Zero Trust team ${e.teamDomain}`,`global session now ${e.organization.sessionSet}, for every Access application in the account`):d(`Zero Trust team ${e.teamDomain} \xB7 sign-in with ${E}.`),e.cloudflareAdded&&g("Sign in with Cloudflare","added: members of this Cloudflare account sign in with their Cloudflare account"),e.pinAdded&&g("One-time PIN sign-in","added: Access emails everyone else a code");let{policy:$}=e,p=[...$.emails,...$.domains.map(i=>`@${i}`)];$.created?g(`Access policy "${$.name}"`,`lets in ${h(p)}`):$.added.length>0?g(`Access policy "${$.name}"`,`now also lets in ${h($.added)}`):d(`Access policy "${$.name}" lets in ${h(p)}.`);let I=o.appsWithRoutes>0?`public routes of ${x(o.appsWithRoutes,"app")} let through${o.appsWithMcp>0?`, /mcp on ${x(o.appsWithMcp,"app host")}`:""}`:o.appsWithMcp>0?`/mcp on ${x(o.appsWithMcp,"app host")} let through`:"no app has public routes or /mcp",v="MCP, the OAuth endpoints and /health let through",S=i=>i.outcome==="updated"&&i.signInAdded.length>0?" \xB7 sign-in methods added":"",u=i=>d(`Access in front of ${i} left as it is (see the warning above).`);if(e.combined){let i=`${a} and *.${m}`;e.gateway.outcome==="skipped"?u(i):e.gateway.outcome==="unchanged"?d(`Access in front of ${i} is as it should be.`):g(`Access in front of ${i}`,`${e.gateway.outcome}${S(e.gateway)} \xB7 ${v} \xB7 ${I}`)}else e.gateway.outcome==="skipped"?u(a):e.gateway.outcome==="unchanged"?d(`Access in front of ${a} is as it should be.`):g(`Access in front of ${a}`,`${e.gateway.outcome}${S(e.gateway)} \xB7 ${v}`),e.apps.outcome==="skipped"?u(`*.${m}`):e.apps.outcome==="unchanged"?d(`Access in front of *.${m} is as it should be (${I}).`):g(`Access in front of *.${m}`,`${e.apps.outcome}${S(e.apps)} \xB7 ${I}`);if(e.settings.outcome==="set"){let i=e.settings.reason==="changed"?" \xB7 an application's AUD tag had changed":e.settings.reason==="unrecorded"?" \xB7 recorded, so a rerun can tell when they go stale":"";g("Gateway settings",`${Z.join(", ")} \xB7 one new version${i}`)}else d("Gateway settings kept: they name these applications already (--write-settings writes them again).");let y=e.allowedMethods.every(i=>i.type===Be),f=e.allowedMethods.length>1,_=f?"Access asks them to sign in first, with their Cloudflare account if they are a member of this Cloudflare account, otherwise with a code emailed to them":y?"Access emails them a code first":"Access asks them to sign in first",C=e.toLink.length>0?`${h(e.toLink)} ${e.toLink.length===1?"signs":"sign"} in once with ${e.toLink.length===1?"their":"their own"} password; ${_}. After that Access alone signs them in.`:null,n=[],b=[];e.emailDomains.length>0&&(n.push(`People at ${h(e.emailDomains)} pass Access, but still need an invitation here, unless they may join on their first sign-in: ${W} secret set CLOUDFLARE_ACCESS_AUTO_JOIN_DOMAINS (${e.emailDomains.join(", ")}).`),b.push({command:`${W} secret set CLOUDFLARE_ACCESS_AUTO_JOIN_DOMAINS`,note:`${e.emailDomains.join(", ")}: people there join as members on their first sign-in`}));let s=e.signInMethods.filter(i=>!e.allowedMethods.includes(i));s.length>0&&n.push(`${h(s.map(i=>`${i.name??i.id} (${i.type})`))} ${s.length===1?"is":"are"} on the team but not allowed on the EveryApp applications: access on allows only the one-time PIN and a Cloudflare provider restricted to this account's members. Allow another on both applications in the dashboard (Zero Trust \u2192 Access controls \u2192 Applications); access on never takes a method off.`),n.push("MCP clients and personal access tokens keep working: the Gateway's /mcp, the OAuth endpoints, /health and each app's public routes are let through without a login (an app host's /mcp only where its manifest asks for it)."),n.push(`Once everyone has signed in through Access, passwords can go: ${W} secret set EMAIL_PASSWORD_SIGN_IN (false).`),b.push({command:`${W} secret set EMAIL_PASSWORD_SIGN_IN`,note:"false, once everyone has linked Access"}),t.emit({type:"done",message:[...A,...C?[`Sign in at https://${a}: ${C}`]:[],...n].join(" "),display:[...w,"",...Ie([{label:"Sign in",value:l.cyan(`https://${a}`)}]),...C?[`${" ".repeat(7+2)}${C}`]:[],...n.map(i=>l.dim(i))].join(`
|
|
18
|
+
`),data:{team:{domain:e.teamDomain,created:e.organization.created,sessionSet:e.organization.sessionSet,globalSession:e.organization.globalSession},signInMethods:e.signInMethods.map(i=>gt(i,e.allowedMethods)),identityProviders:{oneTimePinAdded:e.pinAdded,cloudflareAdded:e.cloudflareAdded},policy:$,applications:{gateway:ue(e.gateway),apps:ue(e.apps),combined:e.combined},settings:{names:[...Z],...e.settings},signIn:{url:`https://${a}`,pending:e.toLink,first:f?"both":y?"pin":"idp"},next:b}})}function gt(t,e){return{id:t.id,type:t.type,name:t.name??null,allowed:e.some(o=>o.id===t.id),...t.type===Ze?{restrictToAccountMembers:t.config?.restrict_to_account_members===!0}:{}}}function ue({application:t,outcome:e,signInAdded:o}){return{id:t.id,aud:t.aud,name:t.name??null,outcome:e,destinations:(t.destinations??[]).map(a=>({uri:a.uri??null,public:(a.overrides??[]).map(m=>m.path_pattern)})),allowedIdps:t.allowed_idps??[],signInAdded:o}}async function St(t){let{out:e}=t,o=t.interactive??le(t.flags.json??!1),a=await ve(t),{cf:m,db:w,install:A}=a;dt(A);let g=pe(A),{gatewayHost:d,appBaseDomain:E}=g,$=await ce(m,ie),p=Z.filter(s=>$.includes(s)),I=re(await oe(m),g),v=t.keepApplications?[]:[...new Map([I.gateway,I.apps].filter(s=>s!==null).map(s=>[s.id,s])).values()],S=v.filter(s=>ye(s.destinations??[],g).foreign.length===0),u=v.filter(s=>!S.includes(s));if(p.length===0&&v.length===0){let s=`Cloudflare Access isn't in front of ${d}. Nothing changed.`;e.emit({type:"done",message:s,display:l.dim(s),data:{removed:!1}});return}let y=s=>s.name??s.id;await Fe({yes:t.flags.yes,interactive:o,confirm:t.confirm,question:`Turn Cloudflare Access off for ${d}?`,unattended:"Turning Access off needs confirmation at a terminal, or --yes",context:[...p.length>0?[`Removes ${h(p)} from the Gateway: passwords sign people in again at once.`]:[],...S.length>0?[`Deletes ${x(S.length,"Access application")}: ${h(S.map(y))}.`]:[],...u.length>0?[`Takes ${d} and *.${E} out of ${h(u.map(y))}, which also covers something else.`]:[],...t.keepApplications&&(I.gateway||I.apps)?["The Access applications stay: Access still asks people to sign in there."]:[],...S.some(K)?["The Gateway's application has Managed OAuth on: AI apps connected through it stop."]:[],"The team, its identity providers and the policy stay."],cancelled:"Cancelled. Access stays on."}),e.emit({type:"step",step:"access.off",status:"start",message:"Turning Cloudflare Access off..."}),p.length>0&&await _e(a,Object.fromEntries(p.map(s=>[s,null])),{flags:t.flags,out:e,announce:!1}),await nt(w,await mt(w,a.deployer,{access:"off"}));let f=[];for(let s of S)await Ue(m,s.id)&&f.push(y(s));let _=[];for(let s of u){let i=ye(s.destinations??[],g).foreign;await Ge(m,s.id,Ne(s,{destinations:i})),_.push(y(s))}e.emit({type:"step",step:"access.off",status:"ok"});let C=[],n=[];if(p.length>0&&(C.push(Q("Gateway settings removed",h(p))),n.push(`Removed ${h(p)} from the Gateway.`)),f.length>0&&(C.push(Q(`${x(f.length,"Access application")} deleted`,h(f))),n.push(`Deleted ${h(f)}.`)),_.length>0&&(C.push(Q(`${d} and *.${E} taken out of ${h(_)}`)),n.push(`Took ${d} and *.${E} out of ${h(_)}.`)),t.keepApplications&&(I.gateway||I.apps)){let s="The Access applications stay: Access still asks people to sign in there, and the Gateway no longer requires it.";C.push(l.dim(s)),n.push(s)}let b=`Passwords sign people in as before. The Zero Trust team, its identity providers and the policy "${Y}" are left as they were.`;e.emit({type:"done",message:[...n,b].join(" "),display:[...C,l.dim(b)].join(`
|
|
19
|
+
`),data:{removed:!0,settings:p,applications:{deleted:S.filter(s=>f.includes(y(s))).map(s=>s.id),trimmed:u.map(s=>s.id),kept:t.keepApplications??!1}}})}async function Ct(t){let{out:e}=t,o=t.now??Date.now,a=await ve(t),{cf:m,db:w,install:A}=a,g=pe(A),{gatewayHost:d,appBaseDomain:E}=g,$=A.deploymentMode==="hosted",p=$?null:await ge(m),I=await ce(m,ie),v=Z.filter(c=>I.includes(c)),S=$?null:await Ee(w),u=p?(await fe(m)).find(c=>c.name===Y)??null:null,y=p?await he(m):[],f=Ce(y),_=f.map(c=>c.id),C=Ae(y),n=p?re(await oe(m),g):{gateway:null,apps:null},b=await pt(w,o()),s=K(n.gateway),i=await Je(w),G=xe(E,i,{managedOAuth:s});p&&ut(e,y);let L=v.length===Z.length&&n.gateway!==null,U=L&&S&&p&&n.apps?be(S,{teamDomain:p.auth_domain.toLowerCase(),gatewayAud:n.gateway.aud,appsAud:n.apps.aud}):null,B=n.gateway!==null&&n.gateway.id===n.apps?.id,T=He({scope:g,found:n,surfaces:i,providerIds:_}),D=n.apps!==null&&!T.paths.includes(`*.${E}`),q=n.gateway!==null&&!T.paths.includes(d),k=c=>c===null?null:!T.signIn.includes(c.id===n.gateway?.id?d:`*.${E}`),z=c=>c===null||u===null||(c.policies??[]).some(F=>F.id===u.id),P=u?[...b.members,...b.invited].filter(c=>!J(u.include??[]).includes(c)):[],R=[];!$&&(!L||U===!1||!D||!q||!z(n.gateway)||!z(n.apps)||P.length>0||p!==null&&(C.cloudflare||C.pin)||k(n.gateway)===!1||k(n.apps)===!1)&&R.push(`${W} access on`);let V=[...C.cloudflare?["a Cloudflare account"]:[],...C.pin?["a one-time PIN"]:[]],ee=$e(y),te=y.filter(c=>!f.includes(c)),X=I.includes(De),ne=`${W} secret set ${De}`,j=u?[...J(u.include??[]),...H(u.include??[]).map(c=>`@${c}`)]:[],se=[{label:"Access",value:$?l.dim("not available on a hosted Gateway"):L?l.green("on"):n.gateway?l.yellow("applications exist, Gateway settings missing"):l.dim("off")},{label:"Team",value:p?`${p.auth_domain}${p.session_duration?l.dim(` \xB7 global session ${p.session_duration}`):""}`:l.dim($?"":"none in this Cloudflare account")},{label:"Lets in",value:u?`${h(j)}${P.length>0?l.yellow(` \xB7 not yet: ${h(P)}`):""}${l.dim(` (policy "${u.name}")`)}`:l.dim(`no policy "${Y}" yet`)},...p?[{label:"Sign in",value:`${f.length>0?`with ${Se(f)}`:l.dim("no sign-in method yet")}${V.length>0?l.yellow(` \xB7 access on adds ${h(V)}`):""}${ee.length>0?l.yellow(" \xB7 open to any Cloudflare account (see the warning)"):""}${te.length>0?l.dim(` \xB7 on the team, not allowed here: ${h(te.map(c=>c.name??c.id))}`):""}`},{label:"Providers",value:`${f.length>0?h(f.map(c=>`${c.name??c.type} ${l.dim(c.id)}`)):l.dim("none allowed")} \xB7 ${X?`pinned in the Gateway (${De})`:l.dim(`any the policy admits; pin them: ${ne} ${f.map(c=>c.id).join(",")||"<ids>"}`)}`}]:[],{label:d,value:n.gateway?`${n.gateway.name??n.gateway.id} \xB7 ${q?"paths as they should be":l.yellow("paths differ")}${k(n.gateway)===!1?l.yellow(" \xB7 sign-in methods differ"):""}${K(n.gateway)?" \xB7 Managed OAuth":""}${z(n.gateway)?"":l.yellow(" \xB7 policy not attached")}`:l.dim("no Access application")},{label:`*.${E}`,value:n.apps?`${n.apps.name??n.apps.id} \xB7 ${D?"public routes as they should be":l.yellow("public routes differ")}${k(n.apps)===!1?l.yellow(" \xB7 sign-in methods differ"):""}${z(n.apps)?"":l.yellow(" \xB7 policy not attached")}`:l.dim("no Access application")},{label:"Settings",value:v.length>0?`${h(v)}${U===!1?l.yellow(" \xB7 name an application that no longer exists: nobody can sign in"):U===!0?l.dim(" \xB7 name the applications above"):l.dim(" (values can't be read back)")}`:l.dim("none")},...b.toLink.length>0&&L?[{label:"To link",value:`${h(b.toLink)} (sign in once with the password through Access)`}]:[]];e.emit({type:"done",message:`Cloudflare Access is ${L?"on":"off"} for ${d}.`,display:[...Ie(se),...R.length>0?["",l.dim("To fix: ")+l.bold(R.join(", "))]:[]].join(`
|
|
20
|
+
`),data:{on:L,hosted:$,team:p?{domain:p.auth_domain,sessionDuration:p.session_duration??null}:null,policy:u?{id:u.id,name:u.name,emails:J(u.include??[]),domains:H(u.include??[]),notYet:P}:null,signIn:p?{methods:y.map(c=>gt(c,f)),cloudflare:!C.cloudflare,pin:!C.pin,openToAnyCloudflareAccount:ee.map(c=>c.id),pinned:X,pinCommand:X?null:`${ne} ${f.map(c=>c.id).join(",")}`}:null,applications:{gateway:n.gateway?{...ue({application:n.gateway,outcome:"unchanged",signInAdded:[]}),inSync:q,signInInSync:k(n.gateway),managedOAuth:K(n.gateway),policyAttached:z(n.gateway)}:null,apps:n.apps?{...ue({application:n.apps,outcome:"unchanged",signInAdded:[]}),inSync:D,signInInSync:k(n.apps),policyAttached:z(n.apps)}:null,combined:B},desired:{apps:G.destinations.map(c=>({uri:c.uri,public:c.overrides.map(F=>F.path_pattern)}))},drift:{...T,settings:U===!1},settings:{names:v,current:U},linkPending:b.toLink,...R.length>0?{fixes:R}:{}}})}export{Kt as a,Qt as b,en as c,wt as d,St as e,Ct as f};
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import{C as z,G as Q,H as B,a as j,b as V,s as P,t as Z,u as Y}from"./chunk-
|
|
1
|
+
import{C as z,G as Q,H as B,a as j,b as V,s as P,t as Z,u as Y}from"./chunk-PDPUGYJW.js";import{a as v}from"./chunk-WVHJIYQ3.js";import{a as O,b as _,c as M,d as D,i as G,j as q,l as L,m as E,o as F,q as U}from"./chunk-GAPQSINH.js";import{c as k,e as x}from"./chunk-DCFHBCCW.js";import{ha as b}from"./chunk-KOBKGQ27.js";import{b as W}from"./chunk-AMCNAKYU.js";import{a as S,b as A,e as I,f as N,g as R,h as T}from"./chunk-I7FNTTUY.js";import{Yc as C,bc as g,c as m,ca as $,k as y}from"./chunk-FQ2A7YAP.js";import{text as ee}from"node:stream/consumers";import w from"chalk";var te={secret:(e,{context:i,optional:n})=>R(e,{context:i,optional:n}),text:(e,{context:i,optional:n,validate:o})=>N(e,{context:i,validate:s=>n&&!s.trim()?null:o(s)}),confirm:A,choose:(e,i,n)=>I(e,i,{context:n})};async function Oe(e,i){await C(e,n=>ne({flags:e,out:n,appId:i}))}async function ne(e){let{out:i,flags:n}=e,o=e.interactive??S(n.json??!1),s=e.prompter??te;ie(e.appId);let t=await re(e),r=await J(t),a=se(r,t);if(o){let h=e.tell??T;for(let X of ae(t,r))h(X)}let c=await ce(t,r,a,e),p=o?await ue(t,r,a,c,s):{},l=de({...c,...p},r),d=Object.keys(l);if(d.length===0&&!r.setup.ready&&!o)throw me(t,r,a);let f=d.length>0?await oe(t,l,e):null,u=f?await J({...t,registry:f.gateway?.bound?.length?await v(t.connection.db,t.connection.install):t.registry}):r;t.deployed&&t.source==="registry"?await V(t.connection.db,{appRowId:t.deployed.rowId,setup:u.setup,deployer:t.connection.deployer},i):t.deployed&&await j(t.connection,{gateway:[],appRowId:t.deployed.rowId},i),ge(t,u,a,d,f,i)}async function oe(e,i,n){try{return await z(e.connection,{manifest:e.manifest,source:e.source,app:e.deployed},i,{...n,...e.deployed&&e.source==="registry"?{setupRecordedBy:e.deployed.rowId}:{}})}catch(o){throw!(o instanceof g)||o.code!=="SECRETS_PARTIALLY_APPLIED"?o:new g(o.code,o.message,{...K(e,"to set what is left"),retryable:!0,data:o.data})}}function K(e,i,n=""){return e.deployed?{rerun:`${m} configure ${e.appId}${n}`,rerunNote:i}:{rerun:`${m} configure${n}`,rerunNote:`in the app's directory, ${i}`}}function ie(e){if(!e?.includes("="))return;let i=e.split("=")[0];throw new g("VALUE_ON_COMMAND_LINE",`${i}=\u2026 looks like a value on the command line, which configure never takes
|
|
2
2
|
It lands in the shell's history and the process list: rotate it if it was real. Nothing was set.`,{fix:`pipe NAME=value lines in (one per line), or export ${i} and add --from-env`})}async function re(e){let i=()=>x({gateway:k(e.flags.gateway),accountId:e.flags["account-id"],interactive:S(e.flags.json??!1),login:{json:e.flags.json,out:e.out,step:"login"},createCf:e.createCf});if(e.appId){let t=await i(),r=await b(t.db,e.appId);if(!r||r.status==="pending")throw new g("APP_NOT_FOUND",`${e.appId} isn't deployed to this Gateway
|
|
3
3
|
An app is configured by name after its first deploy; in its directory, configure works before that too (for the Gateway's settings). Nothing was changed.`,{rerun:`${m} status`,rerunNote:"lists its apps"});let a=Q(r);return{appId:a.id,manifest:a,source:"registry",deployed:{workerName:r.workerName,rowId:r.id},connection:t,registry:await v(t.db,t.install)}}let n=await W(e.cwd??process.cwd());if(!n)throw new g("MANIFEST_NOT_FOUND","No everyapp.config.ts in this directory, and no app named",{fix:`name the app: ${m} configure <app> (${m} status lists them), or run this from its directory`});let o=await i(),s=await b(o.db,n.id);return{appId:n.id,manifest:n,source:"directory",deployed:s&&s.status!=="pending"?{workerName:s.workerName,rowId:s.id}:null,connection:o,registry:await v(o.db,o.install)}}async function J(e){let{cf:i}=e.connection,n=M(await O(i),e.registry),o=e.deployed?await _(i,e.deployed.workerName):null,{report:s,setup:t}=D({manifest:e.manifest,appId:e.appId,gatewayNames:n,secretNames:o,lookup:e.registry}),r=new Set;for(let a of s.settings){let c=a.holder==="gateway"?n:o??[];for(let p of[...a.names,...a.alsoReads])c.includes(p)&&r.add(p)}return{report:s,setup:t,held:r}}function se({report:e},i){let n=t=>t.names.length>0&&(t.holder==="gateway"||i.deployed!==null),o=t=>t.set===!1&&n(t),s=new Set(e.groups.filter(t=>t.met).map(t=>t.group));return{required:e.settings.filter(t=>t.need.kind==="required"&&o(t)),groups:e.groups.filter(t=>!t.met&&t.members.some(r=>r.blocking)).map(t=>({group:t.group,members:t.members.filter(o)})).filter(t=>t.members.length>0),optional:e.settings.filter(t=>o(t)&&!t.blocking&&(t.need.kind==="optional"||t.need.kind==="anyOf"&&s.has(t.need.group))),afterDeploy:e.settings.filter(t=>t.holder==="app"&&t.names.length>0&&i.deployed===null)}}function ae(e,{report:i}){let n=q(e.appId,i.settings).map(o=>!e.deployed&&o.where===e.appId?{...o,status:w.dim("after first deploy")}:o);return[w.dim(`${e.appId}'s settings are held as the Gateway's secrets: an AI key or a capability's client on the Gateway Worker, once for every app; ${e.appId}'s own secrets on its Worker. Changes are live at once, no deploy needed.`),"",...n.length>0?L(n,{app:!1}):[w.dim(`${e.appId} declares no secrets and needs no Gateway settings.`)],""]}function le({report:e},i){return e.settings.find(n=>n.names.includes(i))??e.settings.find(n=>n.alsoReads.includes(i))}function de(e,{report:i}){let n={};for(let o of i.settings)for(let s of[...o.names,...o.alsoReads])e[s]!==void 0&&n[s]===void 0&&(n[s]=e[s]);return n}async function ce(e,i,n,o){let s={},t=(a,c)=>$(a)?Y(a,c):c,r=o.flags["from-env"]?null:await(o.readStdin??pe)();if(r!==null)for(let{name:a,value:c,line:p}of fe(r)){let l=le(i,a);if(!l){let d=/^[A-Z][A-Z0-9_]*$/.test(a)?a:`line ${p} (not shown: it may be a value)`;throw new g("SECRET_NOT_DECLARED",`${e.appId} doesn't declare ${d}
|
|
4
4
|
The piped lines set what its ${e.source==="registry"?"deployed manifest":"everyapp.config.ts"} lists (a provider, a capability or one of its secrets). Nothing was set.`,{fix:`leave it out, or declare it in everyapp.config.ts${e.source==="registry"?" and deploy again":""}; a bare value goes to ${m} secret set NAME`})}if(l.holder==="app"&&!e.deployed)throw new g("APP_NOT_FOUND",`${e.appId} isn't deployed yet
|
|
5
5
|
Its own ${a} can be set after its first deploy. Nothing was set.`,{rerun:`${m} deploy`});if(!c.trim())throw new g("SECRET_EMPTY",`${a} is empty in the piped lines`,{fix:`give ${a} a value, or leave the line out`});s[a]=t(a,c)}if(o.flags["from-env"]){let a=o.env??process.env,c=[...n.required,...n.groups.flatMap(p=>p.members),...n.optional];for(let p of c)for(let l of p.names){if(s[l]!==void 0||i.held.has(l))continue;let d=a[l];d===void 0||!d.trim()||(s[l]=t(l,d),o.out.emit({type:"progress",step:"configure.env",message:`${l} from $${l}`}))}}return s}async function pe(){if(process.stdin.isTTY)return null;let e=await ee(process.stdin);return e.trim()?e:null}function fe(e){let i=[];return e.split(/\r?\n/).forEach((n,o)=>{let s=n.trim();if(!s||s.startsWith("#"))return;let t=/^(?:export\s+)?([A-Za-z_][A-Za-z0-9_]*)\s*=(.*)$/.exec(s);if(!t)throw new g("PIPED_LINE_INVALID",`Line ${o+1} of the piped input isn't NAME=value
|
|
6
6
|
Nothing was set.`,{fix:`pipe NAME=value lines, one per line; a bare value goes to ${m} secret set NAME`});let r=t[2].trim(),a=r.length>=2&&(r.startsWith('"')||r.startsWith("'"))?r[0]:null;a&&r.endsWith(a)&&(r=r.slice(1,-1)),i.push({name:t[1],value:r,line:o+1})}),i}async function ue(e,i,n,o,s){let t={},r=l=>o[l]!==void 0||t[l]!==void 0||i.held.has(l),a=l=>l.names.every(r),c=async(l,d)=>{let f=!0;for(let u of l.names){if(r(u))continue;let h=await H(u,l,s,{optional:d,context:f});f=!1,h&&(t[u]=h)}};if(n.required.length>0||n.groups.length>0){for(let d of n.required)await c(d,!1);for(let d of n.groups){if(d.members.some(a))continue;let f=d.members.length===1?d.members[0]:await s.choose(`Which ${d.group}? One is enough.`,d.members.map(u=>({label:u.label,hint:u.names.join(" + "),value:u})));await c(f,!1)}let l=n.optional.filter(d=>!a(d));if(l.length>0&&await s.confirm(`Set the ${l.length===1?"optional setting":`${l.length} optional settings`} too?`,l.map(f=>E(f)[0])))for(let f of l)await c(f,!0);return t}let p=i.report.settings.filter(l=>l.names.length>0&&(l.holder==="gateway"||e.deployed!==null));if(p.length===0)return t;for(;;){let l=await s.choose(`Everything ${e.appId} needs is set. Change one?`,[...p.map(d=>({label:d.names.join(" + "),hint:`${d.label!==d.names.join("+")?`${d.label} \xB7 `:""}${G(d)}`,value:d})),{label:"No, done",value:null}]);if(!l)return t;for(let d of l.names){let f=await H(d,l,s,{optional:!0,context:d===l.names[0]});f&&(t[d]=f)}}}async function H(e,i,n,{optional:o,context:s}){let t=F(i),r=s?[...E(i),...t?[t]:[],...P(e)]:P(e),a=o?`${e} (Enter to skip)`:e;return($(e)?await n.text(a,{context:r,optional:o,validate:p=>Z(e,p)}):await n.secret(a,{context:r,optional:o})).trim()}function me(e,i,n){let o=[...n.required,...n.groups.map(s=>s.members[0])].flatMap(s=>s.names).filter(s=>!i.held.has(s));return new g("SECRET_VALUE_REQUIRED",`Can't ask for ${e.appId}'s settings without a terminal
|
|
7
7
|
${e.appId} needs ${y(o)}. Run this at a terminal, pipe NAME=value lines in (one per line), or export them under those names and add --from-env (which also takes the variable of any unset optional setting).`,{...K(e,"with the variables exported"," --from-env"),data:{names:o}})}function ge(e,i,n,o,s,t){let{appId:r}=e,{setup:a}=i,c=n.afterDeploy.flatMap(h=>h.names),p=a.ready?[]:U(a).filter(h=>!i.held.has(h)),l=o.length>0?`Set ${y(o)}. `:"",d=[],f,u;a.ready?e.deployed?(f=`${l}${r} is ready`,u=w.green(`${r} is ready.`)):(c.length>0?d.push({command:`${m} deploy`,note:`then ${m} configure ${r} for ${y(c)}`}):d.push({command:`${m} deploy`,note:"in the app's directory"}),f=`${l}${r}'s Gateway settings are set${c.length>0?`; its own ${y(c)} come after its first deploy`:""}`,u=`${r}'s Gateway settings are set.${c.length>0?` Its own ${y(c)} come after its first deploy.`:""}`):(t.emit({type:"warning",code:"APP_NEEDS_SETUP",step:"app.secrets",message:`${r} won't open until ${y(p)} ${p.length===1?"is":"are"} set`,data:{setup:a}}),d.push(e.deployed?{command:`${m} configure ${r}`,note:"at a terminal, with NAME=value lines on stdin, or with --from-env"}:{command:`${m} configure`,note:"in the app's directory: at a terminal, with NAME=value lines on stdin, or with --from-env"}),f=`${l}${r} still needs ${y(p)}`,u=w.yellow(`${r} still needs ${y(p)}.`)),o.length>0&&(u=`${u}
|
|
8
|
-
${w.dim("Live now. No deploy needed.")}`),t.emit({type:"done",message:f,display:u,data:{app:{id:r,deployed:e.deployed!==null,setup:a},set:[...o],...s?{changed:B(s)}:{},...d.length>0?{next:d}:{}}})}export{Oe as
|
|
8
|
+
${w.dim("Live now. No deploy needed.")}`),t.emit({type:"done",message:f,display:u,data:{app:{id:r,deployed:e.deployed!==null,setup:a},set:[...o],...s?{changed:B(s)}:{},...d.length>0?{next:d}:{}}})}export{Oe as a,ne as b,fe as c};
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import{i as L}from"./chunk-QFTBDXLF.js";import{c as k,e as z}from"./chunk-DCFHBCCW.js";import{D as T,N as y,O as h,P as O,Q as F,u as I,z as x}from"./chunk-KOBKGQ27.js";import{a as D}from"./chunk-I7FNTTUY.js";import{Rc as C,c as v,f as A}from"./chunk-FQ2A7YAP.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,i.deployer),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,37 @@
|
|
|
1
|
+
import{a as Or,b as Cr,c as jr,e as Ne}from"./chunk-EP3IQ354.js";import{a as S,b as C,c as Dr,d as Tr,e as Mr,f as Lr,g as xr,h as Ur,i as te,j as Gr}from"./chunk-O64FPLGX.js";import{b as Wr,c as zr}from"./chunk-5IC3ZN52.js";import{a as Nr,d as $r,e as Se}from"./chunk-V7BWZOSZ.js";import{a as _r,b as Pr}from"./chunk-BWNZ6F4F.js";import{b as jt}from"./chunk-PDPUGYJW.js";import{a as zt}from"./chunk-WVHJIYQ3.js";import{a as Tt,b as Mt,d as be,e as Lt,m as xt,q as Ut}from"./chunk-GAPQSINH.js";import{a as Xt,b as er,c as tr,d as rr,e as nr}from"./chunk-4LKLQOM7.js";import{A as Sr,b as ur,c as fr,d as gr,f as wr,g as Re,h as Ae,i as yr,j as hr,m as br,n as vr,p as kr,q as Er,s as Rr,u as Ar,w as Ir,x as ee,y as Ie}from"./chunk-GJK6GAWO.js";import{b as cr,c as pr,d as lr,e as dr,g as mr}from"./chunk-26KS6TD6.js";import{d as Ht,e as qt,f as Qt,g as Yt,m as Zt}from"./chunk-S2G4G73L.js";import{n as Jt}from"./chunk-BCTEWNN4.js";import{a as ir,b as sr,c as ar,d as or,g as Ee}from"./chunk-KQM6ZUX5.js";import{R as vt}from"./chunk-QKHLRLK3.js";import{a as ve,b as Wt}from"./chunk-ORGV2NNT.js";import{c as Gt}from"./chunk-KVCL64LI.js";import{a as _,b as H,e as he,f as T,g as Dt,h as M}from"./chunk-3EADVHFN.js";import{c as $,d as j,e as Bt,h as q,i as Kt}from"./chunk-HJGZGZFE.js";import{b as Ft}from"./chunk-LI3YLKLC.js";import{g as yt}from"./chunk-EQLY5I46.js";import{a as It,c as Ct,e as _t}from"./chunk-DCFHBCCW.js";import{_ as St,fa as Nt,ha as $t,ia as Ot,m as kt,n as Et,o as Rt,p as At}from"./chunk-KOBKGQ27.js";import{f as ye}from"./chunk-TIYSZWP5.js";import{a as X,e as Vt,f as ke}from"./chunk-AMCNAKYU.js";import{a as ft,b as gt,h as wt}from"./chunk-I7FNTTUY.js";import{Ab as Je,Bc as ut,Eb as Ze,Fb as Xe,H as Ye,Ic as ht,Jb as et,Kb as tt,Kc as bt,Qb as rt,Rb as fe,Sb as nt,Tb as ge,Ub as it,Vb as st,Xb as at,Yb as ot,Yc as Pt,Zb as Z,b as me,bc as g,c as N,cc as ct,d as I,dc as pt,ec as lt,fc as dt,hc as z,k as ue,sc as mt,wc as we}from"./chunk-FQ2A7YAP.js";import an from"node:path";import yn from"chalk";async function Vr({whoami:e,discovery:n,out:i,offer:t}){let{deps:a}=t,s=t.accountId?["--account-id",t.accountId]:[];if(!a.interactive){let m=await hn(e,t).catch(()=>null),h=[N,"setup","--domain",m??"<hostname>",...s].join(" ");throw new ct("install_gateway",`Install a Gateway first: ${bn(n)}
|
|
2
|
+
Apps deploy behind one. Setup needs a person once, to create the owner account.`,void 0,{rerun:h,data:{accounts:n.probed,...m?{domain:m}:{}}})}let r=await ye({whoami:e,flag:t.accountId,interactive:!0}),o=r.name??r.id,c=await Se(a.createCf(r.id),r.id),w=`apps.${c.length===1?c[0]:await a.prompts.pickZone(c)}`;if(t.yes)wt(yn.dim(`${o} has no Gateway yet, so --yes installs one at ${w} first.`));else if(!await(t.confirm??gt)(`Install a Gateway at ${w}?`,[`${o} has no Gateway yet. Apps deploy behind one, so it's installed first.`]))throw new pt(`Cancelled. Nothing deployed.
|
|
3
|
+
Apps deploy behind a Gateway. To install one elsewhere: ${[N,"setup","--domain","<hostname>",...s].join(" ")}`);return await $r({whoami:e,discovery:n,flags:{domain:w,"account-id":r.id,"force-dns":t.forceDns,yes:t.yes,verbose:t.verbose},out:i,deps:a}),It({whoami:e,createCf:a.createCf,accountId:r.id,interactive:!0})}async function hn(e,n){let i=await ye({whoami:e,flag:n.accountId,interactive:!1});return`apps.${(await Se(n.deps.createCf(i.id),i.id))[0]}`}function bn(e){let n=e.probed.map(i=>i.name??i.id);return n.length===1?`${n[0]} has none yet`:`none of ${n.join(", ")} has one yet`}import vn from"node:fs/promises";var Br=64,kn=["d1","kv","hyperdrive","r2","vectorize"];function En(e){return kn.includes(e)}function Rn(e,n){let i=structuredClone(e),t=i.name===$.workerName,a=i.env??{};for(let[c,l]of Object.entries(a))An(c,l,n);for(let c of i.triggers??[])c.type==="queue"&&In(c,n);n.shared&&a.EVERY_APP_ORG_ID&&(delete a.EVERY_APP_ORG_ID,a.EVERYAPP_SHARED={type:"text",value:"1"});let s=JSON.stringify([$.publicKey]),r=$e(i,c=>c===s?JSON.stringify(n.identityPublicKeys):c.replaceAll($.gatewayUrl,()=>n.gatewayUrl).replaceAll($.accountId,()=>n.accountId).replaceAll($.organizationId,()=>n.organizationId).replaceAll($.workerName,()=>n.workerName));if(t&&n.deletedDurableObjects?.length){let c=r.exports??={};for(let l of n.deletedDurableObjects){if(c[l])throw new g("APP_POLICY",`Durable Object class ${l} is both exported by the build and being deleted; declare it in everyapp.config.ts, or stop exporting it.`);c[l]={type:"durable-object",state:"deleted"}}}let o=qr(r);if(o.length>0)throw new g("INSTALL_PLACEHOLDER_LEFT",`The build of ${String(r.name)} still holds a build placeholder after installing it, at ${o.join(", ")}. Build the Worker from everyAppWorker() in cloudflare.config.ts, and leave its names, keys and ids to the deploy.`);return $n(r),r}async function Fr({cwd:e,target:n}){for await(let{file:i,config:t}of Jt(e))await vn.writeFile(i,`${JSON.stringify(Rn(t,n),null,2)}
|
|
4
|
+
`)}function An(e,n,i){if(n.type==="json"){Sn(e,n,i);return}if(n.type==="secrets-store-secret"){Nn(e,n,i);return}let t=String(n.type);if(t==="queue"){if(n.name!==j(e))return;n.name=Hr(e,i,`The build binds Queue ${e}`);return}if(!En(t))return;let a=j(e);if(n[t==="kv"||t==="hyperdrive"?"id":"name"]!==a)return;let r=i.resources[t]?.[e];if(!r)throw new g("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(n,r)}var Kr=j("");function In(e,n){for(let i of["name","deadLetterQueue"]){let t=e[i];if(typeof t!="string"||!t.startsWith(Kr))continue;let a=t.slice(Kr.length);e[i]=Hr(a,n,`The build ${i==="name"?"consumes":"sends failed messages to"} Queue ${a}`)}}function Hr(e,n,i){let t=n.resources.queues?.[e];if(!t)throw new g("INSTALL_INPUTS_MISSING",`${i}, which the deploy didn't provision`,{fix:"declare it in everyapp.config.ts's resources.queues"});return t.name}function Sn(e,n,i){let t=n.value;if(typeof t!="object"||t===null||Array.isArray(t)||t.id!==j(e))return;let a=i.resources.aiGateway?.[e];if(!a)throw new g("INSTALL_INPUTS_MISSING",`The build binds ${_["ai-gateway"]} ${e}, which the deploy didn't provision`,{fix:"declare it in everyapp.config.ts's resources.aiGateway"});n.value={id:a.id,accountId:a.accountId,url:a.url}}function Nn(e,n,i){if(n.secretName!==j(e))return;let t=i.resources.secretsStore?.[e];if(!t)throw new g("INSTALL_INPUTS_MISSING",`The build binds ${_["secrets-store-secret"]} ${e}, which the deploy didn't provision`,{fix:"declare it in everyapp.config.ts's resources.secretsStore"});n.storeId=t.storeId,n.secretName=t.secretName}function $e(e,n){return typeof e=="string"?n(e):Array.isArray(e)?e.map(i=>$e(i,n)):e&&typeof e=="object"?Object.fromEntries(Object.entries(e).map(([i,t])=>[i,$e(t,n)])):e}function qr(e,n=""){let i=[$.workerName,$.accountId,$.organizationId,$.gatewayUrl,$.publicKey].flatMap(a=>[a,JSON.stringify(a).slice(1,-1)]),t=a=>i.some(s=>a.includes(s));return typeof e=="string"?t(e)?[n||"(root)"]:[]:e&&typeof e=="object"?Object.entries(e).flatMap(([a,s])=>{let r=n?`${n}.${a}`:a;return t(a)?[r]:qr(s,r)}):[]}function $n(e){let n=[...Object.entries(e.env??{}),...Object.entries(e.exports??{})].filter(([,i])=>i.type==="workflow");for(let[i,t]of n){let a=String(t.name);if(a.length>Br)throw new g("WORKFLOW_NAME_TOO_LONG",`${i} would be the Workflow "${a}", longer than Cloudflare's ${Br} characters`,{fix:"shorten its binding name in everyapp.config.ts"})}}async function Qr({cf:e,names:n,appId:i,out:t}){let a=[];for(let s of[...new Set(n)].sort()){try{if(await Wr(e,s))continue;await zr(e,s)}catch(r){if(z(r,"already_exists"))continue;throw z(r,"r2_not_enabled")?new g("R2_NOT_ENABLED",`R2 isn't enabled in this Cloudflare account, and ${i} needs an R2 bucket (${s})
|
|
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:I()}):r}a.push(s),t.emit({type:"progress",step:"app.build",message:`Created R2 bucket "${s}".`,data:{bucket:s}})}return a}async function Ce({cf:e,gatewayDb:n,registration:i},t){let a=t?.name??"",s=t?.workerName??i.workerName;if(!(await H(n,i.workerName)).some(o=>o.kind==="worker"&&o.binding===a)){if(await Gt(e,s)!==null)throw new g("WORKER_NAME_TAKEN",`A Worker named ${s} 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:I()});await T(n,i.workerName,{kind:"worker",binding:a,name:s,resourceId:s})}}async function Zr(e){let{cf:n,registration:i,manifest:t}=e;Pn(i.workerName,t);let a=await H(e.gatewayDb,i.workerName),s=await On({...e,owned:a}),r=async()=>{let u=t.resources?.aiGateway??[];if(u.length===0)return{};let f={};for(let{name:b,...R}of u){let O=await Mn({...e,owned:a,binding:b,settings:R});f[b]={id:O,accountId:e.accountId,url:Bt(e.accountId,O)}}return{aiGateway:f}},o=(u,f)=>Q({...e,owned:a,kind:u,binding:f,name:Oe(i,u,f),find:u==="d1"?b=>kt(n,b):b=>Rt(n,b),create:u==="d1"?b=>Et(n,b):b=>At(n,b)}),c={};for(let u of t.resources?.d1??[])c[u]={name:Oe(i,"d1",u),id:await o("d1",u)};let l={};for(let u of t.resources?.kv??[])l[u]={id:await o("kv",u)};let w=t.resources?.r2??[],m=w.length?{r2:Object.fromEntries(w.map(u=>[u,{name:Oe(i,"r2",u)}]))}:{},h=t.resources?.hyperdrive??[],p=async()=>Dn({...e,owned:a});if(h.length===0)return{d1:c,kv:l,...m,...await Yr(e,a),...await p(),...await r(),...s};let y=new Map(h.map(({name:u})=>{let f=Ur(e.secrets??{},t,u);return[u,f?te(f.url,f.variable):null]})),E={};for(let{name:u,caching:f="off"}of h)E[u]={id:await xn({...e,owned:a,binding:u,name:Ln(i.workerName,u),origin:y.get(u)??null,originVariables:Lr(u,h.length),caching:f})};return{d1:c,kv:l,...m,hyperdrive:E,...await Yr(e,a),...await p(),...await r(),...s}}async function On(e){let{cf:n,registration:i,owned:t,manifest:a}=e,s=(a.resources?.secretsStore??[]).map(p=>p.name);if(s.length===0)return{};let r=await br(n),o=t.find(p=>p.kind==="secrets-store-secret"&&p.resourceId)?.resourceId?.split("/")[0],c=r.find(p=>p.id===o)??vr(r);if(!c)throw new g("SECRETS_STORE_MISSING",`This Cloudflare account has no Secrets Store, and ${a.id} binds a Secrets Store secret (${s[0]})
|
|
7
|
+
Make one once in the dashboard: Secrets Store \u2192 Create store (cf can't create a store).`,{fix:"create a store in the Cloudflare dashboard (Secrets Store)",rerun:I()});let l=e.secrets??{},w=new Map;for(let p of s){let y=Z(i.workerName,p);w.set(y,await kr(n,c.id,y))}let m=s.filter(p=>!w.get(Z(i.workerName,p))&&!l[p]);if(m.length>0){let p=m.map(Mr);throw new g("SECRETS_STORE_VALUE_MISSING",`${m.join(", ")} ${m.length===1?"needs its":"need their"} Secrets Store ${m.length===1?"secret's value":"secrets' values"}
|
|
8
|
+
Creating ${m.length===1?"the secret":"each secret"} in the store "${c.name}" needs ${m.length===1?"it":"them"}.`,{fix:`set ${p.join(", ")} in ${S}`,rerun:I()})}let h={};for(let p of s){let y=Z(i.workerName,p);await Q({...e,kind:"secrets-store-secret",binding:p,name:y,find:async E=>{let u=w.get(E);return u?`${c.id}/${u.id}`:null},create:async E=>`${c.id}/${await Er(n,c.id,E,l[p])}`}),h[p]={storeId:c.id,secretName:y}}return{secretsStore:h}}async function Yr(e,n){let i=e.manifest.resources?.queues??[];if(i.length===0)return{};let{cf:t,registration:a}=e,s=e.sleep??(l=>new Promise(w=>setTimeout(w,l))),r,o=async l=>(await(r??=Ae(t))).find(w=>w.queue_name===l)?.queue_id??null,c={};for(let{name:l}of i){let w=fe(a.workerName,l),m=n.find(p=>p.kind==="queue"&&p.binding===l&&p.name===w)?.resourceId,h=await Q({...e,owned:n,kind:"queue",binding:l,name:w,find:async p=>{if(m)for(let y=0;y<Cn;y+=1){y>0&&await s(Jr);let E=await yr(t,m).catch(u=>{if(z(u,"unknown"))return null;throw u});if(E?.queue_name===p)return E.queue_id}return o(p)},create:async p=>{let y=await hr(t,p);for(let E=0;E<_n&&!(await Ae(t)).some(u=>u.queue_id===y);E+=1)await s(Jr);return y}});c[l]={name:w,id:h}}return{queues:c}}var Cn=3,_n=15,Jr=1500;function Pn(e,n){for(let{name:i}of n.resources?.queues??[]){let t=fe(e,i);if(!nt(t))throw new g("QUEUE_NAME_INVALID",`${i} would be the queue "${t}", which Cloudflare refuses
|
|
9
|
+
A queue's name is at most ${rt} lowercase letters, digits and hyphens, starting and ending with a letter or digit.`,{fix:"shorten its binding name in everyapp.config.ts",rerun:I()})}}async function Dn(e){let{cf:n,registration:i,manifest:t}=e,a=t.resources?.vectorize??[];if(a.length===0)return{};let s=a.map(o=>({binding:o.name,name:it(i.workerName,o.name),shape:Tn(o)}));for(let{binding:o,name:c}of s)if(c.length>ge)throw new g("VECTORIZE_NAME_TOO_LONG",`${o} would be the Vectorize index "${c}", longer than Cloudflare's ${ge} characters`,{fix:"shorten its binding name in everyapp.config.ts"});let r={};for(let{binding:o,name:c,shape:l}of s){let w=null;await Q({...e,kind:"vectorize",binding:o,name:c,find:async h=>(w=await Rr(n,h),w?.name??null),create:async h=>(await Ar(n,h,l)).name});let m=w;if(m&&!Ir(m,l))throw new g("VECTORIZE_CONFIG_MISMATCH",`Vectorize index "${c}" has ${ee(m.config??{})}, but everyapp.config.ts declares ${ee(l)} for ${o}
|
|
10
|
+
An index can't be reshaped once it is created.`,{fix:`rename the binding in everyapp.config.ts to make a new one, or change ${o} back to ${ee(m.config??{})}`,rerun:I()});r[o]={name:c}}return{vectorize:r}}function Tn(e){return e.preset!==void 0?{preset:e.preset}:{dimensions:e.dimensions,metric:e.metric}}async function Mn(e){let{cf:n,registration:i,binding:t,settings:a,onChanged:s}=e,r=ot(i.workerName,t);if(!at(r))throw new g("INVALID_MANIFEST",`resources.aiGateway: ${t} would be the AI Gateway "${r}", which Cloudflare refuses (lowercase letters and digits joined by single hyphens, at most ${st} characters)`,{fix:"shorten the binding name in everyapp.config.ts"});let o={found:null};await Q({...e,kind:"ai-gateway",name:r,find:async l=>(o.found=await lr(n,l),o.found?.id??null),create:async l=>(await dr(n,l,a)).id});let c=o.found;if(c&&!pr(c,a)){await mr(n,c,a);let l=M({kind:"ai-gateway",name:r}),w=cr(a);(c.collect_logs??!1)!==w.collectLogs&&s?.(w.collectLogs?`Turned on request logs on ${l} (collectLogs).`:`Turned off request logs on ${l} (collectLogs: false).`),(c.cache_ttl??0)!==w.cacheTtl&&s?.(w.cacheTtl===0?`Turned off response caching on ${l} (no cacheTtl).`:`Set ${l} to cache responses for ${w.cacheTtl} s (cacheTtl).`)}return r}function Ln(e,n){return`${e}${tt}${n.toLowerCase().replaceAll("_","-")}`}async function xn(e){let{cf:n,gatewayDb:i,registration:t,owned:a,binding:s,name:r,origin:o,originVariables:c,caching:l}=e,{onRecreated:w,onChanged:m}=e,{workerName:h}=t,p={kind:"hyperdrive",binding:s,name:r},y=M(p),E=Tr(s),u=a.find(R=>R.kind==="hyperdrive"&&R.binding===s&&R.name===r),f=await ur(n,r),b=async R=>{let O=o!==null&&!Re(R,o),L=!wr(R,l);!O&&!L||(await gr(n,R.id,{...O?{origin:o}:{},...L||l==="off"?{caching:l}:{}}),O&&m?.(`Pointed ${y} at the database in ${S}.`),L&&m?.(l==="off"?`Turned off query caching on ${y} (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 ${y} (caching: "default").`))};if(u?.resourceId){if(f?.id===u.resourceId)return await b(f),f.id;if(f)throw en(p,u.resourceId);w?.(y,p.kind)}else if(u){if(f)return await T(i,h,{...p,resourceId:f.id}),await b(f),f.id}else if(f){if(o&&Re(f,o))return await T(i,h,{...p,resourceId:f.id}),m?.(`Adopted ${y}, which connects to the database in ${S}.`),await b(f),f.id;throw new g("RESOURCE_NAME_TAKEN",`A Hyperdrive config named "${r}" already exists in this Cloudflare account
|
|
11
|
+
No deploy of this app created it.`,{fix:`to use it, set ${E} in ${S} to the URL of the database it connects to; otherwise delete or rename it`,rerun:I()})}if(!o)throw new g("HYPERDRIVE_ORIGIN_MISSING",`${s} needs the database its Hyperdrive config connects to
|
|
12
|
+
Creating the config needs its URL, from ${S} on the machine that deploys; nothing in that file reaches the Worker.`,{fix:`set ${xr(c)} in ${S} to postgres://<user>:<password>@<host>:<port>/<database>`,rerun:I(),data:{binding:s,variables:c,file:S}});return Xr(e,p,()=>fr(n,r,o,l))}function Oe(e,n,i){let t=e.resources[n][i];if(!t||et(t))throw new g("RESOURCE_NAME_MISSING",`The Gateway assigned no usable ${_[n]} name for binding ${i}`,{rerun:`${N} setup`,rerunNote:"to upgrade the Gateway"});return t}async function Q(e){let{gatewayDb:n,registration:i,owned:t,kind:a,binding:s,name:r,find:o,create:c,onRecreated:l}=e,{workerName:w}=i,m={kind:a,binding:s,name:r},h=t.find(y=>y.kind===a&&y.binding===s&&y.name===r),p=await o(r);if(h?.resourceId){if(p===h.resourceId)return p;if(p)throw en(m,h.resourceId);l?.(M(m),a)}else if(h){if(p)return await T(n,w,{...m,resourceId:p}),p}else if(p)throw new g("RESOURCE_NAME_TAKEN",`${/^[AEIOU]/.test(_[a])?"An":"A"} ${_[a]} named "${r}" already exists in this Cloudflare account
|
|
13
|
+
No deploy of this app created it; it may belong to another Gateway, app or project.`,{fix:"delete or rename it",rerun:I()});return Xr(e,m,()=>c(r))}async function Xr({gatewayDb:e,registration:n,onCreated:i},t,a){let{workerName:s}=n;await T(e,s,{...t,resourceId:null});let r;try{r=await a()}catch(o){throw z(o,"already_exists")?(await Dt(e,s,{kind:t.kind,binding:t.binding}),new g("RESOURCE_NAME_TAKEN",`${M(t)} was created by someone else while this deploy was creating it`,{fix:"delete or rename it",rerun:I()})):o}return await T(e,s,{...t,resourceId:r}),i?.(M(t),t.kind),r}function en(e,n){return new g("RESOURCE_REPLACED",`${M(e)} isn't the one this app created
|
|
14
|
+
That one (${n}) was deleted, and this one was created by someone else since.`,{fix:"delete or rename it",rerun:I()})}function _e(e,n){return(n.resources?.workflows??[]).map(i=>({binding:i.name,className:i.className,name:Kt(e,i.name),worker:i.worker?q(e,i.worker):e}))}async function tn({cf:e,workerName:n,names:i}){for(let t of i){let a=await Ie(e,t);if(a&&a.script_name!==n)throw new g("WORKFLOW_NAME_TAKEN",`A Workflow named "${t}" already exists in this Cloudflare account
|
|
15
|
+
It runs on Worker ${a.script_name??"(unknown)"}, not ${n}; deploying would take it over.`,{fix:"delete or rename it",rerun:I()})}}async function rn({cf:e,workerName:n,previousManifest:i,names:t}){let a=Je.safeParse(i);if(!a.success)return[];let s=[];for(let r of _e(n,a.data))t.includes(r.name)||(await Ie(e,r.name))?.script_name===r.worker&&s.push(r);return s}import{execa as Un}from"execa";var Gn=10*6e4;function re({packageName:e,binName:n,env:i={},missing:t}){return async({args:a,cwd:s,env:r})=>{let o;try{o=(await mt(s,e,n)).binPath}catch{throw t()}let c=await Un(process.execPath,[o,...a],{cwd:s,env:{NODE_NO_WARNINGS:"1",...i,...r},stdin:"ignore",reject:!1,timeout:Gn});return{exitCode:c.timedOut?124:c.exitCode??1,stdout:String(c.stdout??""),stderr:String(c.stderr??"")}}}async function ne({run:e,args:n,cwd:i,databaseUrl:t,reasonPatterns:a,failed:s}){let{password:r}=te(t,C),o=await e({args:n,cwd:i,env:{[C]:t}});if(o.exitCode===0)return o.stdout;let l=Gr(`${o.stderr}
|
|
16
|
+
${o.stdout}`,[t,r,encodeURIComponent(r)]).split(`
|
|
17
|
+
`).map(m=>m.trim()).filter(Boolean),w=a.map(m=>l.find(h=>m.test(h))).find(m=>m!==void 0);throw s(w??l.at(-1)??`exit ${o.exitCode}`)}function Wn(){return re({packageName:"drizzle-kit",binName:"drizzle-kit",missing:()=>new g("DRIZZLE_KIT_MISSING",`Postgres migrations need drizzle-kit, which isn't installed
|
|
18
|
+
Nothing was migrated or uploaded.`,{fix:"add drizzle-kit to devDependencies, then deploy again"})})}async function nn({cwd:e,databaseUrl:n,config:i,run:t=Wn()}){await ne({run:t,args:["migrate",...i?["--config",i]:[]],cwd:e,databaseUrl:n,reasonPatterns:[/error/i],failed:a=>new g("MIGRATION_FAILED",`drizzle-kit couldn't migrate the Postgres database
|
|
19
|
+
${a}. Nothing was uploaded.`,{fix:`check ${C} in ${S} and the migrations`})})}function zn(){return re({packageName:"prisma",binName:"prisma",env:{PRISMA_HIDE_UPDATE_MESSAGE:"1"},missing:()=>new g("PRISMA_MISSING",`Prisma migrations need prisma, which isn't installed
|
|
20
|
+
Nothing was migrated or uploaded.`,{fix:"add prisma to devDependencies, then deploy again"})})}async function sn({cwd:e,databaseUrl:n,config:i,run:t=zn()}){return[...(await ne({run:t,args:["migrate","deploy",...i?["--config",i]:[]],cwd:e,databaseUrl:n,reasonPatterns:[/\bP\d{4}\b/,/error/i],failed:s=>new g("MIGRATION_FAILED",`prisma migrate deploy couldn't migrate the Postgres database
|
|
21
|
+
${s}. Nothing was uploaded.`,{fix:`check ${C} in ${S}, prisma.config.ts (its datasource reads it) and the migrations`})})).matchAll(/^Applying migration `([^`]+)`/gm)].map(s=>s[1])}var jn=new Set(["pending","binding"]);async function on(e){let n={rollback:null};try{return await Vn(e,n)}catch(i){throw lt(i,n.rollback)}}async function Vn(e,n){let{cwd:i,out:t}=e,a=e.interactive??ft(e.json??!1),s=e.release,r=s?.manifest??e.manifest??await X(i),o=s?.dir??i;s&&Fn(r);let c=r.migrations?.dialect==="postgresql",l=c||r.resources?.hyperdrive?.length||r.resources?.secretsStore?.length?await Dr(i):{};if(c&&!l[C])throw new g("POSTGRES_URL_MISSING",`${r.id} needs a Postgres URL to migrate its database
|
|
22
|
+
Format: postgres://<user>:<password>@<host>:<port>/<database>`,{fix:`set ${C} in ${S}, then deploy again`});let w=s?null:await Pr(i);if(!s&&!w)throw new g("MISSING_CLOUDFLARE_CONFIG",_r);w&&!w.usesEveryAppWorker&&t.emit({type:"warning",code:"NONSTANDARD_CLOUDFLARE_CONFIG",message:`cloudflare.config.ts doesn't use everyAppWorker()
|
|
23
|
+
The deploy checks the Worker it builds against the app policy.`});let m=e.offerInstall,h=Xt(e.reconcile,t,e.verbose);t.emit({type:"step",step:"app.connect",status:"start",message:"Finding your Gateway..."});let{cf:p,accountId:y,accountName:E,databaseId:u,db:f,install:b,gatewayUrl:R,deployer:O}=await _t({gateway:e.gateway,accountId:e.accountId,interactive:a,login:{json:e.json,out:t,step:"app.login"},createCf:e.createCf,onNoGateway:m?({whoami:G,discovery:oe})=>Vr({whoami:G,discovery:oe,out:t,offer:{accountId:e.accountId,yes:m.yes,confirm:m.confirm,forceDns:e.forceDns,verbose:e.verbose,deps:{...Nr({gateway:h,interactive:a}),...e.createCf?{createCf:e.createCf}:{},...m.setup}}}):void 0});t.emit({type:"step",step:"app.connect",status:"ok",data:{gatewayUrl:R}});let L=await zt(f,b);Kn(r,L,R);let[pn,Pe]=await Promise.all([St(f),$t(f,r.id)]),De=!Pe||jn.has(Pe.status);t.emit({type:"step",step:"app.deploy",status:"ok",message:`Deploying ${r.id}${s?` ${s.release.version} from ${Ne(s.origin)}`:""} to ${R}.`,data:{appId:r.id,organizationName:pn?.organization.name??E,firstDeploy:De,gatewayUrl:R,gatewayHost:new URL(R).host,...s?{version:s.release.version,origin:Ne(s.origin),release:{version:s.release.version,gitSha:s.release.gitSha,origin:s.origin,sha256:s.release.sha256}}:{}}}),await Zt(b,h.source);let Te=b.jwtPublicKey;if(!Te)throw new g("IDENTITY_KEY_UNKNOWN",`The Gateway is missing its sign-in public key
|
|
24
|
+
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:A,organization:x,hasOwner:ln,deployerGranted:dn}=await er(f,{manifest:r,install:b,deployer:O,accountName:E}),P=A.app.hostname,v=A.app.workerName,Me=A.kind!=="existing",Le=Xe(r,A.app.tier);if(Le.length>0)throw new g("TIER_POLICY",`${r.id} can't be deployed as configured
|
|
25
|
+
${Le.join(`
|
|
26
|
+
`)}`,{fix:"change everyapp.config.ts, then deploy again"});let ie=ht(r),se=bt(r);t.emit({type:"step",step:"app.register",status:"ok",message:`${Me?"Registered":"Updating"} ${r.id} as ${v} at https://${P} (${A.app.status}).`,data:{appId:r.id,workerName:v,hostname:P,status:A.app.status,existingApp:!Me,firstDeploy:De,defaultAccess:A.app.isDefault,deployerAccess:dn,hasOwner:ln,publicRoutes:ie,mcp:se,scope:A.app.scope,organizationId:x.id,organizationName:x.name,gatewayUrl:R}});let{outsideBase:V,newHost:xe}=await Ht({cf:p,out:t,install:b,hostname:P,forceDns:e.forceDns,cfAsks:a&&t.verbose}),B=await yt({db:f,out:t},{workerName:v,appId:r.id,purpose:"app.deploy"}),K,ae,Y=[];try{let G=Hn(A,r,e.allowDeleteDurableObjectData??!1),oe=await qn({cf:p,plan:A,workerName:v,manifest:r,allowDelete:e.allowDeleteWorkflows??!1}),We=!1,ce={cf:p,gatewayDb:f,registration:{workerName:v,resources:A.resources},onCreated:(d,k)=>{t.emit({type:"progress",step:"app.resources",message:`Created ${d}.`}),k==="hyperdrive"&&(We=!0)},onRecreated:(d,k)=>t.emit({type:"warning",code:"RESOURCE_RECREATED",step:"app.resources",message:`The ${k==="d1"?"database":_[k]} ${r.id} used before is gone; creating a new, empty one
|
|
27
|
+
${d} no longer exists in this Cloudflare account.`}),onChanged:d=>t.emit({type:"progress",step:"app.resources",message:d})},D=(r.workers??[]).map(d=>({name:d.name,workerName:q(v,d.name)}));t.emit({type:"step",step:"app.resources",status:"start",message:"Preparing the app's resources..."}),await Ce(ce);for(let d of D)await Ce(ce,d);let W=await Ot(f,A.app.id),pe=Ee(r).receives;!pe&&W.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
|
|
28
|
+
Its addresses (${W.inbound.join(", ")}) stay on the Gateway until you clear them.`,data:{rerun:`${N} email unset inbound`}});let F=await ir({cf:p,gatewayDb:f,accountId:y,workerName:v,addresses:pe?W.inbound:[],interactive:a,enableRouting:e.enableEmailRouting,confirm:e.confirm}),ze=await Zr({...ce,manifest:r,secrets:l,accountId:y});if(t.emit({type:"step",step:"app.resources",status:"ok",message:"The app's resources are ready."}),We){let d=r.resources?.hyperdrive?.some(k=>k.caching==="default")?"default":"off";t.emit({type:"step",step:"app.hyperdrive",status:"ok",message:"Created the app's Hyperdrive config.",data:{caching:d}})}!s&&r.install!==!1&&(t.emit({type:"step",step:"app.install",status:"start",message:"Installing dependencies..."}),await(e.installDeps??ut)({cwd:i,description:"Installing dependencies...",install:r.install,verbose:e.verbose??!1}),t.emit({type:"step",step:"app.install",status:"ok"}));let je={workerName:v,organizationId:x.id,accountId:y,gatewayUrl:R,identityPublicKeys:[Te],resources:ze,deletedDurableObjects:G,helperWorkers:D.map(d=>d.workerName),declared:r.resources};s||(t.emit({type:"step",step:"app.build",status:"start",message:"Building..."}),await Cr({cwd:i,cf:p,buildCommand:r.build,verbose:e.verbose??!1})),await Fr({cwd:o,target:je});let{workflows:Ve,helperWorkflows:Be,r2Buckets:mn}=await jr({cwd:o,inputs:je});await Qr({cf:p,names:mn,appId:r.id,out:t});for(let d of[{workerName:v,names:Ve},...D.map(k=>({workerName:k.workerName,names:Be[k.workerName]??[]}))])await tn({cf:p,...d});t.emit({type:"step",step:"app.build",status:"ok",message:`${s?"Installed the release":"Built the app"} and checked its Worker${D.length?"s":""}.`,data:{release:s!==void 0,workflows:[...Ve,...Object.values(Be).flat()]}}),s?t.emit({type:"progress",step:"app.schema",message:`The release's publisher checked its migrations against its schema when it packed ${r.id} ${s.release.version}.`}):await Or({cwd:i,manifest:r,out:t});let un=(await H(f,v)).filter(d=>d.kind==="worker"),Ke=d=>un.find(k=>k.binding===d)?.versionId,fn={question:"Replace the version that's serving?",effect:"Migrations run first."};for(let d of[{workerName:v,shownAs:r.id,recordedVersionIds:[A.versionId,Ke("")]},...D.map(k=>({workerName:k.workerName,shownAs:`${r.id}'s ${k.name} Worker`,recordedVersionIds:[Ke(k.name)]}))])await Wt({cf:p,...d,interactive:a,confirm:e.confirm,change:fn});await B.check(),n.rollback=await Qn({cf:p,out:t,cwd:o,manifest:r,resources:ze,accountId:y,registry:f,workerName:v,restoreCommand:`${N} db restore${s?` ${r.id}`:""}`,appSecrets:l,drizzleKit:e.drizzleKit,prisma:e.prisma});let Fe={GATEWAY_URL:R,EVERY_APP_ORG_ID:x.id};for(let d of D)await B.check(),t.emit({type:"step",step:"app.helper",status:"start",message:`Uploading ${d.workerName}...`,data:{name:d.name,workerName:d.workerName}}),await ve({cf:p,cwd:o,workerName:d.workerName,buildOutputWorker:d.workerName,accountId:y,message:`everyapp ${me} ${r.id} ${d.name}`,secrets:Fe,interactive:a,attach:t.verbose,out:t,step:"app.helper",onUploaded:k=>he(f,v,k,d.name)}),t.emit({type:"step",step:"app.helper",status:"ok",message:`Uploaded ${d.workerName}.`,data:{name:d.name,workerName:d.workerName}});await B.check(),t.emit({type:"step",step:"app.upload",status:"start",message:`Uploading ${v}...`});let He=await ve({cf:p,cwd:o,workerName:v,accountId:y,message:`everyapp ${me} ${r.id}`,secrets:Fe,interactive:a,attach:t.verbose,out:t,step:"app.upload",onUploaded:d=>he(f,v,d)});if(!He.versionId)throw new g("VERSION_UNKNOWN",`Cloudflare reports no version for ${r.id} after the upload`,{data:{workerName:v}});K=He.versionId,t.emit({type:"step",step:"app.upload",status:"ok",message:`Uploaded version ${K}.`,data:{versionId:K}});for(let d of oe)await Sr(p,d.name),t.emit({type:"step",step:"app.workflows",status:"ok",message:`Deleted the Workflow ${d.binding} (${d.name}) with its instances.`,data:{binding:d.binding,name:d.name}});let qe=Ee(r).sends&&b.deploymentMode!=="hosted";if(F){await B.check(),t.emit({type:"step",step:"app.email",status:"start",message:`Routing ${r.id}'s mail...`,data:{removing:F.routes.length===0}});let{routed:d,removed:k}=await sr({cf:p,gatewayDb:f,plan:F,onProgress:de=>t.emit({type:"progress",step:"app.email",message:de})}),J={appId:r.id,workerName:v,senders:W.senders,routed:d,removed:k,sendersSettable:qe},Qe=J.sendersSettable?or(J.routed,J.senders):[];t.emit({type:"step",step:"app.email",status:"ok",message:ar(J),data:{addresses:d,removed:k,enabled:F.enable.map(({domain:de})=>de),...Qe.length>0?{replyHint:`To reply from ${Qe.join(", ")}, set up Email Sending, then: ${N} email set --sender`}:{}}})}!F&&pe&&W.inbound.length===0&&(t.emit({type:"step",step:"app.email",status:"skip",message:`${r.id} receives no mail yet.`}),Y.push({command:`${N} email set --inbound <address>`,note:`routes mail to ${r.id}`})),qe&&W.senders.length===0&&Y.push({command:`${N} email set --sender '*@<domain>'`,note:`lets ${r.id} send as your domain`});let gn=(A.previousManifest?.workers??[]).map(d=>String(d.name)).filter(d=>!D.some(k=>k.name===d));for(let d of gn)t.emit({type:"warning",code:"HELPER_WORKER_KEPT",step:"app.upload",message:`Helper Worker ${d} is no longer in everyapp.config.ts, but it still runs
|
|
29
|
+
Its Worker is ${q(v,d)}.`,data:{fix:"delete that Worker in the Cloudflare dashboard"}});let le=await Mt(p,v).catch(d=>(t.emit({type:"progress",step:"app.secrets",message:`Couldn't list ${v}'s secrets: ${dt(d).split(`
|
|
30
|
+
`)[0]}`}),null));ae=await Nt(f,A.app.id,{versionId:K,manifest:r,actor:O.actor,email:O.email,source:s?"release":"cli",...le?{secretNames:le}:{}});let wn=await Bn({cf:p,manifest:r,appId:r.id,secretNames:le,out:t,next:Y,providers:L});await jt(f,{appRowId:A.app.id,setup:wn,deployer:O},t)}finally{await B.release()}await tr({cf:p,db:f,databaseId:u,out:t,accountId:y,appId:r.id,workerName:v,publishHost:xe,interactive:a,forceDns:e.forceDns,seams:{...e.reconcile,openRelease:h.openRelease,source:h.source},verb:"deploy"});let U=`https://${P}`,Ue=!V&&(e.waitForLive??!0),Ge=await rr({wait:Ue,db:f,appRowId:A.app.id,appId:r.id,hostname:P,out:t,seams:e.live,message:`${r.id} is live at ${U}.`,verb:"deploy"});if(!Ge){let G=V?"outside-base":Ue?void 0:xe?"certificate":"first-visit";t.emit(ae==="active"&&!V?{type:"step",step:"app.live",status:"ok",message:`${r.id} is live at ${U}.`,data:{hostname:P,url:U}}:{type:"step",step:"app.live",status:"skip",message:`${r.id} isn't live yet: ${U}.`,data:{hostname:P,url:U,...G?{reason:G}:{}}})}return await vt({cf:p,db:f,install:b,out:t},{appId:r.id,surface:{publicRoutes:ie.length>0,mcp:se!==null}}),V&&t.emit({type:"warning",code:"APP_HOST_OUTSIDE_BASE",step:"app.domain",message:`${P} isn't one label below ${b.appBaseDomain}
|
|
31
|
+
The Gateway only serves names directly under ${b.appBaseDomain}, so ${r.id} can't be reached.`}),{liveUrl:U,gatewayUrl:R,organizationId:x.id,organizationName:x.name,hostname:P,workerName:v,versionId:K,live:Ge||ae==="active"&&!V,publicRoutes:ie,mcp:se,next:Y}}async function Bn({cf:e,manifest:n,appId:i,secretNames:t,out:a,next:s,providers:r}){if(!Lt(n,r))return be({manifest:n,appId:i,gatewayNames:[],secretNames:[],lookup:r}).setup;let o=await Tt(e).catch(()=>null),{setup:c}=be({manifest:n,appId:i,gatewayNames:o,secretNames:t,lookup:r});if(c.ready||!c.command)return c;let l=Ut(c),w=c.unmet.find(m=>m.why);return a.emit({type:"warning",code:"APP_NEEDS_SETUP",step:"app.secrets",message:[`${i} won't open until ${ue(l)} ${l.length===1?"is":"are"} set`,...w?[xt(w)[0]]:[]].join(`
|
|
32
|
+
`),data:{setup:c}}),s.push({command:c.command.command,note:`asks for each; ${i} opens once they are set`}),c}function Kn(e,n,i){let t=Object.keys(e.capabilities??{}).filter(a=>!n.get(a));if(t.length>0){let a=Ye(n);throw new g("CAPABILITY_UNKNOWN",[`${e.id} lists ${ue(t)} under capabilities, which ${i.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(`
|
|
33
|
+
`),{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}})}Ze(e,{capabilities:n})}function Fn(e){if(e.migrations?.dialect==="postgresql")throw new g("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 Hn(e,n,i){let t=new Map((n.resources?.durableObjects??[]).map(s=>[s.className,s.worker]));for(let s of e.previousManifest?.resources?.durableObjects??[]){let r=String(s.className),o=s.worker?String(s.worker):void 0;if(t.has(r)&&t.get(r)!==o)throw new g("DURABLE_OBJECT_MOVED",`${r} can't move to another Worker
|
|
34
|
+
A Durable Object's data can't follow it.`,{fix:"give the class a new name in everyapp.config.ts"});if(!t.has(r)&&o)throw new g("HELPER_DURABLE_OBJECT_REMOVED",`The helper Worker ${o} still defines ${r}
|
|
35
|
+
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(s=>String(s.className)).filter(s=>!t.has(s));if(a.length>0&&!i){let s=a.length===1;throw new g("DURABLE_OBJECT_REMOVED",`Deploying would delete ${s?`${a[0]}'s data`:`the data of ${a.join(", ")}`} for good
|
|
36
|
+
everyapp.config.ts no longer declares the Durable Object class${s?"":"es"} ${a.join(", ")}.`)}return a}async function qn({cf:e,plan:n,workerName:i,manifest:t,allowDelete:a}){let s=await rn({cf:e,workerName:i,previousManifest:n.previousManifest,names:_e(i,t).map(r=>r.name)});if(s.length>0&&!a){let r=s.length===1;throw new g("WORKFLOW_REMOVED",`Deploying would delete the Workflow${r?"":"s"} ${s.map(o=>o.binding).join(", ")} and ${r?"its":"their"} instances
|
|
37
|
+
everyapp.config.ts no longer declares ${r?"it":"them"}. Renaming a binding renames its Workflow.`)}return s}async function Qn({cf:e,out:n,cwd:i,manifest:t,resources:a,accountId:s,registry:r,workerName:o,restoreCommand:c,appSecrets:l,drizzleKit:w,prisma:m}){if(t.migrations?.dialect==="postgresql")return await Yn({out:n,cwd:i,manifest:t,appSecrets:l,drizzleKit:w,prisma:m}),null;let h=t.resources?.d1??[];if(h.length===0)return null;let p=Vt(h,t.migrations),y=a.d1?.[p]?.id,E=an.resolve(i,ke(t));if(!y||!await we(E))return cn(n),null;n.emit({type:"step",step:"app.migrations",status:"start",message:"Migrating the database..."});let u=await qt({cf:e,databaseId:y,accountId:s,dir:E,registry:r,target:Ft(o),restoreCommand:c});return n.emit({type:"step",step:"app.migrations",status:"ok",message:u.applied.length>0?`Applied ${u.applied.join(", ")}.${Qt(u.rollback)}`:"The app's database is up to date.",data:Yt(u)}),u.rollback}async function Yn({out:e,cwd:n,manifest:i,appSecrets:t,drizzleKit:a,prisma:s}){let r=i.migrations?.engine==="prisma"?"prisma":"drizzle",o=r==="drizzle"?ke(i):i.migrations?.dir;if(o!==void 0&&!await we(an.resolve(n,o))){cn(e);return}e.emit({type:"step",step:"app.migrations",status:"start",message:"Migrating the Postgres database...",data:{dialect:"postgresql",engine:r}});let c={cwd:n,databaseUrl:t[C],config:i.migrations?.config},l;r==="prisma"?l=await sn({...c,...s?{run:s}:{}}):await nn({...c,...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,...l?{applied:l}:{}}})}function cn(e){e.emit({type:"step",step:"app.migrations",status:"skip",message:"No migrations to apply."})}async function Hs(e){await Pt(e,async n=>{let i=process.cwd(),t=await on({cwd:i,manifest:await X(i),gateway:Ct(e.gateway),accountId:e["account-id"],out:n,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}});n.emit({type:"done",...Jn(t)})})}function Jn(e){return{data:{...nr(e),organization:e.organizationName,publicRoutes:e.publicRoutes,mcp:e.mcp,...e.next.length>0?{next:e.next}:{}}}}export{on as a,Hs as b,Jn as c};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{a as u}from"./chunk-U4ATZJEU.js";import{bc as g,yc as l}from"./chunk-FQ2A7YAP.js";import y from"node:fs/promises";import d from"node:path";import{parseEnv as h}from"node:util";var i=".everyapp/secrets.env",o="POSTGRES_DATABASE_URL";async function U(e){let n;try{n=await y.readFile(d.join(e,i),"utf8")}catch(r){if(l(r))return{};throw r}u(e,`${d.dirname(i)}/`);let t={};for(let[r,s]of Object.entries(h(n)))s?.trim()&&(t[r]=s.trim());return t}function m(e){return`${e}_ORIGIN_URL`}function x(e){return e}function L(e,n){let t=m(e);return n===1?[o,t]:[t]}function O([e,...n]){return n.length>0?`${e} (or ${n.join(", ")})`:`${e}`}function _(e,n,t){let r=m(t);return e[r]?{url:e[r],variable:r}:(n.resources?.hyperdrive??[]).length===1&&e[o]?{url:e[o],variable:o}:null}var R={postgres:5432,postgresql:5432,mysql:3306};function I(e,n){let t=f=>new g("DATABASE_URL_INVALID",`${n} in ${i} ${f}`,{fix:"write it as postgres://<user>:<password>@<host>:<port>/<database>"}),r;try{r=new URL(e)}catch{throw t("isn't a URL")}let s=r.protocol.replace(/:$/,"");if(s!=="postgres"&&s!=="postgresql"&&s!=="mysql")throw t("isn't a postgres:// or mysql:// URL");let a=decodeURIComponent(r.pathname.replace(/^\//,"")),p=decodeURIComponent(r.username),c=decodeURIComponent(r.password);if(!r.hostname||!a||!p||!c)throw t("needs a host, a database, a user and a password");return{scheme:s,host:r.hostname,port:r.port?Number(r.port):R[s],database:a,user:p,password:c}}function $(e,n){let t=e;for(let r of n)r&&(t=t.split(r).join("***"));return t}export{i as a,o as b,U as c,m as d,x as e,L as f,O as g,_ as h,I as i,$ as j};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import{c as l}from"./chunk-KVCL64LI.js";import{b as y,d as b}from"./chunk-I7FNTTUY.js";import{bc as m,cc as u,d,fc as p,gc as v,hc as w,nc as h,pc as g}from"./chunk-FQ2A7YAP.js";var I=9e5;async function x(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,o=e.onUploaded&&!e.dryRun?g({async:()=>k(e,n,t)}):void 0;try{return await R(e,r,n,()=>{t=!0})}catch(s){throw o&&!h()&&await k(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)}})}),s}finally{h()||o?.()}}async function k(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 R(e,r,n,t){let o=e.interactive&&e.attach&&!e.dryRun,s=c=>e.cf.run({plane:"project",cwd:e.cwd,cliCf:e.cliCf,mode:c,timeoutMs:I,...r?{files:{"secrets.json":r}}:{},args:f=>["deploy","--prebuilt","--no-provision","--mode","production","--message",e.message,...e.buildOutputWorker?["--worker",e.buildOutputWorker]:[],...r?["--secrets-file",f["secrets.json"]]:[],...e.dryRun?["--dry-run"]:[]]}),i;try{i=(await s(o?"interactive":"text").catch(f=>{if(e.interactive&&w(f,"strict_conflict"))return s("interactive");throw f})).stdout}catch(c){throw _(c,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 m("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:d(),rerunNote:"to deploy again"});return await e.onUploaded?.(a.versionId,!0),{versionId:a.versionId,output:i}}async function T({cf:e,workerName:r,shownAs:n,recordedVersionIds:t,interactive:o,confirm:s=y,change:i}){let a=await l(e,r);if(a&&!(a.versionId&&t.includes(a.versionId))){if(!o)throw new u("rerun_interactive",`${C(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:d([],{terminal:!0}),rerunNote:"in a terminal",data:{workerName:r,versionId:a.versionId,needsTerminal:!0}});await b(s,i.question,{context:[`${C(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 D(e){return`https://dash.cloudflare.com/${e}/workers/plans`}var C=e=>e.replace(/^the /,"The ");function _(e,{workerName:r,accountId:n}){return e instanceof v?e.kind==="strict_conflict"?new u("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:d([],{terminal:!0}),rerunNote:"in a terminal, and confirm cf's prompt",data:{needsTerminal:!0}}):e.kind==="subdomain_missing"?new u("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`):/Queue handler is missing/i.test(e.message)?new m("QUEUE_HANDLER_MISSING",`${r}'s new version is live without its queue consumers
|
|
7
|
+
Its bundle exports no queue() handler, which Cloudflare needs before it delivers a message.`,{fix:"export async queue(batch, env) from the Worker's entry beside everyApp()'s fetch, then deploy again",rerun:d(),data:{workerName:r,cloudflare:e.message}}):e.kind==="free_plan"?new u("upgrade_workers_paid",`Subscribe this account to Workers Paid
|
|
8
|
+
Cloudflare refused the upload on the Free plan. EveryApp needs Workers Paid ($5 a month, then usage).`,D(n),{data:{workerName:r,cloudflare:e.message}}):e:e}export{x as a,T as b,D as c};
|