@package-broker/dist-cloudflare 2.0.0-rc.2 → 2.0.0-rc.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (33) hide show
  1. package/cloudflare/assets/access.6859f43998ca.js +1 -0
  2. package/cloudflare/assets/app.e8434f3343de.js +9 -0
  3. package/cloudflare/assets/app.f15f8f21f88b.css +2 -0
  4. package/cloudflare/assets/audit.576009342714.js +1 -0
  5. package/cloudflare/assets/chunk.297a2d571f9c.js +4 -0
  6. package/cloudflare/assets/chunk.3704953b4a66.js +1 -0
  7. package/cloudflare/assets/chunk.6e23a75a1324.js +1 -0
  8. package/cloudflare/assets/chunk.7cb6f6b4daaa.js +1 -0
  9. package/cloudflare/assets/chunk.855a50f45830.js +1 -0
  10. package/cloudflare/assets/chunk.862544cf5835.js +2 -0
  11. package/cloudflare/assets/chunk.976a2ff4338e.js +1 -0
  12. package/cloudflare/assets/chunk.bb25fc845269.js +1 -0
  13. package/cloudflare/assets/chunk.bf48b04e6a00.js +1 -0
  14. package/cloudflare/assets/chunk.ce96495b8b55.js +1 -0
  15. package/cloudflare/assets/chunk.f922af39a279.js +1 -0
  16. package/cloudflare/assets/import.e2a1e35fcb8d.js +1 -0
  17. package/cloudflare/assets/index.html +6 -2
  18. package/cloudflare/assets/manifest.json +80 -8
  19. package/cloudflare/assets/packages.a8726e5144de.js +1 -0
  20. package/cloudflare/assets/projects.711deb86b7c9.js +1 -0
  21. package/cloudflare/assets/setup.dfed30ecfbad.js +1 -0
  22. package/cloudflare/assets/setup.html +3 -3
  23. package/cloudflare/assets/sources.d0ba0048bd96.js +1 -0
  24. package/cloudflare/assets/tokens.f48d235e8d25.js +4 -0
  25. package/cloudflare/assets.json +2 -2
  26. package/cloudflare/build-info.json +4 -4
  27. package/cloudflare/generated/manifest.json +2 -2
  28. package/cloudflare/worker.js +137 -88
  29. package/package.json +1 -1
  30. package/prebuilt.json +33 -15
  31. package/cloudflare/assets/app.b2abf3c46f6e.js +0 -15
  32. package/cloudflare/assets/app.e8cea8b32d3a.css +0 -2
  33. package/cloudflare/assets/setup.98343039898f.js +0 -1
@@ -0,0 +1 @@
1
+ import{a as X,b as Z,c as C,d as ee,e as N,f as T,g as S,h as re,i as te,j as oe}from"./chunk.bb25fc845269.js";import{a as U}from"./chunk.bf48b04e6a00.js";import"./chunk.3704953b4a66.js";import{a as q}from"./chunk.f922af39a279.js";import{a as ae}from"./chunk.ce96495b8b55.js";import{a as V,b as E,c as J}from"./chunk.862544cf5835.js";import{C as D,D as F,E as $,J as Y,c as z,d as K,g as _,j as O,p as R}from"./chunk.6e23a75a1324.js";var x=z(K(),1);var se={"org:read":"Read organization details","org:settings:write":"Change organization settings","org:users:read":"Read organization users","org:users:write":"Manage organization users","org:roles:read":"Read organization roles","org:roles:write":"Manage organization roles","org:grants:read":"Read organization grants","org:grants:write":"Manage organization grants","org:projects:create":"Add projects","org:projects:archive":"Archive projects","org:sources:read":"Read organization sources","org:sources:write":"Manage organization sources","org:tokens:read":"Read organization tokens","org:tokens:revoke":"Revoke organization tokens","org:service-principals:write":"Manage service principals","org:packages:manage":"Manage all packages","org:import:write":"Import runs: create and read","org:import:approve":"Approve and apply import runs","org:audit:read":"Read organization audit records","project:read":"Read project details","project:settings:write":"Change project settings","project:grants:read":"Read project grants","project:grants:write":"Manage project grants","project:packages:read":"Read project packages","project:packages:write":"Publish project packages","project:packages:manage":"Manage project packages","project:sources:read":"Read project sources","project:sources:write":"Manage project sources","project:service-principals:write":"Manage project service principals","project:tokens:create":"Issue project tokens","project:tokens:read":"Read project tokens","project:tokens:revoke":"Revoke project tokens","project:audit:read":"Read project audit records"};async function ie(e){let t=[],s=new Set,n;do{let r=await e.request("get","/_pb/roles",{query:{limit:"50",after:n}});if(!r.ok)return{roles:[],status:r.status===403?"forbidden":"error"};if(t.push(...r.data.items),n=r.data.next??void 0,n&&s.has(n))return{roles:[],status:"error"};n&&s.add(n)}while(n);return{roles:t,status:"ready"}}var H=["project_developer","project_auditor","project_owner","organization_auditor","organization_admin"],B=(e,t)=>e.filter(s=>s.scope===(t===null?"organization":"project")).sort((s,n)=>{let r=c=>c.isSystem&&H.includes(c.key)?H.indexOf(c.key):H.length;return r(s)-r(n)||s.name.localeCompare(n.name)}),ge={project_developer:"Read packages, view sources and issue project tokens; includes publish permission.",project_auditor:"View project details, grants, packages, sources, tokens and audit records.",project_owner:"Manage project settings, access, packages, sources, service principals and tokens.",organization_auditor:"View organization records and project records across the organization.",organization_admin:"Manage the organization and all projects, including users, roles, grants and packages."},ne=e=>e.isSystem&&ge[e.key]||`Custom role \xB7 ${e.permissions.length} permissions`;var o=z(_(),1);function me(e){let t={},s=e.email.trim().toLowerCase();if(e.type==="email"){let n=s.slice(s.indexOf("@")+1);(s.length>254||!/^[\x21-\x7e]+$/.test(s)||!/^[^@]+@[^@]+$/.test(s)||!/^(?=.{1,253}$)(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$/.test(n)||!/[a-z]/.test(n.slice(n.lastIndexOf(".")+1)))&&(t.email="Enter a valid sign-in email address.")}else e.provider||(t.provider="Choose a sign-in provider."),e.group?e.group!==e.group.trim()?t.group="Remove spaces at the start or end. Keep the group's spelling and capitalization.":(e.group.length>256||/[\p{Cc}\p{Cf}\p{Cs}]/u.test(e.group))&&(t.group="Enter the group value sent by your provider."):t.group="Enter the group value sent by your provider.";return e.roleId||(t.roleId="Choose a role to review this grant."),Object.keys(t).length?{errors:t}:{body:{roleId:e.roleId,subject:e.type==="email"?{type:"email",value:s}:{type:"group",provider:e.provider,value:e.group}}}}function Q(e,t,s,n,r){if(e.type==="email"&&!e.email.trim())return"Enter an email address to review this grant.";if(e.type==="group"&&(!s||!e.group))return"Choose a provider and enter a group value to review this grant.";if(!e.roleId)return"Choose a role to review this grant.";let c=e.type==="email"?e.email.trim().toLowerCase():`Members of ${e.group} signing in with ${s.displayName}`,f=n===null?`for ${r}${t?.key==="organization_auditor"?", including read access across projects":t?.permissions.some(m=>m.startsWith("project:"))?", including access across projects":""}`:`on project ${n}`;return`${c} will get ${t?.name??"the selected role"} ${f}.`}function A({id:e,label:t,help:s,error:n,note:r,children:c}){return(0,o.jsxs)("div",{className:"grid min-w-0 gap-1",children:[(0,o.jsx)($,{htmlFor:e,children:t}),c,s?(0,o.jsx)("p",{id:`${e}-help`,className:"text-sm text-neutral-600",children:s}):null,r?(0,o.jsx)("p",{className:"text-sm text-neutral-600",children:r}):null,n?(0,o.jsx)("p",{id:`${e}-error`,role:"alert",children:n}):null]})}function le({catalogue:e,project:t,value:s,onChange:n,id:r,error:c,retry:f}){let m=B(e.roles,t),v=m.find(a=>a.id===s),j=`${r}-help${c?` ${r}-error`:""}`;return e.status==="forbidden"?(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)("p",{className:"lg:col-span-2",children:"Role choices are unavailable for your account. Ask an organization administrator to grant access."}),(0,o.jsx)(A,{id:r,label:"Enter a role ID",help:"Ask an organization administrator for the role ID.",error:c,children:(0,o.jsx)(F,{id:r,name:"roleId",value:s,onChange:a=>n(a.target.value),"aria-invalid":!!c,"aria-describedby":j})})]}):(0,o.jsxs)(o.Fragment,{children:[(0,o.jsxs)("div",{className:"grid min-w-0 gap-2",children:[(0,o.jsx)(A,{id:r,label:"Role",error:c,children:(0,o.jsxs)(q,{id:r,name:"roleId",value:v?s:"",onChange:a=>n(a.target.value),disabled:e.status!=="ready"||!m.length,"aria-invalid":!!c,"aria-describedby":j,children:[(0,o.jsx)("option",{value:"",children:"Choose a role"}),m.map(a=>(0,o.jsx)("option",{value:a.id,children:a.name},a.id))]})}),(0,o.jsxs)("div",{id:`${r}-help`,className:"grid gap-2 text-sm",children:[e.status==="loading"?(0,o.jsx)("p",{children:"Loading roles\u2026"}):e.status==="error"?(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)("p",{role:"alert",children:"Roles could not be loaded. Try again."}),(0,o.jsx)(R,{type:"button",variant:"outline",onClick:f,children:"Retry roles"})]}):m.length?null:(0,o.jsx)("p",{children:"No roles are available to grant at this scope."}),v?(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)("p",{children:ne(v)}),(0,o.jsx)("p",{children:v.isSystem?"System role":"Custom role"}),v.isSystem&&v.key==="project_developer"?(0,o.jsx)("p",{children:"Suggested for developers; includes package read and publish permissions."}):null,v.permissions.includes("project:packages:write")?(0,o.jsx)("p",{children:"Publishing is not available in this version. This role includes the publish permission."}):null]}):null]})]}),v?(0,o.jsxs)("details",{className:"min-w-0 lg:col-span-2",children:[(0,o.jsxs)("summary",{className:"cursor-pointer underline",children:["View permissions (",v.permissions.length,")"]}),(0,o.jsx)("ul",{children:v.permissions.map(a=>(0,o.jsxs)("li",{className:"my-2",children:[(0,o.jsx)("span",{children:se[a]})," ",(0,o.jsx)("code",{className:"break-all",children:a})]},a))})]},v.id):null]})}function pe(e){let t=(0,x.useId)(),[s,n]=(0,x.useState)({type:"email",email:"",group:"",provider:"",roleId:""}),[r,c]=(0,x.useState)({}),[f,m]=(0,x.useState)(!1),v=B(e.catalogue.roles,e.project),j=e.project===null?"":v.find(p=>p.isSystem&&p.key==="project_developer")?.id??"",a=f?s.roleId:j,l=e.providers.length===1?e.providers[0].id:s.provider,d={...s,roleId:a,provider:l},u=v.find(p=>p.id===a),h=e.providers.find(p=>p.id===l),b=p=>({id:`${t}-${p}`,"aria-invalid":!!r[p],"aria-describedby":`${t}-${p}-help${r[p]?` ${t}-${p}-error`:""}`}),k=p=>{n({...s,...p}),c({})},I=e.catalogue.status==="forbidden"||e.catalogue.status==="ready"&&v.length>0;return(0,o.jsxs)("form",{noValidate:!0,className:"my-6 grid max-w-5xl items-start gap-x-6 gap-y-4 lg:grid-cols-2",onSubmit:p=>{if(p.preventDefault(),e.busy||!I)return;let M=me(d),w=M.errors??{};s.type==="email"&&p.currentTarget.querySelector('[name="email"]')?.validity.typeMismatch&&(w.email="Enter a valid sign-in email address."),s.type==="group"&&!h&&(w.provider=l?"This provider is no longer available. Choose another provider.":"Choose a sign-in provider."),e.catalogue.status==="ready"&&!u&&(w.roleId="Choose a role to review this grant."),c(w);let g=["email","provider","group","roleId"].find(y=>w[y]);if(g){p.currentTarget.querySelector(`[id="${t}-${g}"]`)?.focus();return}M.body&&e.submit(M.body)},children:[(0,o.jsx)("p",{className:"lg:col-span-2",children:"Give a person or a sign-in group a role."}),(0,o.jsxs)("div",{className:"lg:col-span-2",children:[(0,o.jsxs)("p",{className:"font-semibold",children:["Access to:"," ",e.project===null?`Organization \xB7 ${e.organization}`:`Project \xB7 ${e.project}`]}),(0,o.jsx)("p",{className:"text-sm text-neutral-600",children:e.project===null?"Organization roles can give access across projects. To give a development group access, choose a project.":"This grant applies to this project."}),e.project===null?(0,o.jsx)("a",{className:"underline",href:"#/projects",children:"Choose a project"}):null]}),(0,o.jsxs)("fieldset",{className:"grid min-w-0 gap-2 lg:col-span-2",children:[(0,o.jsx)("legend",{className:"font-semibold",children:"Who gets access"}),["email","group"].map(p=>(0,o.jsxs)("div",{className:"flex items-center gap-2",children:[(0,o.jsx)("input",{id:`${t}-${p}-radio`,type:"radio",name:"type",value:p,checked:s.type===p,disabled:p==="group"&&(e.providerStatus!=="ready"||!e.providers.length),"aria-describedby":p==="group"?`${t}-provider-status`:void 0,onChange:()=>k({type:p})}),(0,o.jsx)($,{htmlFor:`${t}-${p}-radio`,children:p==="email"?"Person (email)":"Group (from your sign-in provider)"})]},p))]}),(0,o.jsx)("div",{id:`${t}-provider-status`,className:"lg:col-span-2",children:e.providerStatus==="error"?(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)("p",{role:"alert",children:"Sign-in providers could not be loaded. Try again."}),(0,o.jsx)(R,{type:"button",variant:"outline",onClick:e.retry,children:"Retry sign-in providers"})]}):e.providerStatus==="loading"?(0,o.jsx)("p",{children:"Loading sign-in providers\u2026"}):e.providers.length?null:(0,o.jsx)("p",{children:"Group access needs a sign-in provider that sends groups. Grant access to individual people instead."})}),s.type==="email"?(0,o.jsx)(A,{id:`${t}-email`,label:"Email address",help:"Use the person's sign-in email. Email matching ignores capitalization. Their provider must verify the email and allow its domain.",note:"This creates an access rule. No invitation email is sent.",error:r.email,children:(0,o.jsx)(F,{...b("email"),type:"email",name:"email",autoComplete:"email",placeholder:"alex@acme-company.example",value:s.email,onChange:p=>k({email:p.target.value})})}):(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)("div",{className:"grid min-w-0 items-start gap-x-6 gap-y-4 lg:col-span-2 lg:grid-cols-2",children:e.providers.length===1?(0,o.jsxs)("p",{children:["Members signing in with ",h?.displayName]}):(0,o.jsx)(A,{id:`${t}-provider`,label:"Sign-in provider",help:"Choose the provider members use to sign in to Package Broker.",error:r.provider,children:(0,o.jsxs)(q,{...b("provider"),name:"provider",value:l,onChange:p=>k({provider:p.target.value}),children:[(0,o.jsx)("option",{value:"",children:"Choose a provider"}),e.providers.map(p=>(0,o.jsx)("option",{value:p.id,children:p.displayName},p.id))]})})}),(0,o.jsx)(A,{id:`${t}-group`,label:"Group value",help:"Use the exact group value sent by this provider. A group email works only if the provider sends that email as a group value.",note:"Package Broker cannot check whether this group exists. Ask a member to sign in and confirm their access after saving.",error:r.group,children:(0,o.jsx)(F,{...b("group"),name:"group",value:s.group,autoComplete:"off",spellCheck:!1,onChange:p=>k({group:p.target.value})})})]}),(0,o.jsx)(le,{catalogue:e.catalogue,project:e.project,id:`${t}-roleId`,value:a,onChange:p=>{m(!0),k({roleId:p})},error:r.roleId,retry:e.retry}),(0,o.jsxs)("div",{"aria-live":"polite",className:"min-w-0 break-words rounded border p-3 lg:col-span-2",children:[(0,o.jsx)("p",{children:Q(d,u,h,e.project,e.organization)}),s.type==="group"?(0,o.jsx)("p",{className:"text-sm",children:"Applies when the provider reports this exact group value."}):null]}),(0,o.jsx)("div",{className:"flex flex-col items-start sm:flex-row lg:col-span-2",children:(0,o.jsx)(R,{className:"w-full sm:w-auto lg:w-auto",type:"submit",disabled:e.busy||!I||s.type==="group"&&(e.providerStatus!=="ready"||!e.providers.length),children:"Create grant"})})]})}function ce({catalogue:e,project:t,currentRole:s,busy:n,retry:r,submit:c}){let f=(0,x.useId)(),[m,v]=(0,x.useState)(s),j=B(e.roles,t),a=!!m&&(e.status==="forbidden"||e.status==="ready"&&j.some(l=>l.id===m));return(0,o.jsxs)("form",{className:"grid max-w-5xl items-start gap-x-6 gap-y-4 lg:grid-cols-2",onSubmit:l=>{l.preventDefault(),!n&&a&&c(m)},children:[(0,o.jsx)("p",{className:"lg:col-span-2",children:"To change who this grant applies to, create a new grant and revoke this one."}),(0,o.jsx)(le,{id:f,catalogue:e,project:t,value:m,onChange:v,retry:r}),(0,o.jsx)("p",{"aria-live":"polite",className:"min-w-0 break-words lg:col-span-2",children:j.find(l=>l.id===m)?.name?`Save ${j.find(l=>l.id===m).name} ${t===null?"for the organization":`on project ${t}`}.`:"Choose a role to review this grant."}),(0,o.jsx)("div",{className:"flex flex-col items-start sm:flex-row lg:col-span-2",children:(0,o.jsx)(R,{className:"w-full sm:w-auto lg:w-auto",type:"submit",disabled:n||!a,children:"Save role"})})]})}var L=z(K(),1);var i=z(_(),1),ue=["grants","roles"],W=e=>X(e,ue),ve=e=>O("access",W(O("access",e))),P=e=>e.query.project===null&&e.query.status==="roles";function G(e){let t=!e.loading&&!e.stale,s=e.query.q?.toLowerCase()??"";return{roles:e.roles.filter(n=>n.name.toLowerCase().startsWith(s)),grants:e.grants.filter(n=>[n.principalName,n.principalId,n.id].some(r=>r?.toLowerCase().startsWith(s))),writeRoles:t&&e.query.project===null&&e.organization.includes("org:roles:write"),writeGrants:t&&(e.query.project===null?e.organization.includes("org:grants:write"):e.permissions.includes("project:grants:write"))}}function ye(e){let t=Z({query:{project:null},roles:[],catalogue:{roles:[],status:"loading"},providers:[],providerStatus:"loading",organizationName:"this organization",grants:[],next:null,organization:[],permissions:[],loading:!1,listError:!1,busy:!1,stale:!1,notice:null}),{client:s}=e,n=0,r=0;async function c(){let a=++r,l=n;t.set({catalogue:{roles:[],status:"loading"},providerStatus:"loading"});let[d,u,h]=await Promise.all([ie(s),s.request("get","/_pb/auth/providers"),s.request("get","/_pb/organization")]);a!==r||l!==n||t.set({catalogue:d,providers:u.ok?u.data.providers:[],providerStatus:u.ok?"ready":"error",organizationName:h.ok?h.data.name:"this organization"})}async function f(a,l=null){let d=++n;t.set({query:a,roles:[],grants:[],next:null,organization:[],permissions:[],loading:!0,listError:!1,busy:!1,stale:!1,notice:l});let[u,h]=await Promise.all([s.request("get","/_pb/me/permissions"),a.project===null?null:s.request("get","/_pb/projects/{project}/permissions",{params:{project:a.project}})]);if(d!==n)return;let b=u.ok?u.data.organization:[],k=h?.ok?h.data.project:[];t.set({organization:b,permissions:k});let I=P(t.snapshot()),p=a.project===null?b.includes("org:grants:write"):k.includes("project:grants:write");if(!I&&p&&await c(),d!==n)return;if(!(a.project===null?b.includes(I?"org:roles:read":"org:grants:read"):k.includes("project:grants:read"))){t.set({loading:!1,listError:!0,notice:"You do not have permission to view this list."});return}let w={after:a.after,limit:"50"};if(I){let g=await s.request("get","/_pb/roles",{query:w});if(d!==n)return;t.set({loading:!1,listError:!g.ok,roles:g.ok?g.data.items:[],next:g.ok?g.data.next:null,notice:g.ok?l:C(g)})}else if(a.project!==null){let g=await s.request("get","/_pb/projects/{project}/grants",{params:{project:a.project},query:w});if(d!==n)return;t.set({loading:!1,listError:!g.ok,grants:g.ok?g.data.items.map(y=>({id:y.id,principalId:y.principal.id,principalName:y.principal.displayName,kind:y.principal.kind,roleId:y.role.id,roleName:y.role.name,revision:y.revision,createdAt:y.createdAt})):[],next:g.ok?g.data.next:null,notice:g.ok?l:C(g)})}else{let g=await s.request("get","/_pb/grants",{query:w});if(d!==n)return;t.set({loading:!1,listError:!g.ok,grants:g.ok?g.data.items.map(y=>({id:y.id,principalId:null,principalName:null,kind:y.subject.type,roleId:y.roleId,roleName:y.roleId,revision:y.revision,createdAt:y.createdAt})):[],next:g.ok?g.data.next:null,notice:g.ok?l:C(g)})}}async function m(a,l="Access updated.",d=!1){let u=t.snapshot();if(u.busy||u.loading||u.stale)return;let h=n;t.set({busy:!0,notice:null});let b=await a();h===n&&(t.set({busy:!1}),ee(e,b)?t.set({stale:!0,notice:"Complete reauthentication and confirm the pending action."}):b.ok?await f(u.query,l):t.set({stale:b.status===412,notice:d&&b.status===412?"This grant changed. Reload it before saving.":C(b)}))}let v=a=>{let l=t.snapshot(),d=l.roles.find(u=>u.id===a);return G(l).writeRoles&&d&&!d.isSystem&&N(d.revision)?d:null},j=a=>{let l=t.snapshot(),d=l.grants.find(u=>u.id===a);return G(l).writeGrants&&d&&N(d.revision)?d:null};return{snapshot:t.snapshot,subscribe:t.subscribe,load:f,loadFormOptions:c,async createGrant(a){let l=t.snapshot();if(!G(l).writeGrants)return;let d=Q({type:a.subject.type,email:a.subject.type==="email"?a.subject.value:"",group:a.subject.type==="group"?a.subject.value:"",provider:a.subject.type==="group"?a.subject.provider:"",roleId:a.roleId},l.catalogue.roles.find(u=>u.id===a.roleId),a.subject.type==="group"?l.providers.find(u=>a.subject.type==="group"&&u.id===a.subject.provider):void 0,l.query.project,l.organizationName);await m(()=>l.query.project===null?s.request("post","/_pb/grants",{body:a,idempotencyKey:crypto.randomUUID()}):s.request("post","/_pb/projects/{project}/grants",{params:{project:l.query.project},body:a,idempotencyKey:crypto.randomUUID()}),`Grant created. Access depends on the person's email or the groups their provider reports at sign-in. ${d}`,!0)},async changeGrant(a,l){let d=j(a);if(!d)return;let u=t.snapshot().query.project,h={"If-Match":N(d.revision)};await m(()=>u===null?s.request("patch","/_pb/grants/{grant}",{params:{grant:a},headers:h,body:{roleId:l}}):s.request("patch","/_pb/projects/{project}/grants/{grant}",{params:{project:u,grant:a},headers:h,body:{roleId:l}}),void 0,!0)},async revoke(a){let l=j(a);if(!l)return;let d=t.snapshot().query.project,u={"If-Match":N(l.revision)};await m(()=>d===null?s.request("delete","/_pb/grants/{grant}",{params:{grant:a},headers:u}):s.request("delete","/_pb/projects/{project}/grants/{grant}",{params:{project:d,grant:a},headers:u}),void 0,!0)},async createRole(a){G(t.snapshot()).writeRoles&&await m(()=>s.request("post","/_pb/roles",{body:a,idempotencyKey:crypto.randomUUID()}))},async updateRole(a,l){let d=v(a);d&&await m(()=>s.request("patch","/_pb/roles/{role}",{params:{role:a},headers:{"If-Match":N(d.revision)},body:l}))},async deleteRole(a){let l=v(a);l&&await m(()=>s.request("delete","/_pb/roles/{role}",{params:{role:a},headers:{"If-Match":N(l.revision)}}))},async replayed(a){let l=t.snapshot().query.project,d=l===null?P(t.snapshot())?"/_pb/roles":"/_pb/grants":`/_pb/projects/${encodeURIComponent(l)}/grants`;a.path!==d&&!a.path.startsWith(`${d}/`)||(a.ok?await f(t.snapshot().query,"Access updated."):t.set({stale:!0,notice:a.status===412&&!P(t.snapshot())?"This grant changed. Reload it before saving.":C(a)}))},dispose(){++n}}}var de=(e="")=>e.split(/[\s,]+/).filter(Boolean);function fe({state:e,controller:t}){let s=G(e),n=!e.loading&&(e.query.project===null?e.organization.includes("org:grants:write"):e.permissions.includes("project:grants:write"));return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(re,{...e,reload:()=>{t.load(e.query)}}),P(e)?(0,i.jsxs)(i.Fragment,{children:[!e.loading&&!e.listError&&s.roles.length?(0,i.jsx)(V,{label:"Roles",items:s.roles,columns:[{key:"name",label:"Role",value:r=>r.name,render:r=>(0,i.jsxs)("div",{className:"grid gap-1",children:[(0,i.jsx)("strong",{children:r.name}),(0,i.jsx)(D,{value:r.id,label:"role ID"}),r.isSystem?(0,i.jsx)(E,{variant:"outline",children:"System"}):null,r.protectsLastHolder?(0,i.jsx)("span",{className:"text-xs text-neutral-600",children:"Last holder protected"}):null]})},{key:"scope",label:"Scope",value:r=>r.scope},{key:"permissions",label:"Permissions",value:r=>r.permissions.join(", "),render:r=>(0,i.jsx)("div",{className:"flex flex-wrap gap-1",children:r.permissions.map(c=>(0,i.jsx)(E,{variant:"outline",children:c},c))})},{key:"actions",label:"Actions",value:()=>"",sortable:!1,render:r=>s.writeRoles&&!r.isSystem&&N(r.revision)?(0,i.jsxs)("details",{children:[(0,i.jsx)("summary",{className:"cursor-pointer underline",children:"Edit role"}),(0,i.jsxs)("div",{className:"mt-3 grid gap-3",children:[(0,i.jsxs)("form",{className:"grid gap-2",onSubmit:c=>{if(c.preventDefault(),e.busy)return;let f=T(c);t.updateRole(r.id,{name:f.name??""})},children:[(0,i.jsx)(S,{name:"name",label:"Role name",value:r.name}),(0,i.jsx)(R,{type:"submit",disabled:e.busy,children:"Rename role"})]}),(0,i.jsxs)("form",{className:"grid gap-2",onSubmit:c=>{if(c.preventDefault(),e.busy)return;let f=T(c);t.updateRole(r.id,{permissions:de(f.permissions)})},children:[(0,i.jsx)(S,{name:"permissions",label:"Permissions (comma separated)",value:r.permissions.join(", "),required:!1}),(0,i.jsx)(R,{type:"submit",disabled:e.busy,children:"Save permissions"})]}),(0,i.jsx)(U,{action:"Remove role",target:`${r.name} (${r.id})`,scope:"Organization",description:"Deleting this role removes its permission bundle. Review grants using this role before continuing. This cannot be undone.",disabled:e.busy,onConfirm:()=>{t.deleteRole(r.id)}},`${r.id}:${r.revision}`)]})]}):null}]}):null,s.writeRoles?(0,i.jsxs)("details",{className:"detail-group my-6",children:[(0,i.jsx)("summary",{className:"cursor-pointer font-semibold",children:"New role"}),(0,i.jsxs)("form",{className:"my-6 grid gap-3",onSubmit:r=>{if(r.preventDefault(),e.busy)return;let c=T(r);t.createRole({key:c.key??"",name:c.name??"",scope:c.scope,permissions:de(c.permissions)})},children:[(0,i.jsx)("h2",{className:"text-lg font-semibold",children:"New role"}),(0,i.jsx)(S,{name:"key",label:"Role key"}),(0,i.jsx)(S,{name:"name",label:"Role name"}),(0,i.jsxs)($,{className:"grid gap-1",children:["Scope",(0,i.jsxs)(q,{name:"scope",children:[(0,i.jsx)("option",{value:"organization",children:"Organization"}),(0,i.jsx)("option",{value:"project",children:"Project"})]})]}),(0,i.jsx)(S,{name:"permissions",label:"Permissions (comma separated)",required:!1}),(0,i.jsx)(R,{type:"submit",disabled:e.busy,children:"Create role"})]})]}):null]}):(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)("h2",{className:"my-3 text-lg font-semibold",children:e.query.project===null?"Organization grants":"Members and project grants"}),!e.loading&&!e.listError&&s.grants.length?(0,i.jsx)(V,{label:e.query.project===null?"Organization grants":"Members and project grants",items:s.grants,columns:[{key:"principal",label:"Principal / grant",value:r=>r.principalName??r.principalId??r.id,render:r=>(0,i.jsxs)("div",{className:"grid gap-1",children:[(0,i.jsx)("strong",{children:r.principalName??"Grant"}),(0,i.jsx)(D,{value:r.principalId??r.id,label:r.principalId?"principal ID":"grant ID"})]})},{key:"kind",label:"Kind",value:r=>r.kind,render:r=>(0,i.jsx)(E,{variant:"outline",children:r.kind})},{key:"role",label:"Role",value:r=>r.roleName},{key:"added",label:"Added",value:r=>r.createdAt,priority:2,render:r=>(0,i.jsx)(ae,{value:r.createdAt})},{key:"id",label:"Grant ID",value:r=>r.id,priority:3,render:r=>(0,i.jsx)(D,{value:r.id,label:"grant ID"})},{key:"actions",label:"Actions",value:()=>"",sortable:!1,render:r=>n&&N(r.revision)?(0,i.jsxs)("details",{children:[(0,i.jsx)("summary",{className:"cursor-pointer underline",children:"Change role"}),(0,i.jsxs)("div",{className:"mt-3 grid gap-2",children:[(0,i.jsx)(ce,{catalogue:e.catalogue,project:e.query.project,currentRole:r.roleId,busy:e.busy||e.stale,retry:()=>{t.loadFormOptions()},submit:c=>t.changeGrant(r.id,c)}),(0,i.jsx)(U,{action:"Revoke grant",target:`${r.principalName??r.principalId??r.id} \xB7 ${e.catalogue.roles.find(c=>c.id===r.roleId)?.name??r.roleName}`,scope:e.query.project===null?"Organization":`Project: ${e.query.project}`,description:"This removes the access provided by this grant. Other grants still apply. To restore this access, create a new grant.",disabled:e.busy||e.stale,onConfirm:()=>{t.revoke(r.id)}},`${r.id}:${r.revision}`)]})]}):null}]}):null,n?(0,i.jsxs)("details",{className:"detail-group my-6",children:[(0,i.jsx)("summary",{className:"cursor-pointer font-semibold",children:"New grant"}),(0,i.jsx)(pe,{catalogue:e.catalogue,providers:e.providers,providerStatus:e.providerStatus,project:e.query.project,organization:e.organizationName,busy:e.busy||e.stale,retry:()=>{t.loadFormOptions()},submit:r=>t.createGrant(r)},e.query.project??"organization")]}):null]}),!e.loading&&!e.listError&&(P(e)?s.roles:s.grants).length===0?(0,i.jsx)(J,{kind:e.query.q?"filtered-empty":"empty",title:"No entries found on this page."}):null,e.next?(0,i.jsx)("a",{className:"my-4 inline-block underline",href:ve({...e.query,after:e.next}),children:"Next entries"}):null]})}function Be(){let e=Y(),t=(0,L.useMemo)(()=>ye(e),[e]),s=(0,L.useSyncExternalStore)(t.subscribe,t.snapshot,t.snapshot),n=oe(e,t,W,"access"),r=W(n);return(0,i.jsxs)("section",{"aria-labelledby":"page-heading",children:[(0,i.jsx)("h1",{tabIndex:-1,id:"page-heading",className:"text-xl font-semibold",children:"Access"}),(0,i.jsx)("p",{className:"mt-1 text-neutral-600",children:"Membership comes from project grants. A role is the bundle of permissions a grant carries."}),(0,i.jsx)(te,{route:"access",query:r,statuses:r.project===null?ue:["grants"]},n),(0,i.jsx)(fe,{state:s,controller:t})]})}export{Be as AccessPage,fe as AccessView,G as accessViewModel,ve as buildAccessHash,ye as createAccessController,W as parseAccessHash};