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.
- package/dist/lib/db/feature-toggle-store.d.ts +2 -2
- package/dist/lib/db/feature-toggle-store.js +4 -4
- package/dist/lib/db/feature-toggle-store.js.map +1 -1
- package/dist/lib/db/project-stats-store.d.ts +2 -1
- package/dist/lib/db/project-stats-store.js +22 -0
- package/dist/lib/db/project-stats-store.js.map +1 -1
- package/dist/lib/features/feature-toggle/time-to-production/time-to-production.d.ts +2 -0
- package/dist/lib/features/feature-toggle/time-to-production/time-to-production.js +15 -0
- package/dist/lib/features/feature-toggle/time-to-production/time-to-production.js.map +1 -0
- package/dist/lib/features/feature-toggle/time-to-production/time-to-production.test.js +27 -0
- package/dist/lib/features/feature-toggle/time-to-production/time-to-production.test.js.map +1 -0
- package/dist/lib/services/feature-toggle-service.js +10 -0
- package/dist/lib/services/feature-toggle-service.js.map +1 -1
- package/dist/lib/services/project-service.js +15 -45
- package/dist/lib/services/project-service.js.map +1 -1
- package/dist/lib/types/experimental.d.ts +1 -0
- package/dist/lib/types/experimental.js +1 -0
- package/dist/lib/types/experimental.js.map +1 -1
- package/dist/lib/types/stores/feature-toggle-store.d.ts +2 -2
- package/dist/lib/types/stores/project-stats-store-type.d.ts +5 -0
- package/dist/migrations/20230420211308-update-context-fields-add-sessionId.d.ts +2 -0
- package/dist/migrations/20230420211308-update-context-fields-add-sessionId.js +21 -0
- package/dist/migrations/20230420211308-update-context-fields-add-sessionId.js.map +1 -0
- package/dist/test/e2e/api/admin/feature.e2e.test.js +48 -2
- package/dist/test/e2e/api/admin/feature.e2e.test.js.map +1 -1
- package/dist/test/e2e/services/project-service.e2e.test.js +54 -0
- package/dist/test/e2e/services/project-service.e2e.test.js.map +1 -1
- package/dist/test/fixtures/fake-feature-toggle-store.d.ts +2 -2
- package/dist/test/fixtures/fake-feature-toggle-store.js +2 -2
- package/dist/test/fixtures/fake-feature-toggle-store.js.map +1 -1
- package/dist/test/fixtures/fake-project-stats-store.d.ts +2 -1
- package/dist/test/fixtures/fake-project-stats-store.js +3 -0
- package/dist/test/fixtures/fake-project-stats-store.js.map +1 -1
- package/frontend/build/index.html +1 -1
- package/frontend/build/static/{CreateProject-a2c9a780.js → CreateProject-06fb0787.js} +1 -1
- package/frontend/build/static/{Error-38b8cdc0.js → Error-8b41c742.js} +1 -1
- package/frontend/build/static/{ExpandMore-ee840700.js → ExpandMore-14929315.js} +1 -1
- package/frontend/build/static/{FeatureArchiveDialog-0d7ae6c3.js → FeatureArchiveDialog-e0047702.js} +1 -1
- package/frontend/build/static/{FeatureMetricsChart-ed667dfd.js → FeatureMetricsChart-c3ad56b6.js} +1 -1
- package/frontend/build/static/{FeatureViewLazyExport-1b33033a.js → FeatureViewLazyExport-7827e8c5.js} +2 -2
- package/frontend/build/static/{LazyAdminExport-f1db04ed.js → LazyAdminExport-d95ca76c.js} +2 -2
- package/frontend/build/static/{LazyProjectExport-984413bf.js → LazyProjectExport-ef778b59.js} +1 -1
- package/frontend/build/static/{NetworkOverview-c9972cf4.js → NetworkOverview-b3e0c73f.js} +1 -1
- package/frontend/build/static/{NetworkTraffic-b4d65658.js → NetworkTraffic-729ad6fc.js} +1 -1
- package/frontend/build/static/{Playground-82d86aa7.js → Playground-a32c4264.js} +1 -1
- package/frontend/build/static/{StrategyItemContainer-72e360fd.js → StrategyItemContainer-681b4c1e.js} +1 -1
- package/frontend/build/static/{chartjs-adapter-date-fns.esm-00d0c032.js → chartjs-adapter-date-fns.esm-a07e3ced.js} +1 -1
- package/frontend/build/static/{index-c65a88d1.js → index-307298c7.js} +1 -1
- package/frontend/build/static/{index-78310b22.js → index-8da761a6.js} +1 -1
- package/frontend/build/static/{index-99d4171f.js → index-a6ca4785.js} +73 -73
- package/frontend/build/static/{unknownify-9d8df72f.js → unknownify-ac0e04aa.js} +1 -1
- package/frontend/build/static/{useProjectRole-dba93dda.js → useProjectRole-76e51391.js} +1 -1
- package/package.json +1 -1
- package/dist/lib/read-models/time-to-production/time-to-production.d.ts +0 -20
- package/dist/lib/read-models/time-to-production/time-to-production.js +0 -75
- package/dist/lib/read-models/time-to-production/time-to-production.js.map +0 -1
- package/dist/lib/read-models/time-to-production/time-to-production.test.js +0 -182
- package/dist/lib/read-models/time-to-production/time-to-production.test.js.map +0 -1
- /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-
|
|
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,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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"}
|
|
File without changes
|