unleash-server 4.22.3 → 4.22.6

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 (59) hide show
  1. package/dist/lib/db/feature-toggle-store.d.ts +2 -2
  2. package/dist/lib/db/feature-toggle-store.js +4 -4
  3. package/dist/lib/db/feature-toggle-store.js.map +1 -1
  4. package/dist/lib/db/project-stats-store.d.ts +2 -1
  5. package/dist/lib/db/project-stats-store.js +22 -0
  6. package/dist/lib/db/project-stats-store.js.map +1 -1
  7. package/dist/lib/features/feature-toggle/time-to-production/time-to-production.d.ts +2 -0
  8. package/dist/lib/features/feature-toggle/time-to-production/time-to-production.js +15 -0
  9. package/dist/lib/features/feature-toggle/time-to-production/time-to-production.js.map +1 -0
  10. package/dist/lib/features/feature-toggle/time-to-production/time-to-production.test.js +27 -0
  11. package/dist/lib/features/feature-toggle/time-to-production/time-to-production.test.js.map +1 -0
  12. package/dist/lib/services/feature-toggle-service.js +10 -0
  13. package/dist/lib/services/feature-toggle-service.js.map +1 -1
  14. package/dist/lib/services/project-service.js +15 -45
  15. package/dist/lib/services/project-service.js.map +1 -1
  16. package/dist/lib/types/experimental.d.ts +1 -0
  17. package/dist/lib/types/experimental.js +1 -0
  18. package/dist/lib/types/experimental.js.map +1 -1
  19. package/dist/lib/types/stores/feature-toggle-store.d.ts +2 -2
  20. package/dist/lib/types/stores/project-stats-store-type.d.ts +5 -0
  21. package/dist/migrations/20230420211308-update-context-fields-add-sessionId.d.ts +2 -0
  22. package/dist/migrations/20230420211308-update-context-fields-add-sessionId.js +21 -0
  23. package/dist/migrations/20230420211308-update-context-fields-add-sessionId.js.map +1 -0
  24. package/dist/test/e2e/api/admin/feature.e2e.test.js +48 -2
  25. package/dist/test/e2e/api/admin/feature.e2e.test.js.map +1 -1
  26. package/dist/test/e2e/services/project-service.e2e.test.js +54 -0
  27. package/dist/test/e2e/services/project-service.e2e.test.js.map +1 -1
  28. package/dist/test/fixtures/fake-feature-toggle-store.d.ts +2 -2
  29. package/dist/test/fixtures/fake-feature-toggle-store.js +2 -2
  30. package/dist/test/fixtures/fake-feature-toggle-store.js.map +1 -1
  31. package/dist/test/fixtures/fake-project-stats-store.d.ts +2 -1
  32. package/dist/test/fixtures/fake-project-stats-store.js +3 -0
  33. package/dist/test/fixtures/fake-project-stats-store.js.map +1 -1
  34. package/frontend/build/index.html +1 -1
  35. package/frontend/build/static/{CreateProject-a2c9a780.js → CreateProject-06fb0787.js} +1 -1
  36. package/frontend/build/static/{Error-38b8cdc0.js → Error-8b41c742.js} +1 -1
  37. package/frontend/build/static/{ExpandMore-ee840700.js → ExpandMore-14929315.js} +1 -1
  38. package/frontend/build/static/{FeatureArchiveDialog-0d7ae6c3.js → FeatureArchiveDialog-e0047702.js} +1 -1
  39. package/frontend/build/static/{FeatureMetricsChart-ed667dfd.js → FeatureMetricsChart-c3ad56b6.js} +1 -1
  40. package/frontend/build/static/{FeatureViewLazyExport-1b33033a.js → FeatureViewLazyExport-7827e8c5.js} +2 -2
  41. package/frontend/build/static/{LazyAdminExport-f1db04ed.js → LazyAdminExport-d95ca76c.js} +2 -2
  42. package/frontend/build/static/{LazyProjectExport-984413bf.js → LazyProjectExport-ef778b59.js} +1 -1
  43. package/frontend/build/static/{NetworkOverview-c9972cf4.js → NetworkOverview-b3e0c73f.js} +1 -1
  44. package/frontend/build/static/{NetworkTraffic-b4d65658.js → NetworkTraffic-729ad6fc.js} +1 -1
  45. package/frontend/build/static/{Playground-82d86aa7.js → Playground-a32c4264.js} +1 -1
  46. package/frontend/build/static/{StrategyItemContainer-72e360fd.js → StrategyItemContainer-681b4c1e.js} +1 -1
  47. package/frontend/build/static/{chartjs-adapter-date-fns.esm-00d0c032.js → chartjs-adapter-date-fns.esm-a07e3ced.js} +1 -1
  48. package/frontend/build/static/{index-c65a88d1.js → index-307298c7.js} +1 -1
  49. package/frontend/build/static/{index-78310b22.js → index-8da761a6.js} +1 -1
  50. package/frontend/build/static/{index-99d4171f.js → index-a6ca4785.js} +73 -73
  51. package/frontend/build/static/{unknownify-9d8df72f.js → unknownify-ac0e04aa.js} +1 -1
  52. package/frontend/build/static/{useProjectRole-dba93dda.js → useProjectRole-76e51391.js} +1 -1
  53. package/package.json +1 -1
  54. package/dist/lib/read-models/time-to-production/time-to-production.d.ts +0 -20
  55. package/dist/lib/read-models/time-to-production/time-to-production.js +0 -75
  56. package/dist/lib/read-models/time-to-production/time-to-production.js.map +0 -1
  57. package/dist/lib/read-models/time-to-production/time-to-production.test.js +0 -182
  58. package/dist/lib/read-models/time-to-production/time-to-production.test.js.map +0 -1
  59. /package/dist/lib/{read-models → features/feature-toggle}/time-to-production/time-to-production.test.d.ts +0 -0
@@ -1 +1 @@
1
- import{aR as r,aS as a,r as o,aT as c}from"./index-99d4171f.js";const u=(e={})=>{const{data:t,error:n,mutate:s}=r(a("api/admin/metrics/rps"),i,e);return o.useMemo(()=>({metrics:t,loading:!n&&!t,refetch:()=>s(),error:n}),[t,n,s])},i=e=>fetch(e).then(c("Instance Metrics")).then(t=>t.json()),f=e=>!e||e==="undefined"?"unknown":e;export{f as a,u};
1
+ import{aR as r,aS as a,r as o,aT as c}from"./index-a6ca4785.js";const u=(e={})=>{const{data:t,error:n,mutate:s}=r(a("api/admin/metrics/rps"),i,e);return o.useMemo(()=>({metrics:t,loading:!n&&!t,refetch:()=>s(),error:n}),[t,n,s])},i=e=>fetch(e).then(c("Instance Metrics")).then(t=>t.json()),f=e=>!e||e==="undefined"?"unknown":e;export{f as a,u};
@@ -1 +1 @@
1
- import{dX as $,c as L,j as e,H as E,f as l,A as N,N as z,c5 as V,U as X,F as k,C,a as T,X as Y,d8 as q,S as J,h as Q,i as Z,k as ee,W as P,bE as U,ar as te,ds as ne,bJ as oe,dY as se,s as y,aO as F,dH as re,l as B,dJ as A,r as u,I as ae,R as v,c6 as le,dn as ie,d as I,e as ce,a2 as M,aM as H,cl as de,dZ as ue,aY as he,a_ as O,a4 as pe,bS as me,c4 as ye,a9 as be,aj as W,T as w,dD as fe,cX as ge,a5 as Ce,dG as Te,bR as ke,dF as Se,d_ as Ae,aR as ve,aS as G,aT as K,cb as Ie,aU as we}from"./index-99d4171f.js";const Ee=$(),Ye=Ee,Ne=L(e("path",{d:"M21 10h-8.35C11.83 7.67 9.61 6 7 6c-3.31 0-6 2.69-6 6s2.69 6 6 6c2.61 0 4.83-1.67 5.65-4H13l2 2 2-2 2 2 4-4.04L21 10zM7 15c-1.65 0-3-1.35-3-3s1.35-3 3-3 3 1.35 3 3-1.35 3-3 3z"}),"Key"),qe=L(e("path",{d:"M12 8c1.1 0 2-.9 2-2s-.9-2-2-2-2 .9-2 2 .9 2 2 2zm0 2c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm0 6c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2z"}),"MoreVert"),De=()=>{const{uiConfig:t}=E();return l(N,{severity:"info",children:[l("p",{children:["Read the"," ",e("a",{href:"https://docs.getunleash.io/reference/sdks",target:"_blank",rel:"noreferrer",children:"SDK overview"})," ","to connect Unleash to your application. Please note it can take up to ",e("strong",{children:"1 minute"})," before a new API key is activated."]}),e("br",{}),e("strong",{children:"API URL: "})," ",l("pre",{style:{display:"inline"},children:[t.unleashUrl,"/api/"]})]})},xe=["Icon","createdAt"],Re=["Icon","project","seenAt"],Je=({compact:t=!1,setHiddenColumns:n,columns:s,loading:o,rows:r,getTableProps:a,getTableBodyProps:i,headerGroups:c,globalFilter:d,prepareRow:b})=>{const g=z(V.breakpoints.down("md"));return X([{condition:g,columns:xe},{condition:t,columns:Re}],n,s),l(k,{children:[e(C,{condition:r.length>0,show:e(T,{sx:{mb:4},children:e(De,{})})}),e(T,{sx:{overflowX:"auto"},children:e(Y,{value:d,children:l(q,{...a(),children:[e(J,{headerGroups:c}),e(Q,{...i(),children:r.map(f=>(b(f),e(Z,{hover:!0,...f.getRowProps(),children:f.cells.map(h=>e(ee,{...h.getCellProps(),children:h.render("Cell")}))})))})]})})}),e(C,{condition:r.length===0&&!o,show:e(C,{condition:(d==null?void 0:d.length)>0,show:l(P,{children:["No tokens found matching “",d,"”"]}),elseShow:e(P,{children:l("span",{children:["No tokens available. Read ",e(U,{href:"https://docs.getunleash.io/how-to/api",target:"_blank",rel:"noreferrer",children:"API How-to guides"})," "," to learn more."]})})})})]})},Qe=({path:t,permission:n,project:s})=>{const o=te();return e(ne,{Icon:oe,onClick:()=>o(t),"data-testid":se,permission:n,projectId:s,maxWidth:"700px",children:"New API token"})},Pe=y(F)(({theme:t})=>({textDecoration:"none",color:t.palette.links,"&:hover, &:focus":{textDecoration:"underline"}})),Be=({projects:t,project:n})=>{const{searchQuery:s}=re();let o=t&&Array.isArray(t)?t:n?[n]:[];return o.length===0?e(B,{children:e(A,{search:s,children:"*"})}):e(B,{children:o.map((r,a)=>l(u.Fragment,{children:[a>0&&", ",!r||r==="*"?e(A,{search:s,children:"*"}):e(Pe,{to:`/projects/${r}`,children:e(A,{search:s,children:r})})]},r))})},Ze=(t,n)=>{const s=u.useMemo(()=>({sortBy:[{id:"createdAt"}]}),[]),o=u.useMemo(()=>[{id:"Icon",width:"1%",Cell:()=>e(ae,{icon:e(Ne,{color:"disabled"})}),disableSortBy:!0,disableGlobalFilter:!0},{Header:"Username",accessor:"username",Cell:v},{Header:"Type",accessor:"type",Cell:({value:h})=>e(v,{value:j[h.toLowerCase()].label,subtitle:j[h.toLowerCase()].title}),minWidth:280},{Header:"Project",accessor:"project",Cell:h=>e(Be,{project:h.row.original.project,projects:h.row.original.projects}),minWidth:120},{Header:"Environment",accessor:"environment",Cell:v,minWidth:120},{Header:"Created",accessor:"createdAt",Cell:le,minWidth:150,disableGlobalFilter:!0},{Header:"Last seen",accessor:"seenAt",Cell:ie,minWidth:150,disableGlobalFilter:!0},{Header:"Actions",id:"Actions",align:"center",width:"1%",disableSortBy:!0,disableGlobalFilter:!0,Cell:n}],[]),{getTableProps:r,getTableBodyProps:a,headerGroups:i,rows:c,prepareRow:d,state:b,setGlobalFilter:g,setHiddenColumns:f}=I.useTable({columns:o,data:t,initialState:s,sortTypes:ce,autoResetHiddenColumns:!1,disableSortRemove:!0},I.useGlobalFilter,I.useSortBy);return{getTableProps:r,getTableBodyProps:a,headerGroups:i,rows:c,prepareRow:d,state:b,setGlobalFilter:g,setHiddenColumns:f,columns:o}},j={client:{label:"CLIENT",title:"Connect server-side SDK or Unleash Proxy"},frontend:{label:"FRONTEND",title:"Connect web and mobile SDK"},admin:{label:"ADMIN",title:"Full access for managing Unleash"}},et=({token:t,project:n,permission:s,track:o})=>{const{setToastData:r}=M(),a=i=>{ue(i)&&(r({type:"success",title:"Token copied to clipboard"}),o&&typeof o=="function"&&o())};return e(H,{permission:s,projectId:n,tooltipProps:{title:"Copy token",arrow:!0},onClick:()=>a(t.secret),size:"large",children:e(de,{})})},je=y("ul")({marginBottom:0}),tt=({token:t,permission:n,onRemove:s,project:o})=>{const[r,a]=u.useState(!1),{setToastData:i,setToastApiError:c}=M();return l(k,{children:[e(H,{permission:n,projectId:o,tooltipProps:{title:"Delete token",arrow:!0},onClick:()=>a(!0),size:"large",children:e(he,{})}),e(O,{open:r,onClick:async()=>{try{await s(),a(!1),i({type:"success",title:"API token removed"})}catch(b){c(pe(b))}},onClose:()=>a(!1),title:"Confirm deletion",children:l("div",{children:["Are you sure you want to delete the following API token?",e("br",{}),l(je,{children:[l("li",{children:[e("strong",{children:"username"}),":"," ",e("code",{children:t.username})]}),l("li",{children:[e("strong",{children:"type"}),": ",e("code",{children:t.type})]})]})]})})]})},Le=y("div")(()=>({maxWidth:"400px"})),Ue=y("form")(()=>({display:"flex",flexDirection:"column",height:"100%"})),Fe=y(me)(({theme:t})=>({width:"100%",marginBottom:t.spacing(2)})),Me=y(ye)(({theme:t})=>({marginBottom:t.spacing(2),minWidth:"400px",[t.breakpoints.down("sm")]:{minWidth:"379px"}})),_=y("p")(({theme:t})=>({marginBottom:t.spacing(1)})),He=y("label")(({theme:t})=>({marginBottom:t.spacing(1)})),Oe=y(be)(({theme:t})=>({marginLeft:t.spacing(3)})),We=y(T)({marginTop:"auto",display:"flex",justifyContent:"flex-end"}),nt=({children:t,actions:n,handleSubmit:s,handleCancel:o})=>{var i;const{uiConfig:r}=E(),a=Boolean((i=r==null?void 0:r.flags)==null?void 0:i.UNLEASH_CLOUD);return l(Ue,{onSubmit:s,children:[e(C,{condition:a,show:l(N,{severity:"info",sx:{mb:4},children:["Please be aware of our"," ",e(U,{href:"https://www.getunleash.io/fair-use-policy",children:"fair use policy"}),"."]})}),t,l(We,{children:[n,e(Oe,{onClick:o,children:"Cancel"})]})]})},ot=t=>{var x;const{environments:n}=W(),s=(x=n==null?void 0:n.find(p=>p.enabled))==null?void 0:x.name,[o,r]=u.useState(""),[a,i]=u.useState("CLIENT"),[c,d]=u.useState([t||"*"]),[b,g]=u.useState(c),[f,h]=u.useState(),[D,S]=u.useState({});return u.useEffect(()=>{h(a==="ADMIN"?"*":s)},[a,s]),{username:o,type:a,projects:c,environment:f,setUsername:r,setTokenType:p=>{p==="ADMIN"?(i(p),g(c),d(["*"]),h("*")):(i(p),d(b),h(s))},setProjects:d,setEnvironment:h,getApiTokenPayload:()=>({username:o,type:a,environment:f,projects:c}),isValid:()=>{const p={};return o||(p.username="Username is required"),c.length===0&&(p.projects="At least one project is required"),S(p),Object.keys(p).length===0},clearErrors:p=>{if(p){const R={...D};delete R[p],S(R)}else S({})},errors:D}};var m=(t=>(t.ADMIN="ADMIN",t.CLIENT="CLIENT",t.FRONTEND="FRONTEND",t))(m||{});const st=({open:t,closeConfirm:n,token:s,type:o})=>l(O,{open:t,onClick:n,primaryButtonText:"Close",title:"New token created",children:[e(w,{variant:"body1",children:"Your new token has been created successfully."}),e(fe,{token:s}),e(C,{condition:o===m.FRONTEND,show:l(N,{sx:{mt:2},severity:"info",children:["By default, all ",m.FRONTEND," tokens may be used from any CORS origin. If you'd like to configure a strict set of origins, please use the"," ",e(F,{to:"/admin/cors",target:"_blank",children:"CORS origins configuration page"}),"."]})})]}),rt=({username:t,setUsername:n,errors:s,clearErrors:o})=>l(k,{children:[e(_,{children:"What would you like to call this token?"}),e(Fe,{value:t,name:"username",onChange:r=>n(r.target.value),label:"Token name",error:s.username!==void 0,errorText:s.username,onFocus:()=>o("username"),autoFocus:!0})]}),at=({type:t,setType:n})=>{const s=ge("projectId"),{uiConfig:o}=E(),r=[{key:m.CLIENT,label:`Server-side SDK (${m.CLIENT})`,title:"Connect server-side SDK or Unleash Proxy"}];return s||r.push({key:m.ADMIN,label:m.ADMIN,title:"Full access for managing Unleash"}),o.flags.embedProxyFrontend&&r.splice(1,0,{key:m.FRONTEND,label:`Client-side SDK (${m.FRONTEND})`,title:"Connect web and mobile SDK directly to Unleash"}),e(Le,{children:l(Ce,{sx:{mb:2,width:"100%"},children:[e(He,{id:"token-type",children:"What do you want to connect?"}),e(Te,{"aria-labelledby":"token-type",defaultValue:"CLIENT",name:"radio-buttons-group",value:t,onChange:(a,i)=>n(i),children:r.map(({key:a,label:i,title:c})=>e(ke,{value:a,sx:{mb:1},control:e(Se,{sx:{ml:.75,alignSelf:"flex-start"}}),label:e(T,{children:l(T,{children:[e(w,{children:i}),e(w,{variant:"body2",color:"text.secondary",children:c})]})})},a))})]})})},lt=({type:t,environment:n,setEnvironment:s})=>{const{environments:o}=W(),r=t===m.ADMIN?[{key:"*",label:"ALL"}]:o.map(a=>({key:a.name,label:`${a.name.concat(a.enabled?"":" - deprecated")}`,title:a.name,disabled:!1}));return l(k,{children:[e(_,{children:"Which environment should the token have access to?"}),e(Me,{disabled:t===m.ADMIN,options:r,value:n,onChange:s,label:"Environment",id:"api_key_environment",name:"environment",IconComponent:Ae,fullWidth:!0})]})},Ge=t=>t.map(n=>({...n.user,joinedAt:new Date(n.joinedAt),createdBy:n.createdBy})),it=t=>{const{data:n,error:s,mutate:o}=ve(G(`api/admin/groups/${t}`),Ke);return u.useMemo(()=>({group:n&&{...n,users:Ge((n==null?void 0:n.users)??[])},loading:!s&&!n,refetchGroup:()=>o(),error:s}),[n,s,o])},Ke=t=>fetch(t).then(K("Group")).then(n=>n.json()),ct=(t,n={})=>{const s=()=>{const d=G(`api/admin/roles/${t}`);return fetch(d,{method:"GET"}).then(K("project role")).then(b=>b.json())},{data:o,error:r}=Ie({},`api/admin/roles/${t}`,s,n),[a,i]=u.useState(!r&&!o),c=()=>{we(`api/admin/roles/${t}`)};return u.useEffect(()=>{i(!r&&!o)},[o,r]),{role:o||{},error:r,loading:a,refetch:c}};export{Je as A,Ye as B,Qe as C,lt as E,qe as M,tt as R,_ as S,m as T,et as a,ot as b,nt as c,rt as d,at as e,st as f,it as g,ct as h,Ge as m,Ze as u};
1
+ import{dX as $,c as L,j as e,H as E,f as l,A as N,N as z,c5 as V,U as X,F as k,C,a as T,X as Y,d8 as q,S as J,h as Q,i as Z,k as ee,W as P,bE as U,ar as te,ds as ne,bJ as oe,dY as se,s as y,aO as F,dH as re,l as B,dJ as A,r as u,I as ae,R as v,c6 as le,dn as ie,d as I,e as ce,a2 as M,aM as H,cl as de,dZ as ue,aY as he,a_ as O,a4 as pe,bS as me,c4 as ye,a9 as be,aj as W,T as w,dD as fe,cX as ge,a5 as Ce,dG as Te,bR as ke,dF as Se,d_ as Ae,aR as ve,aS as G,aT as K,cb as Ie,aU as we}from"./index-a6ca4785.js";const Ee=$(),Ye=Ee,Ne=L(e("path",{d:"M21 10h-8.35C11.83 7.67 9.61 6 7 6c-3.31 0-6 2.69-6 6s2.69 6 6 6c2.61 0 4.83-1.67 5.65-4H13l2 2 2-2 2 2 4-4.04L21 10zM7 15c-1.65 0-3-1.35-3-3s1.35-3 3-3 3 1.35 3 3-1.35 3-3 3z"}),"Key"),qe=L(e("path",{d:"M12 8c1.1 0 2-.9 2-2s-.9-2-2-2-2 .9-2 2 .9 2 2 2zm0 2c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm0 6c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2z"}),"MoreVert"),De=()=>{const{uiConfig:t}=E();return l(N,{severity:"info",children:[l("p",{children:["Read the"," ",e("a",{href:"https://docs.getunleash.io/reference/sdks",target:"_blank",rel:"noreferrer",children:"SDK overview"})," ","to connect Unleash to your application. Please note it can take up to ",e("strong",{children:"1 minute"})," before a new API key is activated."]}),e("br",{}),e("strong",{children:"API URL: "})," ",l("pre",{style:{display:"inline"},children:[t.unleashUrl,"/api/"]})]})},xe=["Icon","createdAt"],Re=["Icon","project","seenAt"],Je=({compact:t=!1,setHiddenColumns:n,columns:s,loading:o,rows:r,getTableProps:a,getTableBodyProps:i,headerGroups:c,globalFilter:d,prepareRow:b})=>{const g=z(V.breakpoints.down("md"));return X([{condition:g,columns:xe},{condition:t,columns:Re}],n,s),l(k,{children:[e(C,{condition:r.length>0,show:e(T,{sx:{mb:4},children:e(De,{})})}),e(T,{sx:{overflowX:"auto"},children:e(Y,{value:d,children:l(q,{...a(),children:[e(J,{headerGroups:c}),e(Q,{...i(),children:r.map(f=>(b(f),e(Z,{hover:!0,...f.getRowProps(),children:f.cells.map(h=>e(ee,{...h.getCellProps(),children:h.render("Cell")}))})))})]})})}),e(C,{condition:r.length===0&&!o,show:e(C,{condition:(d==null?void 0:d.length)>0,show:l(P,{children:["No tokens found matching “",d,"”"]}),elseShow:e(P,{children:l("span",{children:["No tokens available. Read ",e(U,{href:"https://docs.getunleash.io/how-to/api",target:"_blank",rel:"noreferrer",children:"API How-to guides"})," "," to learn more."]})})})})]})},Qe=({path:t,permission:n,project:s})=>{const o=te();return e(ne,{Icon:oe,onClick:()=>o(t),"data-testid":se,permission:n,projectId:s,maxWidth:"700px",children:"New API token"})},Pe=y(F)(({theme:t})=>({textDecoration:"none",color:t.palette.links,"&:hover, &:focus":{textDecoration:"underline"}})),Be=({projects:t,project:n})=>{const{searchQuery:s}=re();let o=t&&Array.isArray(t)?t:n?[n]:[];return o.length===0?e(B,{children:e(A,{search:s,children:"*"})}):e(B,{children:o.map((r,a)=>l(u.Fragment,{children:[a>0&&", ",!r||r==="*"?e(A,{search:s,children:"*"}):e(Pe,{to:`/projects/${r}`,children:e(A,{search:s,children:r})})]},r))})},Ze=(t,n)=>{const s=u.useMemo(()=>({sortBy:[{id:"createdAt"}]}),[]),o=u.useMemo(()=>[{id:"Icon",width:"1%",Cell:()=>e(ae,{icon:e(Ne,{color:"disabled"})}),disableSortBy:!0,disableGlobalFilter:!0},{Header:"Username",accessor:"username",Cell:v},{Header:"Type",accessor:"type",Cell:({value:h})=>e(v,{value:j[h.toLowerCase()].label,subtitle:j[h.toLowerCase()].title}),minWidth:280},{Header:"Project",accessor:"project",Cell:h=>e(Be,{project:h.row.original.project,projects:h.row.original.projects}),minWidth:120},{Header:"Environment",accessor:"environment",Cell:v,minWidth:120},{Header:"Created",accessor:"createdAt",Cell:le,minWidth:150,disableGlobalFilter:!0},{Header:"Last seen",accessor:"seenAt",Cell:ie,minWidth:150,disableGlobalFilter:!0},{Header:"Actions",id:"Actions",align:"center",width:"1%",disableSortBy:!0,disableGlobalFilter:!0,Cell:n}],[]),{getTableProps:r,getTableBodyProps:a,headerGroups:i,rows:c,prepareRow:d,state:b,setGlobalFilter:g,setHiddenColumns:f}=I.useTable({columns:o,data:t,initialState:s,sortTypes:ce,autoResetHiddenColumns:!1,disableSortRemove:!0},I.useGlobalFilter,I.useSortBy);return{getTableProps:r,getTableBodyProps:a,headerGroups:i,rows:c,prepareRow:d,state:b,setGlobalFilter:g,setHiddenColumns:f,columns:o}},j={client:{label:"CLIENT",title:"Connect server-side SDK or Unleash Proxy"},frontend:{label:"FRONTEND",title:"Connect web and mobile SDK"},admin:{label:"ADMIN",title:"Full access for managing Unleash"}},et=({token:t,project:n,permission:s,track:o})=>{const{setToastData:r}=M(),a=i=>{ue(i)&&(r({type:"success",title:"Token copied to clipboard"}),o&&typeof o=="function"&&o())};return e(H,{permission:s,projectId:n,tooltipProps:{title:"Copy token",arrow:!0},onClick:()=>a(t.secret),size:"large",children:e(de,{})})},je=y("ul")({marginBottom:0}),tt=({token:t,permission:n,onRemove:s,project:o})=>{const[r,a]=u.useState(!1),{setToastData:i,setToastApiError:c}=M();return l(k,{children:[e(H,{permission:n,projectId:o,tooltipProps:{title:"Delete token",arrow:!0},onClick:()=>a(!0),size:"large",children:e(he,{})}),e(O,{open:r,onClick:async()=>{try{await s(),a(!1),i({type:"success",title:"API token removed"})}catch(b){c(pe(b))}},onClose:()=>a(!1),title:"Confirm deletion",children:l("div",{children:["Are you sure you want to delete the following API token?",e("br",{}),l(je,{children:[l("li",{children:[e("strong",{children:"username"}),":"," ",e("code",{children:t.username})]}),l("li",{children:[e("strong",{children:"type"}),": ",e("code",{children:t.type})]})]})]})})]})},Le=y("div")(()=>({maxWidth:"400px"})),Ue=y("form")(()=>({display:"flex",flexDirection:"column",height:"100%"})),Fe=y(me)(({theme:t})=>({width:"100%",marginBottom:t.spacing(2)})),Me=y(ye)(({theme:t})=>({marginBottom:t.spacing(2),minWidth:"400px",[t.breakpoints.down("sm")]:{minWidth:"379px"}})),_=y("p")(({theme:t})=>({marginBottom:t.spacing(1)})),He=y("label")(({theme:t})=>({marginBottom:t.spacing(1)})),Oe=y(be)(({theme:t})=>({marginLeft:t.spacing(3)})),We=y(T)({marginTop:"auto",display:"flex",justifyContent:"flex-end"}),nt=({children:t,actions:n,handleSubmit:s,handleCancel:o})=>{var i;const{uiConfig:r}=E(),a=Boolean((i=r==null?void 0:r.flags)==null?void 0:i.UNLEASH_CLOUD);return l(Ue,{onSubmit:s,children:[e(C,{condition:a,show:l(N,{severity:"info",sx:{mb:4},children:["Please be aware of our"," ",e(U,{href:"https://www.getunleash.io/fair-use-policy",children:"fair use policy"}),"."]})}),t,l(We,{children:[n,e(Oe,{onClick:o,children:"Cancel"})]})]})},ot=t=>{var x;const{environments:n}=W(),s=(x=n==null?void 0:n.find(p=>p.enabled))==null?void 0:x.name,[o,r]=u.useState(""),[a,i]=u.useState("CLIENT"),[c,d]=u.useState([t||"*"]),[b,g]=u.useState(c),[f,h]=u.useState(),[D,S]=u.useState({});return u.useEffect(()=>{h(a==="ADMIN"?"*":s)},[a,s]),{username:o,type:a,projects:c,environment:f,setUsername:r,setTokenType:p=>{p==="ADMIN"?(i(p),g(c),d(["*"]),h("*")):(i(p),d(b),h(s))},setProjects:d,setEnvironment:h,getApiTokenPayload:()=>({username:o,type:a,environment:f,projects:c}),isValid:()=>{const p={};return o||(p.username="Username is required"),c.length===0&&(p.projects="At least one project is required"),S(p),Object.keys(p).length===0},clearErrors:p=>{if(p){const R={...D};delete R[p],S(R)}else S({})},errors:D}};var m=(t=>(t.ADMIN="ADMIN",t.CLIENT="CLIENT",t.FRONTEND="FRONTEND",t))(m||{});const st=({open:t,closeConfirm:n,token:s,type:o})=>l(O,{open:t,onClick:n,primaryButtonText:"Close",title:"New token created",children:[e(w,{variant:"body1",children:"Your new token has been created successfully."}),e(fe,{token:s}),e(C,{condition:o===m.FRONTEND,show:l(N,{sx:{mt:2},severity:"info",children:["By default, all ",m.FRONTEND," tokens may be used from any CORS origin. If you'd like to configure a strict set of origins, please use the"," ",e(F,{to:"/admin/cors",target:"_blank",children:"CORS origins configuration page"}),"."]})})]}),rt=({username:t,setUsername:n,errors:s,clearErrors:o})=>l(k,{children:[e(_,{children:"What would you like to call this token?"}),e(Fe,{value:t,name:"username",onChange:r=>n(r.target.value),label:"Token name",error:s.username!==void 0,errorText:s.username,onFocus:()=>o("username"),autoFocus:!0})]}),at=({type:t,setType:n})=>{const s=ge("projectId"),{uiConfig:o}=E(),r=[{key:m.CLIENT,label:`Server-side SDK (${m.CLIENT})`,title:"Connect server-side SDK or Unleash Proxy"}];return s||r.push({key:m.ADMIN,label:m.ADMIN,title:"Full access for managing Unleash"}),o.flags.embedProxyFrontend&&r.splice(1,0,{key:m.FRONTEND,label:`Client-side SDK (${m.FRONTEND})`,title:"Connect web and mobile SDK directly to Unleash"}),e(Le,{children:l(Ce,{sx:{mb:2,width:"100%"},children:[e(He,{id:"token-type",children:"What do you want to connect?"}),e(Te,{"aria-labelledby":"token-type",defaultValue:"CLIENT",name:"radio-buttons-group",value:t,onChange:(a,i)=>n(i),children:r.map(({key:a,label:i,title:c})=>e(ke,{value:a,sx:{mb:1},control:e(Se,{sx:{ml:.75,alignSelf:"flex-start"}}),label:e(T,{children:l(T,{children:[e(w,{children:i}),e(w,{variant:"body2",color:"text.secondary",children:c})]})})},a))})]})})},lt=({type:t,environment:n,setEnvironment:s})=>{const{environments:o}=W(),r=t===m.ADMIN?[{key:"*",label:"ALL"}]:o.map(a=>({key:a.name,label:`${a.name.concat(a.enabled?"":" - deprecated")}`,title:a.name,disabled:!1}));return l(k,{children:[e(_,{children:"Which environment should the token have access to?"}),e(Me,{disabled:t===m.ADMIN,options:r,value:n,onChange:s,label:"Environment",id:"api_key_environment",name:"environment",IconComponent:Ae,fullWidth:!0})]})},Ge=t=>t.map(n=>({...n.user,joinedAt:new Date(n.joinedAt),createdBy:n.createdBy})),it=t=>{const{data:n,error:s,mutate:o}=ve(G(`api/admin/groups/${t}`),Ke);return u.useMemo(()=>({group:n&&{...n,users:Ge((n==null?void 0:n.users)??[])},loading:!s&&!n,refetchGroup:()=>o(),error:s}),[n,s,o])},Ke=t=>fetch(t).then(K("Group")).then(n=>n.json()),ct=(t,n={})=>{const s=()=>{const d=G(`api/admin/roles/${t}`);return fetch(d,{method:"GET"}).then(K("project role")).then(b=>b.json())},{data:o,error:r}=Ie({},`api/admin/roles/${t}`,s,n),[a,i]=u.useState(!r&&!o),c=()=>{we(`api/admin/roles/${t}`)};return u.useEffect(()=>{i(!r&&!o)},[o,r]),{role:o||{},error:r,loading:a,refetch:c}};export{Je as A,Ye as B,Qe as C,lt as E,qe as M,tt as R,_ as S,m as T,et as a,ot as b,nt as c,rt as d,at as e,st as f,it as g,ct as h,Ge as m,Ze as u};
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "unleash-server",
3
3
  "description": "Unleash is an enterprise ready feature toggles service. It provides different strategies for handling feature toggles.",
4
- "version": "4.22.3",
4
+ "version": "4.22.6",
5
5
  "keywords": [
6
6
  "unleash",
7
7
  "feature toggle",
@@ -1,20 +0,0 @@
1
- import { FeatureToggle, IEvent, IProjectEnvironment } from 'lib/types';
2
- interface IFeatureTimeToProdCalculationMap {
3
- [index: string]: IFeatureTimeToProdData;
4
- }
5
- interface IFeatureTimeToProdData {
6
- createdAt: string;
7
- events: IEvent[];
8
- }
9
- export declare class TimeToProduction {
10
- private features;
11
- private productionEnvironments;
12
- private events;
13
- constructor(features: FeatureToggle[], productionEnvironments: IProjectEnvironment[], events: IEvent[]);
14
- calculateAverageTimeToProd(): number;
15
- getFeatureEvents(): IFeatureTimeToProdCalculationMap;
16
- getProductionEvents(events: IEvent[]): IEvent[];
17
- calculateTimeToProdForFeatures(featureEvents: IFeatureTimeToProdCalculationMap): number[];
18
- sortFeatureEventsByCreatedAt(featureEvents: IFeatureTimeToProdCalculationMap): IFeatureTimeToProdCalculationMap;
19
- }
20
- export {};
@@ -1,75 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.TimeToProduction = void 0;
4
- const date_fns_1 = require("date-fns");
5
- class TimeToProduction {
6
- constructor(features, productionEnvironments, events) {
7
- this.features = features;
8
- this.productionEnvironments = productionEnvironments;
9
- this.events = events;
10
- }
11
- calculateAverageTimeToProd() {
12
- const featureEvents = this.getFeatureEvents();
13
- const sortedFeatureEvents = this.sortFeatureEventsByCreatedAt(featureEvents);
14
- const timeToProdPerFeature = this.calculateTimeToProdForFeatures(sortedFeatureEvents);
15
- if (timeToProdPerFeature.length) {
16
- const sum = timeToProdPerFeature.reduce((acc, curr) => acc + curr, 0);
17
- return Number((sum / Object.keys(sortedFeatureEvents).length).toFixed(1));
18
- }
19
- return 0;
20
- }
21
- getFeatureEvents() {
22
- return this.getProductionEvents(this.events).reduce((acc, event) => {
23
- if (acc[event.featureName]) {
24
- acc[event.featureName].events.push(event);
25
- }
26
- else {
27
- const foundFeature = this.features.find((feature) => feature.name === event.featureName);
28
- acc[event.featureName] = { events: [event] };
29
- acc[event.featureName].createdAt = foundFeature?.createdAt;
30
- }
31
- return acc;
32
- }, {});
33
- }
34
- getProductionEvents(events) {
35
- return events.filter((event) => {
36
- const found = this.productionEnvironments.find((env) => env.name === event.environment);
37
- if (found) {
38
- return found.type === 'production';
39
- }
40
- return false;
41
- });
42
- }
43
- calculateTimeToProdForFeatures(featureEvents) {
44
- return Object.keys(featureEvents).map((featureName) => {
45
- const feature = featureEvents[featureName];
46
- const earliestEvent = feature.events[0];
47
- const createdAtDate = new Date(feature.createdAt);
48
- const eventDate = new Date(earliestEvent.createdAt);
49
- const diff = (0, date_fns_1.differenceInDays)(eventDate, createdAtDate);
50
- return diff;
51
- });
52
- }
53
- sortFeatureEventsByCreatedAt(featureEvents) {
54
- return Object.keys(featureEvents).reduce((acc, featureName) => {
55
- const feature = featureEvents[featureName];
56
- acc[featureName] = {
57
- ...feature,
58
- events: feature.events.sort((a, b) => {
59
- const aDate = new Date(a.createdAt);
60
- const bDate = new Date(b.createdAt);
61
- if (aDate > bDate) {
62
- return 1;
63
- }
64
- if (aDate < bDate) {
65
- return -1;
66
- }
67
- return 0;
68
- }),
69
- };
70
- return acc;
71
- }, {});
72
- }
73
- }
74
- exports.TimeToProduction = TimeToProduction;
75
- //# sourceMappingURL=time-to-production.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"time-to-production.js","sourceRoot":"","sources":["../../../../src/lib/read-models/time-to-production/time-to-production.ts"],"names":[],"mappings":"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"}
@@ -1,182 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- const date_fns_1 = require("date-fns");
4
- const time_to_production_1 = require("./time-to-production");
5
- const modifyEventCreatedAt = (events, days) => {
6
- return events.map((event) => {
7
- const newEvent = { ...event };
8
- newEvent.createdAt = (0, date_fns_1.addDays)(newEvent.createdAt, days);
9
- newEvent.id = newEvent.id + days;
10
- return newEvent;
11
- });
12
- };
13
- const createEvent = (env, overrides) => {
14
- return {
15
- id: Math.floor(Math.random() * 1000),
16
- type: 'feature-environment-enabled',
17
- createdBy: 'Fredrik',
18
- createdAt: new Date('2023-01-25T09:37:32.504Z'),
19
- data: null,
20
- preData: null,
21
- tags: [],
22
- featureName: 'average-prod-time',
23
- project: 'average-time-to-prod',
24
- environment: env,
25
- ...overrides,
26
- };
27
- };
28
- const events = [
29
- {
30
- id: 65,
31
- type: 'feature-environment-enabled',
32
- createdBy: 'Fredrik',
33
- createdAt: new Date('2023-01-25T09:37:32.504Z'),
34
- data: null,
35
- preData: null,
36
- tags: [],
37
- featureName: 'average-prod-time',
38
- project: 'average-time-to-prod',
39
- environment: 'default',
40
- },
41
- {
42
- id: 66,
43
- type: 'feature-environment-enabled',
44
- createdBy: 'Fredrik',
45
- createdAt: new Date('2023-01-31T09:37:32.506Z'),
46
- data: null,
47
- preData: null,
48
- tags: [],
49
- featureName: 'average-prod-time-2',
50
- project: 'average-time-to-prod',
51
- environment: 'default',
52
- },
53
- {
54
- id: 67,
55
- type: 'feature-environment-enabled',
56
- createdBy: 'Fredrik',
57
- createdAt: new Date('2023-01-26T09:37:32.508Z'),
58
- data: null,
59
- preData: null,
60
- tags: [],
61
- featureName: 'average-prod-time-3',
62
- project: 'average-time-to-prod',
63
- environment: 'default',
64
- },
65
- {
66
- id: 68,
67
- type: 'feature-environment-enabled',
68
- createdBy: 'Fredrik',
69
- createdAt: new Date('2023-02-02T09:37:32.509Z'),
70
- data: null,
71
- preData: null,
72
- tags: [],
73
- featureName: 'average-prod-time-4',
74
- project: 'average-time-to-prod',
75
- environment: 'default',
76
- },
77
- ];
78
- const environments = [
79
- {
80
- name: 'default',
81
- type: 'production',
82
- sortOrder: 1,
83
- enabled: true,
84
- protected: true,
85
- projectApiTokenCount: 0,
86
- projectEnabledToggleCount: 0,
87
- },
88
- ];
89
- const features = [
90
- {
91
- name: 'average-prod-time',
92
- description: null,
93
- type: 'release',
94
- project: 'average-time-to-prod',
95
- stale: false,
96
- createdAt: new Date('2022-12-05T09:37:32.483Z'),
97
- lastSeenAt: null,
98
- impressionData: false,
99
- archivedAt: null,
100
- archived: false,
101
- },
102
- {
103
- name: 'average-prod-time-4',
104
- description: null,
105
- type: 'release',
106
- project: 'average-time-to-prod',
107
- stale: false,
108
- createdAt: new Date('2023-01-19T09:37:32.484Z'),
109
- lastSeenAt: null,
110
- impressionData: false,
111
- archivedAt: null,
112
- archived: false,
113
- },
114
- {
115
- name: 'average-prod-time-2',
116
- description: null,
117
- type: 'release',
118
- project: 'average-time-to-prod',
119
- stale: false,
120
- createdAt: new Date('2023-01-19T09:37:32.484Z'),
121
- lastSeenAt: null,
122
- impressionData: false,
123
- archivedAt: null,
124
- archived: false,
125
- },
126
- {
127
- name: 'average-prod-time-3',
128
- description: null,
129
- type: 'release',
130
- project: 'average-time-to-prod',
131
- stale: false,
132
- createdAt: new Date('2023-01-19T09:37:32.486Z'),
133
- lastSeenAt: null,
134
- impressionData: false,
135
- archivedAt: null,
136
- archived: false,
137
- },
138
- ];
139
- describe('calculate average time to production', () => {
140
- test('should build a map of feature events', () => {
141
- const projectStatus = new time_to_production_1.TimeToProduction(features, environments, events);
142
- const featureEvents = projectStatus.getFeatureEvents();
143
- expect(Object.keys(featureEvents).length).toBe(4);
144
- expect(featureEvents['average-prod-time'].createdAt).toBeTruthy();
145
- expect(featureEvents['average-prod-time'].events).toBeInstanceOf(Array);
146
- });
147
- test('should calculate average correctly', () => {
148
- const projectStatus = new time_to_production_1.TimeToProduction(features, environments, events);
149
- const timeToProduction = projectStatus.calculateAverageTimeToProd();
150
- expect(timeToProduction).toBe(21);
151
- });
152
- test('should sort events by createdAt', () => {
153
- const projectStatus = new time_to_production_1.TimeToProduction(features, environments, [
154
- ...modifyEventCreatedAt(events, 5),
155
- ...events,
156
- ]);
157
- const featureEvents = projectStatus.getFeatureEvents();
158
- const sortedFeatureEvents = projectStatus.sortFeatureEventsByCreatedAt(featureEvents);
159
- const [firstEvent, secondEvent] = sortedFeatureEvents['average-prod-time'].events;
160
- const firstEventCreatedAt = new Date(firstEvent.createdAt);
161
- const secondEventCreatedAt = new Date(secondEvent.createdAt);
162
- expect(firstEventCreatedAt.getTime()).toBeLessThan(secondEventCreatedAt.getTime());
163
- const [firstEvent2, secondEvent2] = sortedFeatureEvents['average-prod-time-2'].events;
164
- const firstEventCreatedAt2 = new Date(firstEvent2.createdAt);
165
- const secondEventCreatedAt2 = new Date(secondEvent2.createdAt);
166
- expect(firstEventCreatedAt2.getTime()).toBeLessThan(secondEventCreatedAt2.getTime());
167
- });
168
- test('should not count events that are development environments', () => {
169
- const projectStatus = new time_to_production_1.TimeToProduction(features, environments, [
170
- createEvent('development', {
171
- createdAt: (0, date_fns_1.subDays)(new Date('2023-01-25T09:37:32.504Z'), 10),
172
- }),
173
- createEvent('development', {
174
- createdAt: (0, date_fns_1.subDays)(new Date('2023-01-25T09:37:32.504Z'), 10),
175
- }),
176
- ...events,
177
- ]);
178
- const timeToProduction = projectStatus.calculateAverageTimeToProd();
179
- expect(timeToProduction).toBe(21);
180
- });
181
- });
182
- //# sourceMappingURL=time-to-production.test.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"time-to-production.test.js","sourceRoot":"","sources":["../../../../src/lib/read-models/time-to-production/time-to-production.test.ts"],"names":[],"mappings":"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"}