codeforlife 2.10.6 → 2.11.0

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 (142) hide show
  1. package/README.md +10 -6
  2. package/dist/App-3VkR-ZEZ.js +27 -0
  3. package/dist/App-3VkR-ZEZ.js.map +1 -0
  4. package/dist/App-UfeajXtp.cjs +2 -0
  5. package/dist/App-UfeajXtp.cjs.map +1 -0
  6. package/dist/Countdown-BtUbr1J_.cjs +2 -0
  7. package/dist/{Countdown-CyJ-01oU.cjs.map → Countdown-BtUbr1J_.cjs.map} +1 -1
  8. package/dist/{Countdown-BTyB1rrK.js → Countdown-DhjAmB0u.js} +9 -9
  9. package/dist/{Countdown-BTyB1rrK.js.map → Countdown-DhjAmB0u.js.map} +1 -1
  10. package/dist/{Image-CgYjq-tA.cjs → Image-CgRVUblT.cjs} +2 -2
  11. package/dist/{Image-CgYjq-tA.cjs.map → Image-CgRVUblT.cjs.map} +1 -1
  12. package/dist/{Image-C-f2ChBh.js → Image-DTOu0h-V.js} +2 -2
  13. package/dist/{Image-C-f2ChBh.js.map → Image-DTOu0h-V.js.map} +1 -1
  14. package/dist/{LinkButton-BOPjG7_2.cjs → LinkButton-Kw2brLTK.cjs} +2 -2
  15. package/dist/{LinkButton-BOPjG7_2.cjs.map → LinkButton-Kw2brLTK.cjs.map} +1 -1
  16. package/dist/{LinkButton-Bk50AHHg.js → LinkButton-sQ5jgHnX.js} +3 -3
  17. package/dist/{LinkButton-Bk50AHHg.js.map → LinkButton-sQ5jgHnX.js.map} +1 -1
  18. package/dist/{Navigate-SL_oMjPc.js → Navigate-ClPcw87e.js} +3 -3
  19. package/dist/{Navigate-SL_oMjPc.js.map → Navigate-ClPcw87e.js.map} +1 -1
  20. package/dist/Navigate-CrMwdIBB.cjs +2 -0
  21. package/dist/{Navigate-C_sgy8Xs.cjs.map → Navigate-CrMwdIBB.cjs.map} +1 -1
  22. package/dist/_commonjsHelpers-DKOUU3wS.cjs +2 -0
  23. package/dist/_commonjsHelpers-DKOUU3wS.cjs.map +1 -0
  24. package/dist/_commonjsHelpers-DaMA6jEr.js +9 -0
  25. package/dist/_commonjsHelpers-DaMA6jEr.js.map +1 -0
  26. package/dist/api/endpoints/index.cjs.js +1 -1
  27. package/dist/api/endpoints/index.es.js +2 -2
  28. package/dist/api/index.cjs.js +3 -3
  29. package/dist/api/index.es.js +3 -3
  30. package/dist/api-9cnyvZj7.cjs +2 -0
  31. package/dist/{api-DIgp_6Vr.cjs.map → api-9cnyvZj7.cjs.map} +1 -1
  32. package/dist/{api-BvUiTeR7.js → api-BFYu8ZvQ.js} +2 -2
  33. package/dist/{api-BvUiTeR7.js.map → api-BFYu8ZvQ.js.map} +1 -1
  34. package/dist/{api-CaeeoZaI.cjs → api-CAH3GT1O.cjs} +2 -2
  35. package/dist/{api-CaeeoZaI.cjs.map → api-CAH3GT1O.cjs.map} +1 -1
  36. package/dist/{auth-CQ1InCxP.js → auth-Bb8WkZGN.js} +4 -4
  37. package/dist/{auth-CQ1InCxP.js.map → auth-Bb8WkZGN.js.map} +1 -1
  38. package/dist/auth-BwpsrTko.cjs +2 -0
  39. package/dist/{auth-B7Vdot4N.cjs.map → auth-BwpsrTko.cjs.map} +1 -1
  40. package/dist/client-BK9NlSVR.js +25208 -0
  41. package/dist/client-BK9NlSVR.js.map +1 -0
  42. package/dist/client-CmAMc2Wj.cjs +251 -0
  43. package/dist/client-CmAMc2Wj.cjs.map +1 -0
  44. package/dist/components/form/index.cjs.js +1 -1
  45. package/dist/components/form/index.es.js +1 -1
  46. package/dist/components/index.cjs.js +1 -1
  47. package/dist/components/index.cjs.js.map +1 -1
  48. package/dist/components/index.d.ts +0 -1
  49. package/dist/components/index.es.js +146 -182
  50. package/dist/components/index.es.js.map +1 -1
  51. package/dist/components/page/index.cjs.js +1 -1
  52. package/dist/components/page/index.es.js +1 -1
  53. package/dist/components/router/index.cjs.js +1 -1
  54. package/dist/components/router/index.es.js +2 -2
  55. package/dist/components/table/index.cjs.js +1 -1
  56. package/dist/components/table/index.es.js +1 -1
  57. package/dist/features/index.cjs.js +1 -1
  58. package/dist/features/index.cjs.js.map +1 -1
  59. package/dist/features/index.es.js +10 -11
  60. package/dist/features/index.es.js.map +1 -1
  61. package/dist/general-Bo6JGvKB.cjs +2 -0
  62. package/dist/{general-BPbbmkeX.cjs.map → general-Bo6JGvKB.cjs.map} +1 -1
  63. package/dist/{general-CtTJPCJn.js → general-D7Hqi3gj.js} +3 -3
  64. package/dist/{general-CtTJPCJn.js.map → general-D7Hqi3gj.js.map} +1 -1
  65. package/dist/hooks/index.cjs.js +1 -1
  66. package/dist/hooks/index.es.js +2 -2
  67. package/dist/{index-CBPn0wyX.cjs → index-5C9hpxRF.cjs} +2 -2
  68. package/dist/{index-CBPn0wyX.cjs.map → index-5C9hpxRF.cjs.map} +1 -1
  69. package/dist/{index-Dfo744Sb.js → index-B3e_XaVG.js} +2 -2
  70. package/dist/{index-Dfo744Sb.js.map → index-B3e_XaVG.js.map} +1 -1
  71. package/dist/{index-CXYppxE3.cjs → index-B89FjK7v.cjs} +2 -2
  72. package/dist/{index-CXYppxE3.cjs.map → index-B89FjK7v.cjs.map} +1 -1
  73. package/dist/{index-CI5O_yH6.js → index-BRHFlEjS.js} +37 -39
  74. package/dist/{index-CI5O_yH6.js.map → index-BRHFlEjS.js.map} +1 -1
  75. package/dist/{index-D8Gc0IWi.js → index-CHboZsxD.js} +2 -2
  76. package/dist/{index-D8Gc0IWi.js.map → index-CHboZsxD.js.map} +1 -1
  77. package/dist/index-CwC9mpb3.cjs +2 -0
  78. package/dist/{index-B6aNVvMr.cjs.map → index-CwC9mpb3.cjs.map} +1 -1
  79. package/dist/{index-DCI-3m7f.cjs → index-DuArGzQE.cjs} +3 -3
  80. package/dist/{index-DCI-3m7f.cjs.map → index-DuArGzQE.cjs.map} +1 -1
  81. package/dist/{index-DcmDxIXA.js → index-hdS8RgRc.js} +5 -5
  82. package/dist/{index-DcmDxIXA.js.map → index-hdS8RgRc.js.map} +1 -1
  83. package/dist/index.cjs.js +1 -1
  84. package/dist/index.d.ts +1 -1
  85. package/dist/index.es.js +6 -6
  86. package/dist/{jsx-runtime-Dszzpdy0.cjs → jsx-runtime-B2pbW5Fp.cjs} +3 -3
  87. package/dist/{jsx-runtime-Dszzpdy0.cjs.map → jsx-runtime-B2pbW5Fp.cjs.map} +1 -1
  88. package/dist/{jsx-runtime-C7wFtzyj.js → jsx-runtime-lzYHhGH3.js} +15 -15
  89. package/dist/{jsx-runtime-C7wFtzyj.js.map → jsx-runtime-lzYHhGH3.js.map} +1 -1
  90. package/dist/{schemas-D3tO0rys.js → schemas-BMQZbhti.js} +2 -2
  91. package/dist/{schemas-D3tO0rys.js.map → schemas-BMQZbhti.js.map} +1 -1
  92. package/dist/{schemas-CpAWhNsP.cjs → schemas-DXX4rh8i.cjs} +2 -2
  93. package/dist/{schemas-CpAWhNsP.cjs.map → schemas-DXX4rh8i.cjs.map} +1 -1
  94. package/dist/server/App.d.ts +15 -0
  95. package/dist/server/entry.cjs.js +209 -0
  96. package/dist/server/entry.cjs.js.map +1 -0
  97. package/dist/server/entry.d.ts +14 -0
  98. package/dist/server/entry.es.js +21885 -0
  99. package/dist/server/entry.es.js.map +1 -0
  100. package/dist/server/index.cjs.js +6 -0
  101. package/dist/server/index.cjs.js.map +1 -0
  102. package/dist/server/index.d.ts +6 -0
  103. package/dist/{server.es.js → server/index.es.js} +19 -17
  104. package/dist/server/index.es.js.map +1 -0
  105. package/dist/settings/index.cjs.js +1 -1
  106. package/dist/settings/index.cjs.js.map +1 -1
  107. package/dist/settings/index.d.ts +1 -2
  108. package/dist/settings/index.es.js +5 -5
  109. package/dist/settings/index.es.js.map +1 -1
  110. package/dist/theme/components/index.cjs.js +1 -1
  111. package/dist/theme/components/index.es.js +1 -1
  112. package/dist/theme/index.cjs.js +1 -1
  113. package/dist/theme/index.cjs.js.map +1 -1
  114. package/dist/theme/index.d.ts +1 -2
  115. package/dist/theme/index.es.js +5 -5
  116. package/dist/theme/index.es.js.map +1 -1
  117. package/dist/{urls-RtSTEZfW.cjs → urls-CGZI0f1w.cjs} +2 -2
  118. package/dist/{urls-RtSTEZfW.cjs.map → urls-CGZI0f1w.cjs.map} +1 -1
  119. package/dist/{urls-5m9PgoEX.js → urls-DP4a8kxP.js} +2 -2
  120. package/dist/{urls-5m9PgoEX.js.map → urls-DP4a8kxP.js.map} +1 -1
  121. package/dist/utils/api.cjs.js +1 -1
  122. package/dist/utils/api.es.js +2 -2
  123. package/dist/utils/router.cjs.js +1 -1
  124. package/dist/utils/router.es.js +2 -2
  125. package/dist/utils/test.cjs.js +1 -250
  126. package/dist/utils/test.cjs.js.map +1 -1
  127. package/dist/utils/test.es.js +20 -25223
  128. package/dist/utils/test.es.js.map +1 -1
  129. package/dist/utils/theme.cjs.js +1 -1
  130. package/dist/utils/theme.es.js +2 -2
  131. package/package.json +16 -9
  132. package/dist/Countdown-CyJ-01oU.cjs +0 -2
  133. package/dist/Navigate-C_sgy8Xs.cjs +0 -2
  134. package/dist/api-DIgp_6Vr.cjs +0 -2
  135. package/dist/auth-B7Vdot4N.cjs +0 -2
  136. package/dist/components/App.d.ts +0 -18
  137. package/dist/general-BPbbmkeX.cjs +0 -2
  138. package/dist/index-B6aNVvMr.cjs +0 -2
  139. package/dist/server.cjs.js +0 -6
  140. package/dist/server.cjs.js.map +0 -1
  141. package/dist/server.es.js.map +0 -1
  142. /package/dist/{server.d.ts → server/server.d.ts} +0 -0
@@ -1,2 +1,2 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});require("../jsx-runtime-Dszzpdy0.cjs");require("@mui/material");require("react");const e=require("../index-CXYppxE3.cjs");exports.getClassNames=e.getClassNames;exports.getStyleOverrides=e.getStyleOverrides;exports.includesClassNames=e.includesClassNames;exports.insertDividerBetweenElements=e.insertDividerBetweenElements;exports.matchClassNames=e.matchClassNames;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});require("../jsx-runtime-B2pbW5Fp.cjs");require("@mui/material");require("react");const e=require("../index-B89FjK7v.cjs");exports.getClassNames=e.getClassNames;exports.getStyleOverrides=e.getStyleOverrides;exports.includesClassNames=e.includesClassNames;exports.insertDividerBetweenElements=e.insertDividerBetweenElements;exports.matchClassNames=e.matchClassNames;
2
2
  //# sourceMappingURL=theme.cjs.js.map
@@ -1,7 +1,7 @@
1
- import "../jsx-runtime-C7wFtzyj.js";
1
+ import "../jsx-runtime-lzYHhGH3.js";
2
2
  import "@mui/material";
3
3
  import "react";
4
- import { b as i, g as r, i as l, a as o, m as n } from "../index-D8Gc0IWi.js";
4
+ import { b as i, g as r, i as l, a as o, m as n } from "../index-CHboZsxD.js";
5
5
  export {
6
6
  i as getClassNames,
7
7
  r as getStyleOverrides,
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "codeforlife",
3
3
  "description": "Common frontend code",
4
4
  "private": false,
5
- "version": "2.10.6",
5
+ "version": "2.11.0",
6
6
  "type": "module",
7
7
  "types": "dist/index.d.ts",
8
8
  "module": "dist/index.es.js",
@@ -63,6 +63,16 @@
63
63
  "import": "./dist/middlewares/index.es.js",
64
64
  "require": "./dist/middlewares/index.cjs.js"
65
65
  },
66
+ "./server": {
67
+ "types": "./dist/server/index.d.ts",
68
+ "import": "./dist/server/index.es.js",
69
+ "require": "./dist/server/index.cjs.js"
70
+ },
71
+ "./server/entry": {
72
+ "types": "./dist/server/entry.d.ts",
73
+ "import": "./dist/server/entry.es.js",
74
+ "require": "./dist/server/entry.cjs.js"
75
+ },
66
76
  "./settings": {
67
77
  "types": "./dist/settings/index.d.ts",
68
78
  "import": "./dist/settings/index.es.js",
@@ -73,6 +83,7 @@
73
83
  "import": "./dist/slices/index.es.js",
74
84
  "require": "./dist/slices/index.cjs.js"
75
85
  },
86
+ "./style.css": "./dist/style.css",
76
87
  "./theme": {
77
88
  "types": "./dist/theme/index.d.ts",
78
89
  "import": "./dist/theme/index.es.js",
@@ -132,13 +143,7 @@
132
143
  "types": "./dist/utils/window.d.ts",
133
144
  "import": "./dist/utils/window.es.js",
134
145
  "require": "./dist/utils/window.cjs.js"
135
- },
136
- "./server": {
137
- "types": "./dist/server.d.ts",
138
- "import": "./dist/server.es.js",
139
- "require": "./dist/server.cjs.js"
140
- },
141
- "./style.css": "./dist/style.css"
146
+ }
142
147
  },
143
148
  "files": [
144
149
  "dist"
@@ -164,13 +169,15 @@
164
169
  "✅ Do add `devDependencies` that are unique to this package."
165
170
  ],
166
171
  "dependencies": {
172
+ "@emotion/cache": "11.14.0",
167
173
  "@emotion/react": "11.12.0",
174
+ "@emotion/server": "11.11.0",
168
175
  "@emotion/styled": "11.14.1",
169
176
  "@mui/icons-material": "7.3.2",
170
177
  "@mui/material": "7.3.2",
171
178
  "@mui/x-date-pickers": "8.11.3",
172
179
  "@reduxjs/toolkit": "2.9.0",
173
- "compression": "^1.7.5",
180
+ "compression": "1.8.1",
174
181
  "dayjs": "^1.11.11",
175
182
  "express": "^4.21.2",
176
183
  "formik": "^2.2.9",
@@ -1,2 +0,0 @@
1
- "use strict";const n=require("./jsx-runtime-Dszzpdy0.cjs"),c=require("react"),m=require("@mui/material");require("./auth-B7Vdot4N.cjs");const q=require("./general-BPbbmkeX.cjs");require("react-router");require("yup");require("@mui/icons-material");require("./palette-BnIdHKDE.cjs");const x=({seconds:e,start:u=!0,onEnd:i,...o})=>{e=Math.floor(e);const r=q.useCountdown(e)[0],[s,a]=c.useState(!u);r===0&&!s&&(a(!0),i()),e=Math.floor(r%60);const t=Math.floor(r/60);return n.jsxRuntimeExports.jsx(n.jsxRuntimeExports.Fragment,{children:r>0&&n.jsxRuntimeExports.jsxs(m.Typography,{...o,children:[t>0&&`${t} ${t>1?"mins":"min"} `,e>0&&`${e} ${e>1?"secs":"sec"}`]})})};exports.Countdown=x;
2
- //# sourceMappingURL=Countdown-CyJ-01oU.cjs.map
@@ -1,2 +0,0 @@
1
- "use strict";const n=require("./jsx-runtime-Dszzpdy0.cjs"),e=require("@mui/material"),u=require("react"),i=require("react-router");require("@mui/icons-material");require("./palette-BnIdHKDE.cjs");const c=require("./auth-B7Vdot4N.cjs"),x=t=>n.jsxRuntimeExports.jsx(e.Link,{component:i.Link,...t}),m=t=>n.jsxRuntimeExports.jsx(e.IconButton,{...t,component:i.Link}),L=t=>n.jsxRuntimeExports.jsx(e.ListItem,{...t,component:i.Link}),a=t=>n.jsxRuntimeExports.jsx(e.Tab,{...t,component:i.Link}),k=({delta:t,to:s,...o})=>{const r=c.useNavigate();return u.useEffect(()=>{typeof t=="number"?r(t):r(s,o)},[r,t,s,o]),n.jsxRuntimeExports.jsx(n.jsxRuntimeExports.Fragment,{})};exports.Link=x;exports.LinkIconButton=m;exports.LinkListItem=L;exports.LinkTab=a;exports.Navigate=k;
2
- //# sourceMappingURL=Navigate-C_sgy8Xs.cjs.map
@@ -1,2 +0,0 @@
1
- "use strict";const r=require("react");function u(g){const{page:a=0,limit:e=150}=g||{},[c,f]=r.useState({page:a,limit:e,offset:a*e});return[c,t=>{f(({page:p,limit:o})=>{const s=typeof t=="function"?t({page:p,limit:o}):t;let i=s.page;const n=s.limit;return n!==o&&(i=0),{page:i,limit:n,offset:i*n}})}]}exports.usePagination=u;
2
- //# sourceMappingURL=api-DIgp_6Vr.cjs.map
@@ -1,2 +0,0 @@
1
- "use strict";const y=require("./jsx-runtime-Dszzpdy0.cjs"),C=require("yup"),l=require("react"),w=require("js-cookie"),S=require("react-router"),z=require("react-redux"),V=require("./settings/index.cjs.js"),B=require("./session-CE2U7oL1.cjs"),E=require("./utils/auth.cjs.js");require("@mui/material");const G=require("./utils/general.cjs.js");require("@mui/icons-material");require("./schemas-CpAWhNsP.cjs");require("./urls-RtSTEZfW.cjs");const k=require("./utils/schema.cjs.js");require("./palette-BnIdHKDE.cjs");function H(e){const n=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(e){for(const t in e)if(t!=="default"){const s=Object.getOwnPropertyDescriptor(e,t);Object.defineProperty(n,t,s.get?s:{enumerable:!0,get:()=>e[t]})}}return n.default=e,Object.freeze(n)}const T=H(C);function v(){const e=S.useNavigate(),n=x();return(t,s=void 0)=>{if(typeof t=="number")e(t);else{const{next:o=!0,...i}=s||{};e(o&&"next"in n?n.next:t,i)}}}function q(){return S.useLocation()}function x(e,n){const t=Object.fromEntries(S.useSearchParams()[0].entries());return e?k.tryValidateSync(t,C.object(e),n):t}function J(e,n){const t=S.useParams();return e?k.tryValidateSync(t,C.object(e),n):t}function Q({shape:e,children:n,onValidationError:t,onValidationSuccess:s=()=>{},validateOptions:o}){const i=J(e,o),a=v();return l.useEffect(()=>{i?s(i):t(a)},[]),i?n(i):y.jsxRuntimeExports.jsx(y.jsxRuntimeExports.Fragment,{})}function m(e=V.SESSION_METADATA_COOKIE_NAME){return z.useSelector(B.selectIsLoggedIn)?JSON.parse(w.get(e)):void 0}m.predefine=(e=V.SESSION_METADATA_COOKIE_NAME)=>()=>m(e);function W(e,n={}){const{userType:t,next:s=!0}=n,{pathname:o}=q(),i=v(),a=m(),c=t&&(!a||a.user_type!==t);return l.useEffect(()=>{c&&i({pathname:"/login"+{teacher:"/teacher",student:"/student",indy:"/independent"}[t],search:s?S.createSearchParams({next:o}).toString():void 0})},[i,c,t,s,o]),c?y.jsxRuntimeExports.jsx(y.jsxRuntimeExports.Fragment,{}):typeof e=="function"?e(a):e}function F(e,n=32,t="state"){const s=E.makeOAuth2StorageKey(e,t),o=sessionStorage.getItem(s),[i,a]=l.useState();l.useEffect(()=>{let u;o&&o.length===n?u=o:(u=G.generateSecureRandomString(n),sessionStorage.setItem(s,u)),a(u)},[s,o,n]);const c=l.useCallback(()=>{sessionStorage.removeItem(s),a(void 0)},[s]);return[i,c]}function D(e,n=128,t="codeChallenge"){const s=E.makeOAuth2StorageKey(e,t),o=sessionStorage.getItem(s),[i,a]=l.useState();l.useEffect(()=>{let u;if(o){const r=JSON.parse(o);typeof r=="object"&&r&&"verifier"in r&&typeof r.verifier=="string"&&r.verifier.length===n&&"challenge"in r&&typeof r.challenge=="string"&&"method"in r&&r.method==="S256"&&(u={verifier:r.verifier,challenge:r.challenge,method:r.method})}u?a(u):E.generateOAuth2CodeChallenge(n).then(r=>{sessionStorage.setItem(s,JSON.stringify(r)),a(r)}).catch(r=>{r&&console.error(r)})},[s,o,n]);const c=l.useCallback(()=>{sessionStorage.removeItem(s),a(void 0)},[s]);return[i,c]}function X({provider:e,authUri:n,clientId:t,redirectUri:s,scope:o,responseType:i="code",accessType:a="offline",prompt:c,useSessionMetadata:u,useLoginMutation:r,onCreateSession:P,onRetrieveSession:j}){const[h,I]=F(e),[{verifier:p,challenge:b,method:M}={},R]=D(e),[N,{originalArgs:f={},isLoading:L,isError:K}]=r(),O=u(),_=v(),d=x({code:T.string(),state:T.string()})||{},g=q().state||{};if(l.useEffect(()=>{d.code&&d.state&&_(".",{replace:!0,next:!1,state:{code:d.code,state:d.state}})},[d.code,d.state,_]),l.useEffect(()=>{O?j(O):h&&p&&g.code&&g.state===h&&(f.code!==g.code||f.code_verifier!==p||f.redirect_uri!==s||!K)&&!L&&N({code:g.code,code_verifier:p,redirect_uri:s}).unwrap().then(P).catch(()=>{_(".",{replace:!0,state:{notifications:[{props:{error:!0,children:"Failed to login. Please try again."}}]}})}).finally(()=>{I(),R()})},[_,s,h,g.state,I,p,g.code,R,N,L,K,f.code,f.code_verifier,f.redirect_uri,O,P,j]),h&&b&&M){const A={client_id:t,redirect_uri:s,scope:o,response_type:i,access_type:a,state:h,code_challenge:b,code_challenge_method:M};return c&&(A.prompt=c),[n+"?"+new URLSearchParams(A).toString(),A]}return[]}const Y=e=>X("useSessionMetadata"in e?e:{...e,useSessionMetadata:m});exports.useLocation=q;exports.useNavigate=v;exports.useOAuth2=Y;exports.useOAuth2CodeChallenge=D;exports.useOAuth2State=F;exports.useParams=J;exports.useParamsRequired=Q;exports.useSearchParams=x;exports.useSession=W;exports.useSessionMetadata=m;
2
- //# sourceMappingURL=auth-B7Vdot4N.cjs.map
@@ -1,18 +0,0 @@
1
- import { JSX, ReactNode } from 'react';
2
- import { ProviderProps } from 'react-redux';
3
- import { Action } from 'redux';
4
- import { ThemeProviderProps } from '@mui/material';
5
- export interface AppProps<A extends Action = Action, S = unknown> {
6
- path?: string;
7
- theme: ThemeProviderProps["theme"];
8
- store: ProviderProps<A, S>["store"];
9
- routes: ReactNode;
10
- header?: ReactNode;
11
- footer?: ReactNode;
12
- headerExcludePaths?: string[];
13
- footerExcludePaths?: string[];
14
- maxIdleSeconds?: number;
15
- maxTotalSeconds?: number;
16
- }
17
- declare const App: <A extends Action = Action, S = unknown>({ path, theme, store, maxIdleSeconds, maxTotalSeconds, ...routesProps }: AppProps<A, S>) => JSX.Element;
18
- export default App;
@@ -1,2 +0,0 @@
1
- "use strict";const s=require("react");function d({props:r,attrs:t,eventTypes:c}){const[o,u]=s.useState();return s.useEffect(()=>{if(document.querySelector(`script[src="${r.src}"]`))throw Error("already exists");const e=document.createElement("script");Object.entries(r).forEach(([n,i])=>{e[n]=i}),t!==void 0&&Object.entries(t).forEach(([n,i])=>{e.setAttribute(n,i)});function E(n){u(n.type)}return c?.forEach(n=>{e.addEventListener(n,E)}),document.head.appendChild(e),()=>{c?.forEach(n=>{e.removeEventListener(n,E)}),document.head.removeChild(e)}},[c,t,r]),o}function f(r,t=1){if(r<=0)throw Error("seconds must be > 0");if(t<=0)throw Error("interval must be > 0");const[c,o]=s.useState(r);return s.useEffect(()=>{const u=setInterval(()=>{o(e=>(e=e-t,e<0?0:e))},t*1e3);return()=>{clearInterval(u)}},[t]),[c,o]}function a(r,t,c,o={}){const{options:u,deps:e=[]}=o;s.useEffect(()=>(r.addEventListener(t,c,u),()=>{r.removeEventListener(t,c,u)}),e)}exports.useCountdown=f;exports.useEventListener=a;exports.useExternalScript=d;
2
- //# sourceMappingURL=general-BPbbmkeX.cjs.map
@@ -1,2 +0,0 @@
1
- "use strict";const t=require("./jsx-runtime-Dszzpdy0.cjs"),m=require("react"),e=require("@mui/material"),i=({headers:s,children:n,containerProps:r,headProps:a,headRowProps:c,bodyProps:j,...u})=>t.jsxRuntimeExports.jsx(e.TableContainer,{...r,children:t.jsxRuntimeExports.jsxs(e.Table,{...u,children:[t.jsxRuntimeExports.jsx(e.TableHead,{...a,children:t.jsxRuntimeExports.jsx(e.TableRow,{...c,children:s.map((l,b)=>{const x=`table-head-cell-${b}`;return typeof l=="string"||m.isValidElement(l)?t.jsxRuntimeExports.jsx(e.TableCell,{children:l},x):t.jsxRuntimeExports.jsx(e.TableCell,{...l},x)})})}),t.jsxRuntimeExports.jsx(e.TableBody,{...j,children:n})]})}),o=({cellProps:s,...n})=>t.jsxRuntimeExports.jsx(e.TableCell,{...s,children:t.jsxRuntimeExports.jsx(e.Stack,{...n})}),R=Object.freeze(Object.defineProperty({__proto__:null,BodyRow:e.TableRow,Cell:e.TableCell,CellStack:o,Table:i},Symbol.toStringTag,{value:"Module"}));exports.CellStack=o;exports.Table=i;exports.index=R;
2
- //# sourceMappingURL=index-B6aNVvMr.cjs.map
@@ -1,6 +0,0 @@
1
- "use strict";var u=Object.create;var c=Object.defineProperty;var m=Object.getOwnPropertyDescriptor;var v=Object.getOwnPropertyNames;var C=Object.getPrototypeOf,k=Object.prototype.hasOwnProperty;var w=(r,s,e,t)=>{if(s&&typeof s=="object"||typeof s=="function")for(let a of v(s))!k.call(r,a)&&a!==e&&c(r,a,{get:()=>s[a],enumerable:!(t=m(s,a))||t.enumerable});return r};var o=(r,s,e)=>(e=r!=null?u(C(r)):{},w(s||!r||!r.__esModule?c(e,"default",{value:r,enumerable:!0}):e,r));const y=require("memory-cache"),S=require("node:crypto"),f=require("express"),l=require("node:fs/promises"),I=require("node:http");class P{envIsProduction;templateHtml;hostname;mode;port;base;app;server;cache;healthCheckCacheKey;healthCheckCacheTimeout;healthCheckStatusCodes;devtoolsWorkspaceUUID;constructor({mode:s,port:e,base:t}={}){this.envIsProduction=process.env.NODE_ENV==="production",this.templateHtml="",this.hostname=this.envIsProduction?"0.0.0.0":"127.0.0.1",this.mode=s||process.env.MODE||"development",this.port=e||(process.env.PORT?Number(process.env.PORT):this.envIsProduction?8080:5173),this.base=t||process.env.BASE||"/",this.app=f(),this.server=I.createServer(this.app),this.cache=new y.Cache,this.healthCheckCacheKey="health-check",this.healthCheckCacheTimeout=3e4,this.healthCheckStatusCodes={healthy:200,startingUp:503,shuttingDown:503,unhealthy:503,unknown:503},this.devtoolsWorkspaceUUID=S.randomUUID()}getHealthCheck(s){return{healthStatus:"healthy",additionalInfo:"All healthy."}}handleHealthCheck(s,e){let t=this.cache.get(this.healthCheckCacheKey);if(t===null){const a=this.getHealthCheck(s);a.healthStatus!=="healthy"&&console.warn(`health check: ${JSON.stringify(a)}`),t={appId:process.env.APP_ID||"REPLACE_ME",healthStatus:a.healthStatus,lastCheckedTimestamp:new Date().toISOString(),additionalInformation:a.additionalInfo,startupTimestamp:new Date().toISOString(),appVersion:process.env.APP_VERSION||"REPLACE_ME",details:a.details||[]},this.cache.put(this.healthCheckCacheKey,t,this.healthCheckCacheTimeout)}e.status(this.healthCheckStatusCodes[t.healthStatus]).json(t)}async handleServeHtml(s,e,{getRenderAndTemplate:t,onServeError:a}){try{const h=s.originalUrl.replace(this.base,""),[n,p]=await t(h),i=await n(h),d=p.replace("<!--app-head-->",i.head??"").replace("<!--app-html-->",i.html??"");e.status(200).set({"Content-Type":"text/html"}).send(d)}catch(h){if(h instanceof Error){console.error(h.stack);const n=a(h);e.status(500).end(n)}}}handleChromeDevTools(s,e){if(this.envIsProduction)e.status(404).json({});else{const t=process.env.LOCAL_WORKSPACE_PATH;let a,h;t?(a=200,h={workspace:{uuid:this.devtoolsWorkspaceUUID,root:t}}):(a=404,h={error:"Local workspace path not configured."}),e.status(a).json(h)}}async setUpProduction(){const s=(await import("compression")).default,e=(await import("sirv")).default;return this.templateHtml=await l.readFile("./dist/client/index.html","utf-8"),this.app.use(s()),this.app.use(this.base,e("./dist/client",{extensions:[]})),{getRenderAndTemplate:async()=>{const t=(await import("../../../dist/server/entry-server.js")).render,a=this.templateHtml;return[t,a]},onServeError:()=>{}}}async setUpDevelopment(){const{createServer:s}=await import("vite"),e=await s({configFile:"/workspace/frontend/vite.config.ts",server:{middlewareMode:!0,hmr:{server:this.server}},appType:"custom",base:this.base,mode:this.mode});return this.app.use(e.middlewares),{getRenderAndTemplate:async t=>{const a=(await e.ssrLoadModule("/src/entry-server.tsx")).render;let h=await l.readFile("./index.html","utf-8");return h=await e.transformIndexHtml(t,h),[a,h]},onServeError:t=>(e.ssrFixStacktrace(t),t.stack)}}async run(){const s=this.envIsProduction?await this.setUpProduction():await this.setUpDevelopment();this.app.get("/health-check",(e,t)=>{this.handleHealthCheck(e,t)}),this.app.get("/.well-known/appspecific/com.chrome.devtools.json",(e,t)=>{this.handleChromeDevTools(e,t)}),this.app.get("*",async(e,t)=>{await this.handleServeHtml(e,t,s)}),this.server.listen(this.port,this.hostname,()=>{let e=`Server started.
2
- url: http://${this.hostname}:${this.port}
3
- environment: ${process.env.NODE_ENV}
4
- `;this.envIsProduction||(e+=`mode: ${this.mode}
5
- `),console.log(e)})}}module.exports=P;
6
- //# sourceMappingURL=server.cjs.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"server.cjs.js","sources":["../src/server.ts"],"sourcesContent":["/**\n * © Ocado Group\n * Created on 13/12/2024 at 12:15:05(+00:00).\n *\n * A server for an app in a live environment.\n * Based off: https://github.com/bluwy/create-vite-extra/blob/master/template-ssr-react-ts/server.js\n */\n\nimport { Cache, type CacheClass } from \"memory-cache\"\nimport { type UUID, randomUUID } from \"node:crypto\"\nimport express, { type Express, type Request, type Response } from \"express\"\nimport fs from \"node:fs/promises\"\nimport http from \"node:http\"\n\ntype Mode = \"development\" | \"staging\" | \"production\"\ntype Options = Partial<{\n mode: Mode\n port: number\n base: string\n}>\n\ntype HealthStatus =\n | \"healthy\"\n | \"startingUp\"\n | \"shuttingDown\"\n | \"unhealthy\"\n | \"unknown\"\ntype HealthCheck = {\n healthStatus: HealthStatus\n additionalInfo: string\n details?: Array<{\n name: string\n description: string\n health: HealthStatus\n }>\n}\ntype HealthCheckResponse = {\n appId: string\n healthStatus: HealthStatus\n lastCheckedTimestamp: string\n additionalInformation: string\n startupTimestamp: string\n appVersion: string\n details: Array<{\n name: string\n description: string\n health: HealthStatus\n }>\n}\n\ntype Render = (path: string) => Promise<{ head?: string; html?: string }>\ntype EntryModule = { render: Render }\ntype RenderAndTemplate = [Render, string]\ntype GetRenderAndTemplate = (path: string) => Promise<RenderAndTemplate>\ntype OnServeError = (error: Error) => string | undefined\n\ntype Setup = {\n getRenderAndTemplate: GetRenderAndTemplate\n onServeError: OnServeError\n}\n\nexport default class Server {\n envIsProduction: boolean\n templateHtml: string\n hostname: string\n mode: Mode\n port: number\n base: string\n app: Express\n server: http.Server<typeof http.IncomingMessage, typeof http.ServerResponse>\n cache: CacheClass<string, any>\n healthCheckCacheKey: string\n healthCheckCacheTimeout: number\n healthCheckStatusCodes: Record<HealthStatus, number>\n devtoolsWorkspaceUUID: UUID\n\n constructor({ mode, port, base }: Options = {}) {\n this.envIsProduction = process.env.NODE_ENV === \"production\"\n this.templateHtml = \"\"\n this.hostname = this.envIsProduction ? \"0.0.0.0\" : \"127.0.0.1\"\n\n this.mode = mode || (process.env.MODE as Mode) || \"development\"\n this.port =\n port ||\n (process.env.PORT\n ? Number(process.env.PORT)\n : this.envIsProduction\n ? 8080\n : 5173)\n this.base = base || process.env.BASE || \"/\"\n\n this.app = express()\n this.server = http.createServer(this.app)\n this.cache = new Cache()\n\n this.healthCheckCacheKey = \"health-check\"\n this.healthCheckCacheTimeout = 30000\n this.healthCheckStatusCodes = {\n // The app is running normally.\n healthy: 200,\n // The app is performing app-specific initialisation which must\n // complete before it will serve normal application requests\n // (perhaps the app is warming a cache or something similar). You\n // only need to use this status if your app will be in a start-up\n // mode for a prolonged period of time.\n startingUp: 503,\n // The app is shutting down. As with startingUp, you only need to\n // use this status if your app takes a prolonged amount of time\n // to shutdown, perhaps because it waits for a long-running\n // process to complete before shutting down.\n shuttingDown: 503,\n // The app is not running normally.\n unhealthy: 503,\n // The app is not able to report its own state.\n unknown: 503,\n }\n\n this.devtoolsWorkspaceUUID = randomUUID()\n }\n\n // @ts-expect-error unused var\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n getHealthCheck(request: Request): HealthCheck {\n return {\n healthStatus: \"healthy\",\n additionalInfo: \"All healthy.\",\n }\n }\n\n handleHealthCheck(request: Request, response: Response): void {\n let value: HealthCheckResponse = this.cache.get(\n this.healthCheckCacheKey,\n ) as HealthCheckResponse\n if (value === null) {\n const healthCheck = this.getHealthCheck(request)\n\n if (healthCheck.healthStatus !== \"healthy\") {\n console.warn(`health check: ${JSON.stringify(healthCheck)}`)\n }\n\n value = {\n appId: process.env.APP_ID || \"REPLACE_ME\",\n healthStatus: healthCheck.healthStatus,\n lastCheckedTimestamp: new Date().toISOString(),\n additionalInformation: healthCheck.additionalInfo,\n startupTimestamp: new Date().toISOString(),\n appVersion: process.env.APP_VERSION || \"REPLACE_ME\",\n details: healthCheck.details || [],\n }\n\n this.cache.put(\n this.healthCheckCacheKey,\n value,\n this.healthCheckCacheTimeout,\n )\n }\n\n response.status(this.healthCheckStatusCodes[value.healthStatus]).json(value)\n }\n\n async handleServeHtml(\n request: Request,\n response: Response,\n { getRenderAndTemplate, onServeError }: Setup,\n ): Promise<void> {\n try {\n const path = request.originalUrl.replace(this.base, \"\")\n\n const [render, template] = await getRenderAndTemplate(path)\n\n const rendered = await render(path)\n\n const html = template\n .replace(`<!--app-head-->`, rendered.head ?? \"\")\n .replace(`<!--app-html-->`, rendered.html ?? \"\")\n\n response.status(200).set({ \"Content-Type\": \"text/html\" }).send(html)\n } catch (error) {\n if (error instanceof Error) {\n console.error(error.stack)\n const body = onServeError(error)\n response.status(500).end(body)\n }\n }\n }\n\n // @ts-expect-error unused var\n handleChromeDevTools(request: Request, response: Response) {\n if (this.envIsProduction) {\n response.status(404).json({})\n } else {\n const localWorkspacePath = process.env.LOCAL_WORKSPACE_PATH\n\n let code: number\n let body: object\n if (localWorkspacePath) {\n code = 200\n body = {\n workspace: {\n uuid: this.devtoolsWorkspaceUUID,\n root: localWorkspacePath,\n },\n }\n } else {\n code = 404\n body = { error: \"Local workspace path not configured.\" }\n }\n\n response.status(code).json(body)\n }\n }\n\n async setUpProduction(): Promise<Setup> {\n const compression = (await import(\"compression\")).default\n const sirv = (await import(\"sirv\")).default\n\n this.templateHtml = await fs.readFile(\"./dist/client/index.html\", \"utf-8\")\n\n this.app.use(compression())\n this.app.use(this.base, sirv(\"./dist/client\", { extensions: [] }))\n\n return {\n getRenderAndTemplate: async () => {\n const render = (\n (await import(\n // @ts-expect-error only present after building installing app.\n \"../../../dist/server/entry-server.js\"\n )) as EntryModule\n ).render\n\n // Use cached template.\n const template = this.templateHtml\n\n return [render, template]\n },\n onServeError: () => undefined,\n }\n }\n\n async setUpDevelopment(): Promise<Setup> {\n const { createServer } = await import(\"vite\")\n\n const vite = await createServer({\n configFile: \"/workspace/frontend/vite.config.ts\",\n server: {\n middlewareMode: true,\n hmr: { server: this.server },\n },\n appType: \"custom\",\n base: this.base,\n mode: this.mode,\n })\n\n this.app.use(vite.middlewares)\n\n return {\n getRenderAndTemplate: async path => {\n const render = (\n (await vite.ssrLoadModule(\"/src/entry-server.tsx\")) as EntryModule\n ).render\n\n // Always read fresh template.\n let template = await fs.readFile(\"./index.html\", \"utf-8\")\n template = await vite.transformIndexHtml(path, template)\n\n return [render, template]\n },\n onServeError: error => {\n vite.ssrFixStacktrace(error)\n return error.stack\n },\n }\n }\n\n async run() {\n const setup = this.envIsProduction\n ? await this.setUpProduction()\n : await this.setUpDevelopment()\n\n this.app.get(\"/health-check\", (request, response) => {\n this.handleHealthCheck(request, response)\n })\n\n this.app.get(\n \"/.well-known/appspecific/com.chrome.devtools.json\",\n (request, response) => {\n this.handleChromeDevTools(request, response)\n },\n )\n\n this.app.get(\"*\", async (request, response) => {\n await this.handleServeHtml(request, response, setup)\n })\n\n this.server.listen(this.port, this.hostname, () => {\n let startMessage =\n \"Server started.\\n\" +\n `url: http://${this.hostname}:${this.port}\\n` +\n `environment: ${process.env.NODE_ENV}\\n`\n\n if (!this.envIsProduction) startMessage += `mode: ${this.mode}\\n`\n\n console.log(startMessage)\n })\n }\n}\n"],"names":["Server","mode","port","base","express","http","Cache","randomUUID","request","response","value","healthCheck","getRenderAndTemplate","onServeError","path","render","template","rendered","html","error","body","localWorkspacePath","code","compression","sirv","fs","createServer","vite","setup","startMessage"],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"server.es.js","sources":["../src/server.ts"],"sourcesContent":["/**\n * © Ocado Group\n * Created on 13/12/2024 at 12:15:05(+00:00).\n *\n * A server for an app in a live environment.\n * Based off: https://github.com/bluwy/create-vite-extra/blob/master/template-ssr-react-ts/server.js\n */\n\nimport { Cache, type CacheClass } from \"memory-cache\"\nimport { type UUID, randomUUID } from \"node:crypto\"\nimport express, { type Express, type Request, type Response } from \"express\"\nimport fs from \"node:fs/promises\"\nimport http from \"node:http\"\n\ntype Mode = \"development\" | \"staging\" | \"production\"\ntype Options = Partial<{\n mode: Mode\n port: number\n base: string\n}>\n\ntype HealthStatus =\n | \"healthy\"\n | \"startingUp\"\n | \"shuttingDown\"\n | \"unhealthy\"\n | \"unknown\"\ntype HealthCheck = {\n healthStatus: HealthStatus\n additionalInfo: string\n details?: Array<{\n name: string\n description: string\n health: HealthStatus\n }>\n}\ntype HealthCheckResponse = {\n appId: string\n healthStatus: HealthStatus\n lastCheckedTimestamp: string\n additionalInformation: string\n startupTimestamp: string\n appVersion: string\n details: Array<{\n name: string\n description: string\n health: HealthStatus\n }>\n}\n\ntype Render = (path: string) => Promise<{ head?: string; html?: string }>\ntype EntryModule = { render: Render }\ntype RenderAndTemplate = [Render, string]\ntype GetRenderAndTemplate = (path: string) => Promise<RenderAndTemplate>\ntype OnServeError = (error: Error) => string | undefined\n\ntype Setup = {\n getRenderAndTemplate: GetRenderAndTemplate\n onServeError: OnServeError\n}\n\nexport default class Server {\n envIsProduction: boolean\n templateHtml: string\n hostname: string\n mode: Mode\n port: number\n base: string\n app: Express\n server: http.Server<typeof http.IncomingMessage, typeof http.ServerResponse>\n cache: CacheClass<string, any>\n healthCheckCacheKey: string\n healthCheckCacheTimeout: number\n healthCheckStatusCodes: Record<HealthStatus, number>\n devtoolsWorkspaceUUID: UUID\n\n constructor({ mode, port, base }: Options = {}) {\n this.envIsProduction = process.env.NODE_ENV === \"production\"\n this.templateHtml = \"\"\n this.hostname = this.envIsProduction ? \"0.0.0.0\" : \"127.0.0.1\"\n\n this.mode = mode || (process.env.MODE as Mode) || \"development\"\n this.port =\n port ||\n (process.env.PORT\n ? Number(process.env.PORT)\n : this.envIsProduction\n ? 8080\n : 5173)\n this.base = base || process.env.BASE || \"/\"\n\n this.app = express()\n this.server = http.createServer(this.app)\n this.cache = new Cache()\n\n this.healthCheckCacheKey = \"health-check\"\n this.healthCheckCacheTimeout = 30000\n this.healthCheckStatusCodes = {\n // The app is running normally.\n healthy: 200,\n // The app is performing app-specific initialisation which must\n // complete before it will serve normal application requests\n // (perhaps the app is warming a cache or something similar). You\n // only need to use this status if your app will be in a start-up\n // mode for a prolonged period of time.\n startingUp: 503,\n // The app is shutting down. As with startingUp, you only need to\n // use this status if your app takes a prolonged amount of time\n // to shutdown, perhaps because it waits for a long-running\n // process to complete before shutting down.\n shuttingDown: 503,\n // The app is not running normally.\n unhealthy: 503,\n // The app is not able to report its own state.\n unknown: 503,\n }\n\n this.devtoolsWorkspaceUUID = randomUUID()\n }\n\n // @ts-expect-error unused var\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n getHealthCheck(request: Request): HealthCheck {\n return {\n healthStatus: \"healthy\",\n additionalInfo: \"All healthy.\",\n }\n }\n\n handleHealthCheck(request: Request, response: Response): void {\n let value: HealthCheckResponse = this.cache.get(\n this.healthCheckCacheKey,\n ) as HealthCheckResponse\n if (value === null) {\n const healthCheck = this.getHealthCheck(request)\n\n if (healthCheck.healthStatus !== \"healthy\") {\n console.warn(`health check: ${JSON.stringify(healthCheck)}`)\n }\n\n value = {\n appId: process.env.APP_ID || \"REPLACE_ME\",\n healthStatus: healthCheck.healthStatus,\n lastCheckedTimestamp: new Date().toISOString(),\n additionalInformation: healthCheck.additionalInfo,\n startupTimestamp: new Date().toISOString(),\n appVersion: process.env.APP_VERSION || \"REPLACE_ME\",\n details: healthCheck.details || [],\n }\n\n this.cache.put(\n this.healthCheckCacheKey,\n value,\n this.healthCheckCacheTimeout,\n )\n }\n\n response.status(this.healthCheckStatusCodes[value.healthStatus]).json(value)\n }\n\n async handleServeHtml(\n request: Request,\n response: Response,\n { getRenderAndTemplate, onServeError }: Setup,\n ): Promise<void> {\n try {\n const path = request.originalUrl.replace(this.base, \"\")\n\n const [render, template] = await getRenderAndTemplate(path)\n\n const rendered = await render(path)\n\n const html = template\n .replace(`<!--app-head-->`, rendered.head ?? \"\")\n .replace(`<!--app-html-->`, rendered.html ?? \"\")\n\n response.status(200).set({ \"Content-Type\": \"text/html\" }).send(html)\n } catch (error) {\n if (error instanceof Error) {\n console.error(error.stack)\n const body = onServeError(error)\n response.status(500).end(body)\n }\n }\n }\n\n // @ts-expect-error unused var\n handleChromeDevTools(request: Request, response: Response) {\n if (this.envIsProduction) {\n response.status(404).json({})\n } else {\n const localWorkspacePath = process.env.LOCAL_WORKSPACE_PATH\n\n let code: number\n let body: object\n if (localWorkspacePath) {\n code = 200\n body = {\n workspace: {\n uuid: this.devtoolsWorkspaceUUID,\n root: localWorkspacePath,\n },\n }\n } else {\n code = 404\n body = { error: \"Local workspace path not configured.\" }\n }\n\n response.status(code).json(body)\n }\n }\n\n async setUpProduction(): Promise<Setup> {\n const compression = (await import(\"compression\")).default\n const sirv = (await import(\"sirv\")).default\n\n this.templateHtml = await fs.readFile(\"./dist/client/index.html\", \"utf-8\")\n\n this.app.use(compression())\n this.app.use(this.base, sirv(\"./dist/client\", { extensions: [] }))\n\n return {\n getRenderAndTemplate: async () => {\n const render = (\n (await import(\n // @ts-expect-error only present after building installing app.\n \"../../../dist/server/entry-server.js\"\n )) as EntryModule\n ).render\n\n // Use cached template.\n const template = this.templateHtml\n\n return [render, template]\n },\n onServeError: () => undefined,\n }\n }\n\n async setUpDevelopment(): Promise<Setup> {\n const { createServer } = await import(\"vite\")\n\n const vite = await createServer({\n configFile: \"/workspace/frontend/vite.config.ts\",\n server: {\n middlewareMode: true,\n hmr: { server: this.server },\n },\n appType: \"custom\",\n base: this.base,\n mode: this.mode,\n })\n\n this.app.use(vite.middlewares)\n\n return {\n getRenderAndTemplate: async path => {\n const render = (\n (await vite.ssrLoadModule(\"/src/entry-server.tsx\")) as EntryModule\n ).render\n\n // Always read fresh template.\n let template = await fs.readFile(\"./index.html\", \"utf-8\")\n template = await vite.transformIndexHtml(path, template)\n\n return [render, template]\n },\n onServeError: error => {\n vite.ssrFixStacktrace(error)\n return error.stack\n },\n }\n }\n\n async run() {\n const setup = this.envIsProduction\n ? await this.setUpProduction()\n : await this.setUpDevelopment()\n\n this.app.get(\"/health-check\", (request, response) => {\n this.handleHealthCheck(request, response)\n })\n\n this.app.get(\n \"/.well-known/appspecific/com.chrome.devtools.json\",\n (request, response) => {\n this.handleChromeDevTools(request, response)\n },\n )\n\n this.app.get(\"*\", async (request, response) => {\n await this.handleServeHtml(request, response, setup)\n })\n\n this.server.listen(this.port, this.hostname, () => {\n let startMessage =\n \"Server started.\\n\" +\n `url: http://${this.hostname}:${this.port}\\n` +\n `environment: ${process.env.NODE_ENV}\\n`\n\n if (!this.envIsProduction) startMessage += `mode: ${this.mode}\\n`\n\n console.log(startMessage)\n })\n }\n}\n"],"names":["Server","mode","port","base","express","http","Cache","randomUUID","request","response","value","healthCheck","getRenderAndTemplate","onServeError","path","render","template","rendered","html","error","body","localWorkspacePath","code","compression","sirv","fs","createServer","vite","setup","startMessage"],"mappings":"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"}
File without changes