codeforlife 2.14.6 → 2.14.8

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 (87) hide show
  1. package/dist/{Countdown-B1ilD_qY.js → Countdown-B4alF-zt.js} +2 -2
  2. package/dist/{Countdown-B1ilD_qY.js.map → Countdown-B4alF-zt.js.map} +1 -1
  3. package/dist/{Countdown-DJ5b4A3w.cjs → Countdown-B8t-gwPp.cjs} +2 -2
  4. package/dist/{Countdown-DJ5b4A3w.cjs.map → Countdown-B8t-gwPp.cjs.map} +1 -1
  5. package/dist/{LinkButton-BbGJHgCY.cjs → LinkButton-C_pRNvqs.cjs} +2 -2
  6. package/dist/{LinkButton-BbGJHgCY.cjs.map → LinkButton-C_pRNvqs.cjs.map} +1 -1
  7. package/dist/{LinkButton-BVU_MF2a.js → LinkButton-EQvTNtbi.js} +2 -2
  8. package/dist/{LinkButton-BVU_MF2a.js.map → LinkButton-EQvTNtbi.js.map} +1 -1
  9. package/dist/{Navigate-DfeA_eki.js → Navigate-CmvxpGu9.js} +2 -2
  10. package/dist/{Navigate-DfeA_eki.js.map → Navigate-CmvxpGu9.js.map} +1 -1
  11. package/dist/{Navigate-CioAG5Y-.cjs → Navigate-N_lhvJqc.cjs} +2 -2
  12. package/dist/{Navigate-CioAG5Y-.cjs.map → Navigate-N_lhvJqc.cjs.map} +1 -1
  13. package/dist/auth--UJpsJx8.cjs +2 -0
  14. package/dist/auth--UJpsJx8.cjs.map +1 -0
  15. package/dist/{auth-D-8t6wfR.js → auth-C3UdJFcP.js} +25 -25
  16. package/dist/auth-C3UdJFcP.js.map +1 -0
  17. package/dist/common-BQDBPfA-.js +23 -0
  18. package/dist/common-BQDBPfA-.js.map +1 -0
  19. package/dist/common-Cxc7W70B.cjs +2 -0
  20. package/dist/common-Cxc7W70B.cjs.map +1 -0
  21. package/dist/components/form/index.cjs.js +1 -1
  22. package/dist/components/form/index.es.js +1 -1
  23. package/dist/components/index.cjs.js +1 -1
  24. package/dist/components/index.es.js +5 -5
  25. package/dist/components/page/index.cjs.js +1 -1
  26. package/dist/components/page/index.es.js +1 -1
  27. package/dist/components/router/index.cjs.js +1 -1
  28. package/dist/components/router/index.es.js +2 -2
  29. package/dist/features/index.cjs.js +1 -1
  30. package/dist/features/index.cjs.js.map +1 -1
  31. package/dist/features/index.es.js +3 -3
  32. package/dist/hooks/index.cjs.js +1 -1
  33. package/dist/hooks/index.es.js +1 -1
  34. package/dist/{index-C8T09ieQ.cjs → index-BUG2k4XI.cjs} +2 -2
  35. package/dist/{index-C8T09ieQ.cjs.map → index-BUG2k4XI.cjs.map} +1 -1
  36. package/dist/index-BhTYGZm3.cjs +2 -0
  37. package/dist/{index-Da4T5FYK.cjs.map → index-BhTYGZm3.cjs.map} +1 -1
  38. package/dist/{index-Cxq_P-ni.js → index-CYI_rUWI.js} +3 -3
  39. package/dist/{index-Cxq_P-ni.js.map → index-CYI_rUWI.js.map} +1 -1
  40. package/dist/{index-De-EwYmr.js → index-Uk65JJpc.js} +2 -2
  41. package/dist/{index-De-EwYmr.js.map → index-Uk65JJpc.js.map} +1 -1
  42. package/dist/server/entry/client.cjs.js +2 -0
  43. package/dist/server/entry/client.cjs.js.map +1 -0
  44. package/dist/server/entry/client.d.ts +4 -0
  45. package/dist/server/entry/client.es.js +23 -0
  46. package/dist/server/entry/client.es.js.map +1 -0
  47. package/dist/server/entry/index.cjs.js +2 -0
  48. package/dist/server/entry/index.cjs.js.map +1 -0
  49. package/dist/server/entry/index.d.ts +2 -0
  50. package/dist/server/entry/index.es.js +9 -0
  51. package/dist/server/entry/index.es.js.map +1 -0
  52. package/dist/server/entry/server.cjs.js +2 -0
  53. package/dist/server/entry/server.cjs.js.map +1 -0
  54. package/dist/server/entry/server.d.ts +4 -0
  55. package/dist/server/entry/server.es.js +37 -0
  56. package/dist/server/entry/server.es.js.map +1 -0
  57. package/dist/slices/index.cjs.js +1 -1
  58. package/dist/slices/index.cjs.js.map +1 -1
  59. package/dist/slices/index.es.js +5 -5
  60. package/dist/slices/index.es.js.map +1 -1
  61. package/dist/src/server/entry/client.d.ts +2 -0
  62. package/dist/src/server/entry/common.d.ts +19 -0
  63. package/dist/src/server/entry/index.d.ts +1 -0
  64. package/dist/src/server/entry/server.d.ts +7 -0
  65. package/dist/src/utils/cookies.test.d.ts +1 -0
  66. package/dist/utils/auth.cjs.js +1 -1
  67. package/dist/utils/auth.cjs.js.map +1 -1
  68. package/dist/utils/auth.es.js +7 -7
  69. package/dist/utils/auth.es.js.map +1 -1
  70. package/dist/utils/cookies.cjs.js +2 -0
  71. package/dist/utils/cookies.cjs.js.map +1 -0
  72. package/dist/utils/cookies.d.ts +1 -0
  73. package/dist/utils/cookies.es.js +15 -0
  74. package/dist/utils/cookies.es.js.map +1 -0
  75. package/dist/utils/router.cjs.js +1 -1
  76. package/dist/utils/router.es.js +1 -1
  77. package/package.json +19 -4
  78. package/dist/auth-D-8t6wfR.js.map +0 -1
  79. package/dist/auth-uyv8Mv88.cjs +0 -2
  80. package/dist/auth-uyv8Mv88.cjs.map +0 -1
  81. package/dist/index-Da4T5FYK.cjs +0 -2
  82. package/dist/server/entry.cjs.js +0 -2
  83. package/dist/server/entry.cjs.js.map +0 -1
  84. package/dist/server/entry.d.ts +0 -2
  85. package/dist/server/entry.es.js +0 -62
  86. package/dist/server/entry.es.js.map +0 -1
  87. package/dist/src/server/entry.d.ts +0 -18
@@ -1,6 +1,6 @@
1
- import t from "js-cookie";
1
+ import t from "./cookies.es.js";
2
2
  import { getCsrfCookieName as a, getSessionCookieName as i, getSessionMetadataCookieName as c } from "./settings.es.js";
3
- import { generateSecureRandomString as g } from "./general.es.js";
3
+ import { generateSecureRandomString as s } from "./general.es.js";
4
4
  function u() {
5
5
  t.remove(i()), t.remove(c());
6
6
  }
@@ -10,7 +10,7 @@ function d() {
10
10
  function f(o, e) {
11
11
  return `oauth2.${o}.${e}`;
12
12
  }
13
- const S = ["S256"], l = [
13
+ const S = ["S256"], E = [
14
14
  43,
15
15
  44,
16
16
  45,
@@ -98,8 +98,8 @@ const S = ["S256"], l = [
98
98
  127,
99
99
  128
100
100
  ];
101
- async function E(o) {
102
- const e = g(o), r = new TextEncoder().encode(e), n = await window.crypto.subtle.digest("SHA-256", r);
101
+ async function l(o) {
102
+ const e = s(o), r = new TextEncoder().encode(e), n = await window.crypto.subtle.digest("SHA-256", r);
103
103
  return {
104
104
  verifier: e,
105
105
  challenge: btoa(String.fromCharCode(...new Uint8Array(n))).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, ""),
@@ -107,9 +107,9 @@ async function E(o) {
107
107
  };
108
108
  }
109
109
  export {
110
- l as OAUTH2_CODE_CHALLENGE_LENGTHS,
110
+ E as OAUTH2_CODE_CHALLENGE_LENGTHS,
111
111
  S as OAUTH2_CODE_CHALLENGE_METHODS,
112
- E as generateOAuth2CodeChallenge,
112
+ l as generateOAuth2CodeChallenge,
113
113
  d as getCsrfCookie,
114
114
  u as logout,
115
115
  f as makeOAuth2StorageKey
@@ -1 +1 @@
1
- {"version":3,"file":"auth.es.js","sources":["../../src/utils/auth.ts"],"sourcesContent":["import Cookies from \"js-cookie\"\n\nimport {\n getCsrfCookieName,\n getSessionCookieName,\n getSessionMetadataCookieName,\n} from \"../utils/settings\"\nimport { generateSecureRandomString } from \"./general\"\n\nexport function logout() {\n Cookies.remove(getSessionCookieName())\n Cookies.remove(getSessionMetadataCookieName())\n}\n\n// https://docs.djangoproject.com/en/3.2/ref/csrf/\nexport function getCsrfCookie() {\n return Cookies.get(getCsrfCookieName())\n}\n\nexport function makeOAuth2StorageKey(provider: string, key: string) {\n return `oauth2.${provider}.${key}`\n}\n\nexport const OAUTH2_CODE_CHALLENGE_METHODS = [\"S256\"] as const\n\nexport type OAuth2CodeChallengeMethods =\n (typeof OAUTH2_CODE_CHALLENGE_METHODS)[number]\n\nexport const OAUTH2_CODE_CHALLENGE_LENGTHS = [\n 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61,\n 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80,\n 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99,\n 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114,\n 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128,\n] as const\n\nexport type OAuth2CodeChallengeLengths =\n (typeof OAUTH2_CODE_CHALLENGE_LENGTHS)[number]\n\nexport type OAuth2RequestCodeUrlSearchParams = {\n client_id: string\n redirect_uri: string\n scope: string\n response_type: string\n access_type: string\n prompt?: string\n state: string\n code_challenge: string\n code_challenge_method: string\n}\n\nexport type OAuth2ReceiveCodeUrlSearchParams = {\n code: string\n state: string\n}\n\nexport type OAuth2CodeChallenge = {\n verifier: string\n challenge: string\n method: OAuth2CodeChallengeMethods\n}\n\nexport async function generateOAuth2CodeChallenge(\n length: OAuth2CodeChallengeLengths,\n): Promise<OAuth2CodeChallenge> {\n const verifier = generateSecureRandomString(length)\n const data = new TextEncoder().encode(verifier)\n const digest = await window.crypto.subtle.digest(\"SHA-256\", data)\n\n return {\n verifier,\n challenge: btoa(String.fromCharCode(...new Uint8Array(digest)))\n .replace(/\\+/g, \"-\")\n .replace(/\\//g, \"_\")\n .replace(/=+$/, \"\"),\n method: \"S256\",\n }\n}\n"],"names":["logout","Cookies","getSessionCookieName","getSessionMetadataCookieName","getCsrfCookie","getCsrfCookieName","makeOAuth2StorageKey","provider","key","OAUTH2_CODE_CHALLENGE_METHODS","OAUTH2_CODE_CHALLENGE_LENGTHS","generateOAuth2CodeChallenge","length","verifier","generateSecureRandomString","data","digest"],"mappings":";;;AASO,SAASA,IAAS;AACvB,EAAAC,EAAQ,OAAOC,GAAsB,GACrCD,EAAQ,OAAOE,GAA8B;AAC/C;AAGO,SAASC,IAAgB;AAC9B,SAAOH,EAAQ,IAAII,GAAmB;AACxC;AAEO,SAASC,EAAqBC,GAAkBC,GAAa;AAClE,SAAO,UAAUD,CAAQ,IAAIC,CAAG;AAClC;AAEO,MAAMC,IAAgC,CAAC,MAAM,GAKvCC,IAAgC;AAAA,EAC3C;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EACxE;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EACxE;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EACxE;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EACtE;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AACnE;AA4BA,eAAsBC,EACpBC,GAC8B;AAC9B,QAAMC,IAAWC,EAA2BF,CAAM,GAC5CG,IAAO,IAAI,cAAc,OAAOF,CAAQ,GACxCG,IAAS,MAAM,OAAO,OAAO,OAAO,OAAO,WAAWD,CAAI;AAEhE,SAAO;AAAA,IACL,UAAAF;AAAA,IACA,WAAW,KAAK,OAAO,aAAa,GAAG,IAAI,WAAWG,CAAM,CAAC,CAAC,EAC3D,QAAQ,OAAO,GAAG,EAClB,QAAQ,OAAO,GAAG,EAClB,QAAQ,OAAO,EAAE;AAAA,IACpB,QAAQ;AAAA,EAAA;AAEZ;"}
1
+ {"version":3,"file":"auth.es.js","sources":["../../src/utils/auth.ts"],"sourcesContent":["import cookies from \"../utils/cookies\"\n\nimport {\n getCsrfCookieName,\n getSessionCookieName,\n getSessionMetadataCookieName,\n} from \"../utils/settings\"\nimport { generateSecureRandomString } from \"./general\"\n\nexport function logout() {\n cookies.remove(getSessionCookieName())\n cookies.remove(getSessionMetadataCookieName())\n}\n\n// https://docs.djangoproject.com/en/3.2/ref/csrf/\nexport function getCsrfCookie() {\n return cookies.get(getCsrfCookieName()) as string | undefined\n}\n\nexport function makeOAuth2StorageKey(provider: string, key: string) {\n return `oauth2.${provider}.${key}`\n}\n\nexport const OAUTH2_CODE_CHALLENGE_METHODS = [\"S256\"] as const\n\nexport type OAuth2CodeChallengeMethods =\n (typeof OAUTH2_CODE_CHALLENGE_METHODS)[number]\n\nexport const OAUTH2_CODE_CHALLENGE_LENGTHS = [\n 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61,\n 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80,\n 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99,\n 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114,\n 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128,\n] as const\n\nexport type OAuth2CodeChallengeLengths =\n (typeof OAUTH2_CODE_CHALLENGE_LENGTHS)[number]\n\nexport type OAuth2RequestCodeUrlSearchParams = {\n client_id: string\n redirect_uri: string\n scope: string\n response_type: string\n access_type: string\n prompt?: string\n state: string\n code_challenge: string\n code_challenge_method: string\n}\n\nexport type OAuth2ReceiveCodeUrlSearchParams = {\n code: string\n state: string\n}\n\nexport type OAuth2CodeChallenge = {\n verifier: string\n challenge: string\n method: OAuth2CodeChallengeMethods\n}\n\nexport async function generateOAuth2CodeChallenge(\n length: OAuth2CodeChallengeLengths,\n): Promise<OAuth2CodeChallenge> {\n const verifier = generateSecureRandomString(length)\n const data = new TextEncoder().encode(verifier)\n const digest = await window.crypto.subtle.digest(\"SHA-256\", data)\n\n return {\n verifier,\n challenge: btoa(String.fromCharCode(...new Uint8Array(digest)))\n .replace(/\\+/g, \"-\")\n .replace(/\\//g, \"_\")\n .replace(/=+$/, \"\"),\n method: \"S256\",\n }\n}\n"],"names":["logout","cookies","getSessionCookieName","getSessionMetadataCookieName","getCsrfCookie","getCsrfCookieName","makeOAuth2StorageKey","provider","key","OAUTH2_CODE_CHALLENGE_METHODS","OAUTH2_CODE_CHALLENGE_LENGTHS","generateOAuth2CodeChallenge","length","verifier","generateSecureRandomString","data","digest"],"mappings":";;;AASO,SAASA,IAAS;AACvBC,EAAAA,EAAQ,OAAOC,GAAsB,GACrCD,EAAQ,OAAOE,GAA8B;AAC/C;AAGO,SAASC,IAAgB;AAC9B,SAAOH,EAAQ,IAAII,GAAmB;AACxC;AAEO,SAASC,EAAqBC,GAAkBC,GAAa;AAClE,SAAO,UAAUD,CAAQ,IAAIC,CAAG;AAClC;AAEO,MAAMC,IAAgC,CAAC,MAAM,GAKvCC,IAAgC;AAAA,EAC3C;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EACxE;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EACxE;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EAAI;AAAA,EACxE;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EACtE;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AACnE;AA4BA,eAAsBC,EACpBC,GAC8B;AAC9B,QAAMC,IAAWC,EAA2BF,CAAM,GAC5CG,IAAO,IAAI,cAAc,OAAOF,CAAQ,GACxCG,IAAS,MAAM,OAAO,OAAO,OAAO,OAAO,WAAWD,CAAI;AAEhE,SAAO;AAAA,IACL,UAAAF;AAAA,IACA,WAAW,KAAK,OAAO,aAAa,GAAG,IAAI,WAAWG,CAAM,CAAC,CAAC,EAC3D,QAAQ,OAAO,GAAG,EAClB,QAAQ,OAAO,GAAG,EAClB,QAAQ,OAAO,EAAE;AAAA,IACpB,QAAQ;AAAA,EAAA;AAEZ;"}
@@ -0,0 +1,2 @@
1
+ "use strict";const s=require("js-cookie"),n="j:",o=s.withConverter({write:(t,e)=>{const r=typeof t=="object"&&t!==null?n+JSON.stringify(t):String(t);return s.converter.write(r,e)},read:(t,e)=>{const r=s.converter.read(t,e);return r.startsWith(n)?JSON.parse(r.slice(n.length)):r}});module.exports=o;
2
+ //# sourceMappingURL=cookies.cjs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cookies.cjs.js","sources":["../../src/utils/cookies.ts"],"sourcesContent":["// eslint-disable-next-line @typescript-eslint/no-restricted-imports\nimport Cookies from \"js-cookie\"\n\nconst EXPRESS_JSON_PREFIX = \"j:\"\n\n/**\n * A wrapper around js-cookie that supports Express-style JSON cookies. See:\n * https://github.com/js-cookie/js-cookie/blob/main/SERVER_SIDE.md#express\n */\nconst ExpressCookies = Cookies.withConverter<any>({\n write: (value, name) => {\n const stringValue =\n typeof value === \"object\" && value !== null\n ? EXPRESS_JSON_PREFIX + JSON.stringify(value as object)\n : String(value)\n\n return Cookies.converter.write(stringValue, name)\n },\n read: (cookieValue, name) => {\n const stringValue = Cookies.converter.read(cookieValue, name)\n\n return stringValue.startsWith(EXPRESS_JSON_PREFIX)\n ? (JSON.parse(stringValue.slice(EXPRESS_JSON_PREFIX.length)) as object)\n : stringValue\n },\n})\n\nexport default ExpressCookies\n"],"names":["EXPRESS_JSON_PREFIX","ExpressCookies","Cookies","value","name","stringValue","cookieValue"],"mappings":"0CAGMA,EAAsB,KAMtBC,EAAiBC,EAAQ,cAAmB,CAChD,MAAO,CAACC,EAAOC,IAAS,CACtB,MAAMC,EACJ,OAAOF,GAAU,UAAYA,IAAU,KACnCH,EAAsB,KAAK,UAAUG,CAAe,EACpD,OAAOA,CAAK,EAElB,OAAOD,EAAQ,UAAU,MAAMG,EAAaD,CAAI,CAClD,EACA,KAAM,CAACE,EAAaF,IAAS,CAC3B,MAAMC,EAAcH,EAAQ,UAAU,KAAKI,EAAaF,CAAI,EAE5D,OAAOC,EAAY,WAAWL,CAAmB,EAC5C,KAAK,MAAMK,EAAY,MAAML,EAAoB,MAAM,CAAC,EACzDK,CACN,CACF,CAAC"}
@@ -0,0 +1 @@
1
+ export {}
@@ -0,0 +1,15 @@
1
+ import o from "js-cookie";
2
+ const s = "j:", i = o.withConverter({
3
+ write: (t, e) => {
4
+ const r = typeof t == "object" && t !== null ? s + JSON.stringify(t) : String(t);
5
+ return o.converter.write(r, e);
6
+ },
7
+ read: (t, e) => {
8
+ const r = o.converter.read(t, e);
9
+ return r.startsWith(s) ? JSON.parse(r.slice(s.length)) : r;
10
+ }
11
+ });
12
+ export {
13
+ i as default
14
+ };
15
+ //# sourceMappingURL=cookies.es.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cookies.es.js","sources":["../../src/utils/cookies.ts"],"sourcesContent":["// eslint-disable-next-line @typescript-eslint/no-restricted-imports\nimport Cookies from \"js-cookie\"\n\nconst EXPRESS_JSON_PREFIX = \"j:\"\n\n/**\n * A wrapper around js-cookie that supports Express-style JSON cookies. See:\n * https://github.com/js-cookie/js-cookie/blob/main/SERVER_SIDE.md#express\n */\nconst ExpressCookies = Cookies.withConverter<any>({\n write: (value, name) => {\n const stringValue =\n typeof value === \"object\" && value !== null\n ? EXPRESS_JSON_PREFIX + JSON.stringify(value as object)\n : String(value)\n\n return Cookies.converter.write(stringValue, name)\n },\n read: (cookieValue, name) => {\n const stringValue = Cookies.converter.read(cookieValue, name)\n\n return stringValue.startsWith(EXPRESS_JSON_PREFIX)\n ? (JSON.parse(stringValue.slice(EXPRESS_JSON_PREFIX.length)) as object)\n : stringValue\n },\n})\n\nexport default ExpressCookies\n"],"names":["EXPRESS_JSON_PREFIX","ExpressCookies","Cookies","value","name","stringValue","cookieValue"],"mappings":";AAGA,MAAMA,IAAsB,MAMtBC,IAAiBC,EAAQ,cAAmB;AAAA,EAChD,OAAO,CAACC,GAAOC,MAAS;AACtB,UAAMC,IACJ,OAAOF,KAAU,YAAYA,MAAU,OACnCH,IAAsB,KAAK,UAAUG,CAAe,IACpD,OAAOA,CAAK;AAElB,WAAOD,EAAQ,UAAU,MAAMG,GAAaD,CAAI;AAAA,EAClD;AAAA,EACA,MAAM,CAACE,GAAaF,MAAS;AAC3B,UAAMC,IAAcH,EAAQ,UAAU,KAAKI,GAAaF,CAAI;AAE5D,WAAOC,EAAY,WAAWL,CAAmB,IAC5C,KAAK,MAAMK,EAAY,MAAML,EAAoB,MAAM,CAAC,IACzDK;AAAA,EACN;AACF,CAAC;"}
@@ -1,2 +1,2 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const l=require("react-router");require("react/jsx-runtime");require("react");require("@mui/icons-material");require("@mui/material");require("../palette-BnIdHKDE.cjs");require("../auth-uyv8Mv88.cjs");function q(e,o={}){function c(r,g,t){typeof r.__=="object"&&(t=t?{...t,...r.__}:r.__);const _=typeof e=="string"&&t?l.generatePath(e,t):e;Object.entries(r).forEach(([u,i])=>{if(u!=="__")if(i=i,typeof i=="string"){if(typeof _=="string"&&(!g||u!=="_")){let n=_+i;n.endsWith("/")&&(n=n.slice(0,-1)),r[u]=n}}else c(i,!1,t)})}const f={...o,_:typeof e=="string"?e:"",__:e};return e===""?f._="/":c(f,!0),f}function s(e,o){return e.__[o]}exports.getParam=s;exports.path=q;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const l=require("react-router");require("react/jsx-runtime");require("react");require("@mui/icons-material");require("@mui/material");require("../palette-BnIdHKDE.cjs");require("../auth--UJpsJx8.cjs");function q(e,o={}){function c(r,g,t){typeof r.__=="object"&&(t=t?{...t,...r.__}:r.__);const _=typeof e=="string"&&t?l.generatePath(e,t):e;Object.entries(r).forEach(([u,i])=>{if(u!=="__")if(i=i,typeof i=="string"){if(typeof _=="string"&&(!g||u!=="_")){let n=_+i;n.endsWith("/")&&(n=n.slice(0,-1)),r[u]=n}}else c(i,!1,t)})}const f={...o,_:typeof e=="string"?e:"",__:e};return e===""?f._="/":c(f,!0),f}function s(e,o){return e.__[o]}exports.getParam=s;exports.path=q;
2
2
  //# sourceMappingURL=router.cjs.js.map
@@ -4,7 +4,7 @@ import "react";
4
4
  import "@mui/icons-material";
5
5
  import "@mui/material";
6
6
  import "../palette-CYwuLBW7.js";
7
- import "../auth-D-8t6wfR.js";
7
+ import "../auth-C3UdJFcP.js";
8
8
  function x(t, n = {}) {
9
9
  function c(i, l, e) {
10
10
  typeof i.__ == "object" && (e = e ? { ...e, ...i.__ } : i.__);
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.14.6",
5
+ "version": "2.14.8",
6
6
  "type": "module",
7
7
  "types": "dist/index.d.ts",
8
8
  "module": "dist/index.es.js",
@@ -79,9 +79,19 @@
79
79
  "require": "./dist/server/DefaultRoutes.cjs.js"
80
80
  },
81
81
  "./server/entry": {
82
- "types": "./dist/server/entry.d.ts",
83
- "import": "./dist/server/entry.es.js",
84
- "require": "./dist/server/entry.cjs.js"
82
+ "types": "./dist/server/entry/index.d.ts",
83
+ "import": "./dist/server/entry/index.es.js",
84
+ "require": "./dist/server/entry/index.cjs.js"
85
+ },
86
+ "./server/entry/client": {
87
+ "types": "./dist/server/entry/client.d.ts",
88
+ "import": "./dist/server/entry/client.es.js",
89
+ "require": "./dist/server/entry/client.cjs.js"
90
+ },
91
+ "./server/entry/server": {
92
+ "types": "./dist/server/entry/server.d.ts",
93
+ "import": "./dist/server/entry/server.es.js",
94
+ "require": "./dist/server/entry/server.cjs.js"
85
95
  },
86
96
  "./slices": {
87
97
  "types": "./dist/slices/index.d.ts",
@@ -108,6 +118,11 @@
108
118
  "import": "./dist/utils/auth.es.js",
109
119
  "require": "./dist/utils/auth.cjs.js"
110
120
  },
121
+ "./utils/cookies": {
122
+ "types": "./dist/utils/cookies.d.ts",
123
+ "import": "./dist/utils/cookies.es.js",
124
+ "require": "./dist/utils/cookies.cjs.js"
125
+ },
111
126
  "./utils/form": {
112
127
  "types": "./dist/utils/form.d.ts",
113
128
  "import": "./dist/utils/form.es.js",
@@ -1 +0,0 @@
1
- {"version":3,"file":"auth-D-8t6wfR.js","sources":["../src/hooks/router.tsx","../src/hooks/auth.tsx"],"sourcesContent":["import {\n type Location,\n type Params,\n type To,\n type NavigateOptions as _NavigateOptions,\n useLocation as _useLocation,\n useNavigate as _useNavigate,\n useParams as _useParams,\n useSearchParams as _useSearchParams,\n} from \"react-router\"\nimport { type ObjectShape, object as objectSchema } from \"yup\"\nimport { type ReactNode, useEffect } from \"react\"\n\nimport {\n type ObjectSchemaFromShape,\n type TryValidateSyncOnErrorRT,\n type TryValidateSyncOptions,\n type TryValidateSyncRT,\n tryValidateSync,\n} from \"../utils/schema\"\nimport { type PageState } from \"../components/page\"\nimport { type ReadOnly } from \"../utils/router\"\n\nexport type NavigateOptions<\n State extends Record<string, any> = Record<string, any>,\n> = Omit<_NavigateOptions, \"state\"> & {\n state?: State & Partial<PageState>\n next?: boolean\n}\n\nexport type Navigate = {\n <State extends Record<string, any> = Record<string, any>>(\n to: To,\n options?: NavigateOptions<State>,\n ): void\n (delta: number): void\n}\n\nexport function useNavigate(): Navigate {\n const navigate = _useNavigate()\n const searchParams = useSearchParams()\n\n return (\n toOrDelta: To | number,\n options: (NavigateOptions & { next?: boolean }) | undefined = undefined,\n ) => {\n if (typeof toOrDelta === \"number\") void navigate(toOrDelta)\n else {\n const { next = true, ..._options } = options || {}\n\n void navigate(\n next && \"next\" in searchParams ? searchParams.next : toOrDelta,\n _options,\n )\n }\n }\n}\n\nexport function useLocation<State = {}>() {\n return _useLocation() as Location<null | Partial<PageState & State>>\n}\n\n// -----------------------------------------------------------------------------\n// Use Search Params\n// -----------------------------------------------------------------------------\n\nexport function useSearchParams(): { [k: string]: string }\n\nexport function useSearchParams<\n OnErrorRT extends TryValidateSyncOnErrorRT<ObjectSchemaFromShape<Shape>>,\n Shape extends ObjectShape = {},\n>(\n shape: Shape,\n validateOptions?: TryValidateSyncOptions<\n ObjectSchemaFromShape<Shape>,\n OnErrorRT\n >,\n): TryValidateSyncRT<ObjectSchemaFromShape<Shape>, OnErrorRT>\n\nexport function useSearchParams<\n OnErrorRT extends TryValidateSyncOnErrorRT<ObjectSchemaFromShape<Shape>>,\n Shape extends ObjectShape = {},\n>(\n shape?: Shape,\n validateOptions?: TryValidateSyncOptions<\n ObjectSchemaFromShape<Shape>,\n OnErrorRT\n >,\n) {\n const searchParams = Object.fromEntries(_useSearchParams()[0].entries())\n if (!shape) return searchParams\n\n return tryValidateSync(searchParams, objectSchema(shape), validateOptions)\n}\n\n// -----------------------------------------------------------------------------\n// Use Params\n// -----------------------------------------------------------------------------\n\nexport function useParams(): ReadOnly<Params<string>>\n\nexport function useParams<\n OnErrorRT extends TryValidateSyncOnErrorRT<ObjectSchemaFromShape<Shape>>,\n Shape extends ObjectShape = {},\n>(\n shape: Shape,\n validateOptions?: TryValidateSyncOptions<\n ObjectSchemaFromShape<Shape>,\n OnErrorRT\n >,\n): TryValidateSyncRT<ObjectSchemaFromShape<Shape>, OnErrorRT>\n\nexport function useParams<\n OnErrorRT extends TryValidateSyncOnErrorRT<ObjectSchemaFromShape<Shape>>,\n Shape extends ObjectShape = {},\n>(\n shape?: Shape,\n validateOptions?: TryValidateSyncOptions<\n ObjectSchemaFromShape<Shape>,\n OnErrorRT\n >,\n) {\n const params = _useParams()\n if (!shape) return params\n\n return tryValidateSync(params, objectSchema(shape), validateOptions)\n}\n\nexport function useParamsRequired<\n OnErrorRT extends TryValidateSyncOnErrorRT<ObjectSchemaFromShape<Shape>>,\n Shape extends ObjectShape = {},\n>({\n shape,\n children,\n onValidationError,\n onValidationSuccess = () => {},\n validateOptions,\n}: {\n shape: Shape\n children: (\n data: NonNullable<\n TryValidateSyncRT<ObjectSchemaFromShape<Shape>, OnErrorRT>\n >,\n ) => ReactNode\n onValidationError: (navigate: Navigate) => void\n onValidationSuccess?: (\n params: NonNullable<\n TryValidateSyncRT<ObjectSchemaFromShape<Shape>, OnErrorRT>\n >,\n ) => void\n validateOptions?: TryValidateSyncOptions<\n ObjectSchemaFromShape<Shape>,\n OnErrorRT\n >\n}) {\n const params = useParams(shape, validateOptions)\n const navigate = useNavigate()\n\n useEffect(\n () => {\n if (params) onValidationSuccess(params)\n else onValidationError(navigate)\n },\n [], // eslint-disable-line react-hooks/exhaustive-deps\n )\n\n return params ? children(params) : <></>\n}\n","import * as yup from \"yup\"\nimport { type ReactNode, useCallback, useEffect, useState } from \"react\"\nimport Cookies from \"js-cookie\"\nimport type { TypedUseMutation } from \"@reduxjs/toolkit/query/react\"\nimport { createSearchParams } from \"react-router\"\n// eslint-disable-next-line @typescript-eslint/no-restricted-imports\nimport { useSelector } from \"react-redux\"\n\nimport { type AuthFactor, type User } from \"../api\"\nimport {\n type OAuth2CodeChallenge,\n type OAuth2CodeChallengeLengths,\n type OAuth2ReceiveCodeUrlSearchParams,\n type OAuth2RequestCodeUrlSearchParams,\n generateOAuth2CodeChallenge,\n makeOAuth2StorageKey,\n} from \"../utils/auth\"\nimport { useLocation, useNavigate, useSearchParams } from \"./router\"\nimport { type ExchangeOAuth2CodeArg } from \"../api/endpoints/session\"\nimport { generateSecureRandomString } from \"../utils/general\"\nimport { getSessionMetadataCookieName } from \"../utils/settings\"\n\n// -----------------------------------------------------------------------------\n// Session\n// -----------------------------------------------------------------------------\n\nexport type SelectIsLoggedIn = (state: any) => boolean\n\nexport interface SessionMetadata {\n user_id: User[\"id\"]\n user_type: \"teacher\" | \"student\" | \"indy\"\n auth_factors: Array<AuthFactor[\"type\"]>\n otp_bypass_token_exists: boolean\n}\n\nexport function useSessionMetadata<T = SessionMetadata>(\n selectIsLoggedIn: SelectIsLoggedIn,\n): T | undefined {\n return useSelector(selectIsLoggedIn)\n ? (JSON.parse(Cookies.get(getSessionMetadataCookieName())!) as T)\n : undefined\n}\n\n/**\n * A utility function to predefine a useSessionMetadata hook.\n * @param cookieName The name of the session metadata cookie.\n * @returns An object containing the session metadata.\n */\nuseSessionMetadata.predefine = <SessionMetadata,>(\n selectIsLoggedIn: SelectIsLoggedIn,\n) => {\n return () => useSessionMetadata<SessionMetadata>(selectIsLoggedIn)\n}\n\nexport type UseSessionChildrenFunction<Required extends boolean> = (\n metadata: Required extends true\n ? SessionMetadata\n : SessionMetadata | undefined,\n) => ReactNode\n\nexport type UseSessionChildren<\n UserType extends SessionMetadata[\"user_type\"] | undefined,\n> =\n | ReactNode\n | (UserType extends undefined\n ? UseSessionChildrenFunction<false>\n : UseSessionChildrenFunction<true>)\n\nexport type UseSessionOptions<\n UserType extends SessionMetadata[\"user_type\"] | undefined,\n> = Partial<{\n userType: UserType\n next: boolean\n}>\n\nexport function useSession<\n UserType extends SessionMetadata[\"user_type\"] | undefined = undefined,\n>(\n selectIsLoggedIn: SelectIsLoggedIn,\n children: UseSessionChildren<UserType>,\n options: UseSessionOptions<UserType> = {},\n) {\n const { userType, next = true } = options\n\n const { pathname } = useLocation()\n const navigate = useNavigate()\n const sessionMetadata = useSessionMetadata(selectIsLoggedIn)\n\n const loginRequired =\n userType && (!sessionMetadata || sessionMetadata.user_type !== userType)\n\n useEffect(() => {\n if (loginRequired) {\n navigate({\n pathname:\n \"/login\" +\n {\n teacher: \"/teacher\",\n student: \"/student\",\n indy: \"/independent\",\n }[userType],\n search: next\n ? createSearchParams({ next: pathname }).toString()\n : undefined,\n })\n }\n }, [navigate, loginRequired, userType, next, pathname])\n\n if (loginRequired) return <></>\n\n if (typeof children === \"function\") {\n return sessionMetadata\n ? (children as UseSessionChildrenFunction<true>)(sessionMetadata)\n : (children as UseSessionChildrenFunction<false>)(sessionMetadata)\n }\n\n return children\n}\n\n// -----------------------------------------------------------------------------\n// OAuth2\n// -----------------------------------------------------------------------------\n\nexport function useOAuth2State(\n provider: string,\n length: number = 32,\n storageKey: string = \"state\",\n): [string | undefined, () => void] {\n const oAuth2StorageKey = makeOAuth2StorageKey(provider, storageKey)\n const storageValue = sessionStorage.getItem(oAuth2StorageKey)\n\n const [_state, _setState] = useState<string>()\n\n useEffect(() => {\n let state: string\n if (storageValue && storageValue.length === length) {\n state = storageValue\n } else {\n state = generateSecureRandomString(length)\n sessionStorage.setItem(oAuth2StorageKey, state)\n }\n\n _setState(state)\n }, [oAuth2StorageKey, storageValue, length])\n\n const resetState = useCallback(() => {\n sessionStorage.removeItem(oAuth2StorageKey)\n _setState(undefined)\n }, [oAuth2StorageKey])\n\n return [_state, resetState]\n}\n\nexport function useOAuth2CodeChallenge(\n provider: string,\n length: OAuth2CodeChallengeLengths = 128,\n storageKey: string = \"codeChallenge\",\n): [OAuth2CodeChallenge | undefined, () => void] {\n const oAuth2StorageKey = makeOAuth2StorageKey(provider, storageKey)\n const storageValue = sessionStorage.getItem(oAuth2StorageKey)\n\n const [_codeChallenge, _setCodeChallenge] = useState<OAuth2CodeChallenge>()\n\n useEffect(() => {\n let codeChallenge: OAuth2CodeChallenge | undefined\n if (storageValue) {\n const storageJsonValue: unknown = JSON.parse(storageValue)\n if (\n typeof storageJsonValue === \"object\" &&\n storageJsonValue &&\n \"verifier\" in storageJsonValue &&\n typeof storageJsonValue.verifier == \"string\" &&\n storageJsonValue.verifier.length === length &&\n \"challenge\" in storageJsonValue &&\n typeof storageJsonValue.challenge === \"string\" &&\n \"method\" in storageJsonValue &&\n storageJsonValue.method === \"S256\"\n ) {\n codeChallenge = {\n verifier: storageJsonValue.verifier,\n challenge: storageJsonValue.challenge,\n method: storageJsonValue.method,\n }\n }\n }\n\n if (codeChallenge) _setCodeChallenge(codeChallenge)\n else {\n generateOAuth2CodeChallenge(length)\n .then(codeChallenge => {\n sessionStorage.setItem(\n oAuth2StorageKey,\n JSON.stringify(codeChallenge),\n )\n\n _setCodeChallenge(codeChallenge)\n })\n .catch(error => {\n if (error) console.error(error)\n })\n }\n }, [oAuth2StorageKey, storageValue, length])\n\n const resetCodeChallenge = useCallback(() => {\n sessionStorage.removeItem(oAuth2StorageKey)\n _setCodeChallenge(undefined)\n }, [oAuth2StorageKey])\n\n return [_codeChallenge, resetCodeChallenge]\n}\n\ninterface BaseUseOAuth2KwArgs<SessionMetadata> {\n provider: string\n authUri: string\n clientId: string\n redirectUri: string\n scope: string\n responseType?: \"code\"\n accessType?: \"offline\"\n prompt?: string\n useLoginMutation: TypedUseMutation<\n SessionMetadata,\n ExchangeOAuth2CodeArg,\n any\n >\n onCreateSession: (result: SessionMetadata) => void\n onRetrieveSession: (metadata: SessionMetadata) => void\n}\n\ninterface UseOAuth2KwArgs<SessionMetadata>\n extends BaseUseOAuth2KwArgs<SessionMetadata> {\n useSessionMetadata: () => SessionMetadata | undefined\n}\n\nexport type OAuth2 = [string, OAuth2RequestCodeUrlSearchParams] | []\n\n// https://datatracker.ietf.org/doc/html/rfc7636\nfunction useOAuth2Internal<SessionMetadata>({\n provider,\n authUri,\n clientId,\n redirectUri,\n scope,\n responseType = \"code\",\n accessType = \"offline\",\n prompt,\n useSessionMetadata,\n useLoginMutation,\n onCreateSession,\n onRetrieveSession,\n}: UseOAuth2KwArgs<SessionMetadata>): OAuth2 {\n const [state, resetState] = useOAuth2State(provider)\n const [\n {\n verifier: codeVerifier,\n challenge: codeChallenge,\n method: codeChallengeMethod,\n } = {},\n resetCodeChallenge,\n ] = useOAuth2CodeChallenge(provider)\n const [\n login,\n {\n originalArgs: loginArgs = {} as ExchangeOAuth2CodeArg,\n isLoading: loginIsLoading,\n isError: loginIsError,\n },\n ] = useLoginMutation()\n const sessionMetadata = useSessionMetadata()\n const navigate = useNavigate()\n const searchParams =\n useSearchParams({ code: yup.string(), state: yup.string() }) || {}\n const location = useLocation<OAuth2ReceiveCodeUrlSearchParams>()\n\n const locationState = location.state || {}\n\n useEffect(() => {\n // If the the auth provider has redirected back to our site with the\n // expected search params, we redirect to the current page to remove them.\n if (searchParams.code && searchParams.state) {\n navigate<OAuth2ReceiveCodeUrlSearchParams>(\".\", {\n // Removes the URL containing the search params from the history stack.\n replace: true,\n // Ensure we don't break the auth flow by navigating to another page.\n next: false,\n // Store the search params in the page's state instead.\n state: { code: searchParams.code, state: searchParams.state },\n })\n }\n }, [searchParams.code, searchParams.state, navigate])\n\n useEffect(() => {\n // If we're already logged in, no need to log in again.\n if (sessionMetadata) onRetrieveSession(sessionMetadata)\n else if (\n // If the state and code verifier have been generated...\n state &&\n codeVerifier &&\n // ...and the page's state contains a code...\n locationState.code &&\n // ...and the page's state contains the stored state...\n locationState.state === state &&\n // ...and the login endpoint was not called with the current values or has\n // not returned an error...\n (loginArgs.code !== locationState.code ||\n loginArgs.code_verifier !== codeVerifier ||\n loginArgs.redirect_uri !== redirectUri ||\n !loginIsError) &&\n // ...and the login endpoint is not currently being called...\n !loginIsLoading\n ) {\n // ...call the login endpoint.\n login({\n code: locationState.code,\n code_verifier: codeVerifier,\n redirect_uri: redirectUri,\n })\n .unwrap()\n .then(onCreateSession)\n .catch(() => {\n navigate(\".\", {\n replace: true,\n state: {\n notifications: [\n {\n props: {\n error: true,\n children: \"Failed to login. Please try again.\",\n },\n },\n ],\n },\n })\n })\n .finally(() => {\n resetState()\n resetCodeChallenge()\n })\n }\n }, [\n navigate,\n redirectUri,\n // State\n state,\n locationState.state,\n resetState,\n // Code\n codeVerifier,\n locationState.code,\n resetCodeChallenge,\n // Login\n login,\n loginIsLoading,\n loginIsError,\n loginArgs.code,\n loginArgs.code_verifier,\n loginArgs.redirect_uri,\n // Session\n sessionMetadata,\n onCreateSession,\n onRetrieveSession,\n ])\n\n if (state && codeChallenge && codeChallengeMethod) {\n const urlSearchParams: OAuth2RequestCodeUrlSearchParams = {\n client_id: clientId,\n redirect_uri: redirectUri,\n scope,\n response_type: responseType,\n access_type: accessType,\n state,\n code_challenge: codeChallenge,\n code_challenge_method: codeChallengeMethod,\n }\n\n if (prompt) urlSearchParams[\"prompt\"] = prompt\n\n return [\n authUri + \"?\" + new URLSearchParams(urlSearchParams).toString(),\n urlSearchParams,\n ]\n }\n\n return []\n}\n\nexport const useOAuth2: {\n <SessionMetadata>(kwargs: UseOAuth2KwArgs<SessionMetadata>): OAuth2\n (kwargs: BaseUseOAuth2KwArgs<SessionMetadata>): OAuth2\n} = <_SessionMetadata,>(\n kwargs:\n | UseOAuth2KwArgs<_SessionMetadata>\n | BaseUseOAuth2KwArgs<SessionMetadata>,\n): OAuth2 => {\n return useOAuth2Internal(\n // @ts-expect-error value is assignable\n \"useSessionMetadata\" in kwargs ? kwargs : { ...kwargs, useSessionMetadata },\n )\n}\n"],"names":["useNavigate","navigate","_useNavigate","searchParams","useSearchParams","toOrDelta","options","next","_options","useLocation","_useLocation","shape","validateOptions","_useSearchParams","tryValidateSync","objectSchema","useParams","params","_useParams","useParamsRequired","children","onValidationError","onValidationSuccess","useEffect","jsx","Fragment","useSessionMetadata","selectIsLoggedIn","useSelector","Cookies","getSessionMetadataCookieName","useSession","userType","pathname","sessionMetadata","loginRequired","createSearchParams","useOAuth2State","provider","length","storageKey","oAuth2StorageKey","makeOAuth2StorageKey","storageValue","_state","_setState","useState","state","generateSecureRandomString","resetState","useCallback","useOAuth2CodeChallenge","_codeChallenge","_setCodeChallenge","codeChallenge","storageJsonValue","generateOAuth2CodeChallenge","error","resetCodeChallenge","useOAuth2Internal","authUri","clientId","redirectUri","scope","responseType","accessType","prompt","useLoginMutation","onCreateSession","onRetrieveSession","codeVerifier","codeChallengeMethod","login","loginArgs","loginIsLoading","loginIsError","yup","locationState","urlSearchParams","useOAuth2","kwargs"],"mappings":"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"}
@@ -1,2 +0,0 @@
1
- "use strict";const _=require("react/jsx-runtime"),P=require("yup"),l=require("react"),w=require("js-cookie"),S=require("react-router"),z=require("react-redux");require("@reduxjs/toolkit/query/react");require("@reduxjs/toolkit");const O=require("./utils/auth.cjs.js");require("@mui/material");const B=require("./utils/general.cjs.js");require("@mui/icons-material");require("./schemas-hIW9-H6-.cjs");require("./urls-2gheISSO.cjs");const J=require("./utils/schema.cjs.js");require("./palette-BnIdHKDE.cjs");const D=require("./utils/settings.cjs.js");function G(e){const s=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(e){for(const r in e)if(r!=="default"){const t=Object.getOwnPropertyDescriptor(e,r);Object.defineProperty(s,r,t.get?t:{enumerable:!0,get:()=>e[r]})}}return s.default=e,Object.freeze(s)}const k=G(P);function v(){const e=S.useNavigate(),s=b();return(r,t=void 0)=>{if(typeof r=="number")e(r);else{const{next:a=!0,...o}=t||{};e(a&&"next"in s?s.next:r,o)}}}function A(){return S.useLocation()}function b(e,s){const r=Object.fromEntries(S.useSearchParams()[0].entries());return e?J.tryValidateSync(r,P.object(e),s):r}function K(e,s){const r=S.useParams();return e?J.tryValidateSync(r,P.object(e),s):r}function H({shape:e,children:s,onValidationError:r,onValidationSuccess:t=()=>{},validateOptions:a}){const o=K(e,a),c=v();return l.useEffect(()=>{o?t(o):r(c)},[]),o?s(o):_.jsx(_.Fragment,{})}function m(e){return z.useSelector(e)?JSON.parse(w.get(D.getSessionMetadataCookieName())):void 0}m.predefine=e=>()=>m(e);function Q(e,s,r={}){const{userType:t,next:a=!0}=r,{pathname:o}=A(),c=v(),u=m(e),i=t&&(!u||u.user_type!==t);return l.useEffect(()=>{i&&c({pathname:"/login"+{teacher:"/teacher",student:"/student",indy:"/independent"}[t],search:a?S.createSearchParams({next:o}).toString():void 0})},[c,i,t,a,o]),i?_.jsx(_.Fragment,{}):typeof s=="function"?s(u):s}function F(e,s=32,r="state"){const t=O.makeOAuth2StorageKey(e,r),a=sessionStorage.getItem(t),[o,c]=l.useState();l.useEffect(()=>{let i;a&&a.length===s?i=a:(i=B.generateSecureRandomString(s),sessionStorage.setItem(t,i)),c(i)},[t,a,s]);const u=l.useCallback(()=>{sessionStorage.removeItem(t),c(void 0)},[t]);return[o,u]}function T(e,s=128,r="codeChallenge"){const t=O.makeOAuth2StorageKey(e,r),a=sessionStorage.getItem(t),[o,c]=l.useState();l.useEffect(()=>{let i;if(a){const n=JSON.parse(a);typeof n=="object"&&n&&"verifier"in n&&typeof n.verifier=="string"&&n.verifier.length===s&&"challenge"in n&&typeof n.challenge=="string"&&"method"in n&&n.method==="S256"&&(i={verifier:n.verifier,challenge:n.challenge,method:n.method})}i?c(i):O.generateOAuth2CodeChallenge(s).then(n=>{sessionStorage.setItem(t,JSON.stringify(n)),c(n)}).catch(n=>{n&&console.error(n)})},[t,a,s]);const u=l.useCallback(()=>{sessionStorage.removeItem(t),c(void 0)},[t]);return[o,u]}function W({provider:e,authUri:s,clientId:r,redirectUri:t,scope:a,responseType:o="code",accessType:c="offline",prompt:u,useSessionMetadata:i,useLoginMutation:n,onCreateSession:j,onRetrieveSession:x}){const[h,E]=F(e),[{verifier:p,challenge:I,method:M}={},N]=T(e),[R,{originalArgs:f={},isLoading:L,isError:V}]=n(),q=i(),y=v(),d=b({code:k.string(),state:k.string()})||{},g=A().state||{};if(l.useEffect(()=>{d.code&&d.state&&y(".",{replace:!0,next:!1,state:{code:d.code,state:d.state}})},[d.code,d.state,y]),l.useEffect(()=>{q?x(q):h&&p&&g.code&&g.state===h&&(f.code!==g.code||f.code_verifier!==p||f.redirect_uri!==t||!V)&&!L&&R({code:g.code,code_verifier:p,redirect_uri:t}).unwrap().then(j).catch(()=>{y(".",{replace:!0,state:{notifications:[{props:{error:!0,children:"Failed to login. Please try again."}}]}})}).finally(()=>{E(),N()})},[y,t,h,g.state,E,p,g.code,N,R,L,V,f.code,f.code_verifier,f.redirect_uri,q,j,x]),h&&I&&M){const C={client_id:r,redirect_uri:t,scope:a,response_type:o,access_type:c,state:h,code_challenge:I,code_challenge_method:M};return u&&(C.prompt=u),[s+"?"+new URLSearchParams(C).toString(),C]}return[]}const X=e=>W("useSessionMetadata"in e?e:{...e,useSessionMetadata:m});exports.useLocation=A;exports.useNavigate=v;exports.useOAuth2=X;exports.useOAuth2CodeChallenge=T;exports.useOAuth2State=F;exports.useParams=K;exports.useParamsRequired=H;exports.useSearchParams=b;exports.useSession=Q;exports.useSessionMetadata=m;
2
- //# sourceMappingURL=auth-uyv8Mv88.cjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"auth-uyv8Mv88.cjs","sources":["../src/hooks/router.tsx","../src/hooks/auth.tsx"],"sourcesContent":["import {\n type Location,\n type Params,\n type To,\n type NavigateOptions as _NavigateOptions,\n useLocation as _useLocation,\n useNavigate as _useNavigate,\n useParams as _useParams,\n useSearchParams as _useSearchParams,\n} from \"react-router\"\nimport { type ObjectShape, object as objectSchema } from \"yup\"\nimport { type ReactNode, useEffect } from \"react\"\n\nimport {\n type ObjectSchemaFromShape,\n type TryValidateSyncOnErrorRT,\n type TryValidateSyncOptions,\n type TryValidateSyncRT,\n tryValidateSync,\n} from \"../utils/schema\"\nimport { type PageState } from \"../components/page\"\nimport { type ReadOnly } from \"../utils/router\"\n\nexport type NavigateOptions<\n State extends Record<string, any> = Record<string, any>,\n> = Omit<_NavigateOptions, \"state\"> & {\n state?: State & Partial<PageState>\n next?: boolean\n}\n\nexport type Navigate = {\n <State extends Record<string, any> = Record<string, any>>(\n to: To,\n options?: NavigateOptions<State>,\n ): void\n (delta: number): void\n}\n\nexport function useNavigate(): Navigate {\n const navigate = _useNavigate()\n const searchParams = useSearchParams()\n\n return (\n toOrDelta: To | number,\n options: (NavigateOptions & { next?: boolean }) | undefined = undefined,\n ) => {\n if (typeof toOrDelta === \"number\") void navigate(toOrDelta)\n else {\n const { next = true, ..._options } = options || {}\n\n void navigate(\n next && \"next\" in searchParams ? searchParams.next : toOrDelta,\n _options,\n )\n }\n }\n}\n\nexport function useLocation<State = {}>() {\n return _useLocation() as Location<null | Partial<PageState & State>>\n}\n\n// -----------------------------------------------------------------------------\n// Use Search Params\n// -----------------------------------------------------------------------------\n\nexport function useSearchParams(): { [k: string]: string }\n\nexport function useSearchParams<\n OnErrorRT extends TryValidateSyncOnErrorRT<ObjectSchemaFromShape<Shape>>,\n Shape extends ObjectShape = {},\n>(\n shape: Shape,\n validateOptions?: TryValidateSyncOptions<\n ObjectSchemaFromShape<Shape>,\n OnErrorRT\n >,\n): TryValidateSyncRT<ObjectSchemaFromShape<Shape>, OnErrorRT>\n\nexport function useSearchParams<\n OnErrorRT extends TryValidateSyncOnErrorRT<ObjectSchemaFromShape<Shape>>,\n Shape extends ObjectShape = {},\n>(\n shape?: Shape,\n validateOptions?: TryValidateSyncOptions<\n ObjectSchemaFromShape<Shape>,\n OnErrorRT\n >,\n) {\n const searchParams = Object.fromEntries(_useSearchParams()[0].entries())\n if (!shape) return searchParams\n\n return tryValidateSync(searchParams, objectSchema(shape), validateOptions)\n}\n\n// -----------------------------------------------------------------------------\n// Use Params\n// -----------------------------------------------------------------------------\n\nexport function useParams(): ReadOnly<Params<string>>\n\nexport function useParams<\n OnErrorRT extends TryValidateSyncOnErrorRT<ObjectSchemaFromShape<Shape>>,\n Shape extends ObjectShape = {},\n>(\n shape: Shape,\n validateOptions?: TryValidateSyncOptions<\n ObjectSchemaFromShape<Shape>,\n OnErrorRT\n >,\n): TryValidateSyncRT<ObjectSchemaFromShape<Shape>, OnErrorRT>\n\nexport function useParams<\n OnErrorRT extends TryValidateSyncOnErrorRT<ObjectSchemaFromShape<Shape>>,\n Shape extends ObjectShape = {},\n>(\n shape?: Shape,\n validateOptions?: TryValidateSyncOptions<\n ObjectSchemaFromShape<Shape>,\n OnErrorRT\n >,\n) {\n const params = _useParams()\n if (!shape) return params\n\n return tryValidateSync(params, objectSchema(shape), validateOptions)\n}\n\nexport function useParamsRequired<\n OnErrorRT extends TryValidateSyncOnErrorRT<ObjectSchemaFromShape<Shape>>,\n Shape extends ObjectShape = {},\n>({\n shape,\n children,\n onValidationError,\n onValidationSuccess = () => {},\n validateOptions,\n}: {\n shape: Shape\n children: (\n data: NonNullable<\n TryValidateSyncRT<ObjectSchemaFromShape<Shape>, OnErrorRT>\n >,\n ) => ReactNode\n onValidationError: (navigate: Navigate) => void\n onValidationSuccess?: (\n params: NonNullable<\n TryValidateSyncRT<ObjectSchemaFromShape<Shape>, OnErrorRT>\n >,\n ) => void\n validateOptions?: TryValidateSyncOptions<\n ObjectSchemaFromShape<Shape>,\n OnErrorRT\n >\n}) {\n const params = useParams(shape, validateOptions)\n const navigate = useNavigate()\n\n useEffect(\n () => {\n if (params) onValidationSuccess(params)\n else onValidationError(navigate)\n },\n [], // eslint-disable-line react-hooks/exhaustive-deps\n )\n\n return params ? children(params) : <></>\n}\n","import * as yup from \"yup\"\nimport { type ReactNode, useCallback, useEffect, useState } from \"react\"\nimport Cookies from \"js-cookie\"\nimport type { TypedUseMutation } from \"@reduxjs/toolkit/query/react\"\nimport { createSearchParams } from \"react-router\"\n// eslint-disable-next-line @typescript-eslint/no-restricted-imports\nimport { useSelector } from \"react-redux\"\n\nimport { type AuthFactor, type User } from \"../api\"\nimport {\n type OAuth2CodeChallenge,\n type OAuth2CodeChallengeLengths,\n type OAuth2ReceiveCodeUrlSearchParams,\n type OAuth2RequestCodeUrlSearchParams,\n generateOAuth2CodeChallenge,\n makeOAuth2StorageKey,\n} from \"../utils/auth\"\nimport { useLocation, useNavigate, useSearchParams } from \"./router\"\nimport { type ExchangeOAuth2CodeArg } from \"../api/endpoints/session\"\nimport { generateSecureRandomString } from \"../utils/general\"\nimport { getSessionMetadataCookieName } from \"../utils/settings\"\n\n// -----------------------------------------------------------------------------\n// Session\n// -----------------------------------------------------------------------------\n\nexport type SelectIsLoggedIn = (state: any) => boolean\n\nexport interface SessionMetadata {\n user_id: User[\"id\"]\n user_type: \"teacher\" | \"student\" | \"indy\"\n auth_factors: Array<AuthFactor[\"type\"]>\n otp_bypass_token_exists: boolean\n}\n\nexport function useSessionMetadata<T = SessionMetadata>(\n selectIsLoggedIn: SelectIsLoggedIn,\n): T | undefined {\n return useSelector(selectIsLoggedIn)\n ? (JSON.parse(Cookies.get(getSessionMetadataCookieName())!) as T)\n : undefined\n}\n\n/**\n * A utility function to predefine a useSessionMetadata hook.\n * @param cookieName The name of the session metadata cookie.\n * @returns An object containing the session metadata.\n */\nuseSessionMetadata.predefine = <SessionMetadata,>(\n selectIsLoggedIn: SelectIsLoggedIn,\n) => {\n return () => useSessionMetadata<SessionMetadata>(selectIsLoggedIn)\n}\n\nexport type UseSessionChildrenFunction<Required extends boolean> = (\n metadata: Required extends true\n ? SessionMetadata\n : SessionMetadata | undefined,\n) => ReactNode\n\nexport type UseSessionChildren<\n UserType extends SessionMetadata[\"user_type\"] | undefined,\n> =\n | ReactNode\n | (UserType extends undefined\n ? UseSessionChildrenFunction<false>\n : UseSessionChildrenFunction<true>)\n\nexport type UseSessionOptions<\n UserType extends SessionMetadata[\"user_type\"] | undefined,\n> = Partial<{\n userType: UserType\n next: boolean\n}>\n\nexport function useSession<\n UserType extends SessionMetadata[\"user_type\"] | undefined = undefined,\n>(\n selectIsLoggedIn: SelectIsLoggedIn,\n children: UseSessionChildren<UserType>,\n options: UseSessionOptions<UserType> = {},\n) {\n const { userType, next = true } = options\n\n const { pathname } = useLocation()\n const navigate = useNavigate()\n const sessionMetadata = useSessionMetadata(selectIsLoggedIn)\n\n const loginRequired =\n userType && (!sessionMetadata || sessionMetadata.user_type !== userType)\n\n useEffect(() => {\n if (loginRequired) {\n navigate({\n pathname:\n \"/login\" +\n {\n teacher: \"/teacher\",\n student: \"/student\",\n indy: \"/independent\",\n }[userType],\n search: next\n ? createSearchParams({ next: pathname }).toString()\n : undefined,\n })\n }\n }, [navigate, loginRequired, userType, next, pathname])\n\n if (loginRequired) return <></>\n\n if (typeof children === \"function\") {\n return sessionMetadata\n ? (children as UseSessionChildrenFunction<true>)(sessionMetadata)\n : (children as UseSessionChildrenFunction<false>)(sessionMetadata)\n }\n\n return children\n}\n\n// -----------------------------------------------------------------------------\n// OAuth2\n// -----------------------------------------------------------------------------\n\nexport function useOAuth2State(\n provider: string,\n length: number = 32,\n storageKey: string = \"state\",\n): [string | undefined, () => void] {\n const oAuth2StorageKey = makeOAuth2StorageKey(provider, storageKey)\n const storageValue = sessionStorage.getItem(oAuth2StorageKey)\n\n const [_state, _setState] = useState<string>()\n\n useEffect(() => {\n let state: string\n if (storageValue && storageValue.length === length) {\n state = storageValue\n } else {\n state = generateSecureRandomString(length)\n sessionStorage.setItem(oAuth2StorageKey, state)\n }\n\n _setState(state)\n }, [oAuth2StorageKey, storageValue, length])\n\n const resetState = useCallback(() => {\n sessionStorage.removeItem(oAuth2StorageKey)\n _setState(undefined)\n }, [oAuth2StorageKey])\n\n return [_state, resetState]\n}\n\nexport function useOAuth2CodeChallenge(\n provider: string,\n length: OAuth2CodeChallengeLengths = 128,\n storageKey: string = \"codeChallenge\",\n): [OAuth2CodeChallenge | undefined, () => void] {\n const oAuth2StorageKey = makeOAuth2StorageKey(provider, storageKey)\n const storageValue = sessionStorage.getItem(oAuth2StorageKey)\n\n const [_codeChallenge, _setCodeChallenge] = useState<OAuth2CodeChallenge>()\n\n useEffect(() => {\n let codeChallenge: OAuth2CodeChallenge | undefined\n if (storageValue) {\n const storageJsonValue: unknown = JSON.parse(storageValue)\n if (\n typeof storageJsonValue === \"object\" &&\n storageJsonValue &&\n \"verifier\" in storageJsonValue &&\n typeof storageJsonValue.verifier == \"string\" &&\n storageJsonValue.verifier.length === length &&\n \"challenge\" in storageJsonValue &&\n typeof storageJsonValue.challenge === \"string\" &&\n \"method\" in storageJsonValue &&\n storageJsonValue.method === \"S256\"\n ) {\n codeChallenge = {\n verifier: storageJsonValue.verifier,\n challenge: storageJsonValue.challenge,\n method: storageJsonValue.method,\n }\n }\n }\n\n if (codeChallenge) _setCodeChallenge(codeChallenge)\n else {\n generateOAuth2CodeChallenge(length)\n .then(codeChallenge => {\n sessionStorage.setItem(\n oAuth2StorageKey,\n JSON.stringify(codeChallenge),\n )\n\n _setCodeChallenge(codeChallenge)\n })\n .catch(error => {\n if (error) console.error(error)\n })\n }\n }, [oAuth2StorageKey, storageValue, length])\n\n const resetCodeChallenge = useCallback(() => {\n sessionStorage.removeItem(oAuth2StorageKey)\n _setCodeChallenge(undefined)\n }, [oAuth2StorageKey])\n\n return [_codeChallenge, resetCodeChallenge]\n}\n\ninterface BaseUseOAuth2KwArgs<SessionMetadata> {\n provider: string\n authUri: string\n clientId: string\n redirectUri: string\n scope: string\n responseType?: \"code\"\n accessType?: \"offline\"\n prompt?: string\n useLoginMutation: TypedUseMutation<\n SessionMetadata,\n ExchangeOAuth2CodeArg,\n any\n >\n onCreateSession: (result: SessionMetadata) => void\n onRetrieveSession: (metadata: SessionMetadata) => void\n}\n\ninterface UseOAuth2KwArgs<SessionMetadata>\n extends BaseUseOAuth2KwArgs<SessionMetadata> {\n useSessionMetadata: () => SessionMetadata | undefined\n}\n\nexport type OAuth2 = [string, OAuth2RequestCodeUrlSearchParams] | []\n\n// https://datatracker.ietf.org/doc/html/rfc7636\nfunction useOAuth2Internal<SessionMetadata>({\n provider,\n authUri,\n clientId,\n redirectUri,\n scope,\n responseType = \"code\",\n accessType = \"offline\",\n prompt,\n useSessionMetadata,\n useLoginMutation,\n onCreateSession,\n onRetrieveSession,\n}: UseOAuth2KwArgs<SessionMetadata>): OAuth2 {\n const [state, resetState] = useOAuth2State(provider)\n const [\n {\n verifier: codeVerifier,\n challenge: codeChallenge,\n method: codeChallengeMethod,\n } = {},\n resetCodeChallenge,\n ] = useOAuth2CodeChallenge(provider)\n const [\n login,\n {\n originalArgs: loginArgs = {} as ExchangeOAuth2CodeArg,\n isLoading: loginIsLoading,\n isError: loginIsError,\n },\n ] = useLoginMutation()\n const sessionMetadata = useSessionMetadata()\n const navigate = useNavigate()\n const searchParams =\n useSearchParams({ code: yup.string(), state: yup.string() }) || {}\n const location = useLocation<OAuth2ReceiveCodeUrlSearchParams>()\n\n const locationState = location.state || {}\n\n useEffect(() => {\n // If the the auth provider has redirected back to our site with the\n // expected search params, we redirect to the current page to remove them.\n if (searchParams.code && searchParams.state) {\n navigate<OAuth2ReceiveCodeUrlSearchParams>(\".\", {\n // Removes the URL containing the search params from the history stack.\n replace: true,\n // Ensure we don't break the auth flow by navigating to another page.\n next: false,\n // Store the search params in the page's state instead.\n state: { code: searchParams.code, state: searchParams.state },\n })\n }\n }, [searchParams.code, searchParams.state, navigate])\n\n useEffect(() => {\n // If we're already logged in, no need to log in again.\n if (sessionMetadata) onRetrieveSession(sessionMetadata)\n else if (\n // If the state and code verifier have been generated...\n state &&\n codeVerifier &&\n // ...and the page's state contains a code...\n locationState.code &&\n // ...and the page's state contains the stored state...\n locationState.state === state &&\n // ...and the login endpoint was not called with the current values or has\n // not returned an error...\n (loginArgs.code !== locationState.code ||\n loginArgs.code_verifier !== codeVerifier ||\n loginArgs.redirect_uri !== redirectUri ||\n !loginIsError) &&\n // ...and the login endpoint is not currently being called...\n !loginIsLoading\n ) {\n // ...call the login endpoint.\n login({\n code: locationState.code,\n code_verifier: codeVerifier,\n redirect_uri: redirectUri,\n })\n .unwrap()\n .then(onCreateSession)\n .catch(() => {\n navigate(\".\", {\n replace: true,\n state: {\n notifications: [\n {\n props: {\n error: true,\n children: \"Failed to login. Please try again.\",\n },\n },\n ],\n },\n })\n })\n .finally(() => {\n resetState()\n resetCodeChallenge()\n })\n }\n }, [\n navigate,\n redirectUri,\n // State\n state,\n locationState.state,\n resetState,\n // Code\n codeVerifier,\n locationState.code,\n resetCodeChallenge,\n // Login\n login,\n loginIsLoading,\n loginIsError,\n loginArgs.code,\n loginArgs.code_verifier,\n loginArgs.redirect_uri,\n // Session\n sessionMetadata,\n onCreateSession,\n onRetrieveSession,\n ])\n\n if (state && codeChallenge && codeChallengeMethod) {\n const urlSearchParams: OAuth2RequestCodeUrlSearchParams = {\n client_id: clientId,\n redirect_uri: redirectUri,\n scope,\n response_type: responseType,\n access_type: accessType,\n state,\n code_challenge: codeChallenge,\n code_challenge_method: codeChallengeMethod,\n }\n\n if (prompt) urlSearchParams[\"prompt\"] = prompt\n\n return [\n authUri + \"?\" + new URLSearchParams(urlSearchParams).toString(),\n urlSearchParams,\n ]\n }\n\n return []\n}\n\nexport const useOAuth2: {\n <SessionMetadata>(kwargs: UseOAuth2KwArgs<SessionMetadata>): OAuth2\n (kwargs: BaseUseOAuth2KwArgs<SessionMetadata>): OAuth2\n} = <_SessionMetadata,>(\n kwargs:\n | UseOAuth2KwArgs<_SessionMetadata>\n | BaseUseOAuth2KwArgs<SessionMetadata>,\n): OAuth2 => {\n return useOAuth2Internal(\n // @ts-expect-error value is assignable\n \"useSessionMetadata\" in kwargs ? kwargs : { ...kwargs, useSessionMetadata },\n )\n}\n"],"names":["useNavigate","navigate","_useNavigate","searchParams","useSearchParams","toOrDelta","options","next","_options","useLocation","_useLocation","shape","validateOptions","_useSearchParams","tryValidateSync","objectSchema","useParams","params","_useParams","useParamsRequired","children","onValidationError","onValidationSuccess","useEffect","jsx","Fragment","useSessionMetadata","selectIsLoggedIn","useSelector","Cookies","getSessionMetadataCookieName","useSession","userType","pathname","sessionMetadata","loginRequired","createSearchParams","useOAuth2State","provider","length","storageKey","oAuth2StorageKey","makeOAuth2StorageKey","storageValue","_state","_setState","useState","state","generateSecureRandomString","resetState","useCallback","useOAuth2CodeChallenge","_codeChallenge","_setCodeChallenge","codeChallenge","storageJsonValue","generateOAuth2CodeChallenge","error","resetCodeChallenge","useOAuth2Internal","authUri","clientId","redirectUri","scope","responseType","accessType","prompt","useLoginMutation","onCreateSession","onRetrieveSession","codeVerifier","codeChallengeMethod","login","loginArgs","loginIsLoading","loginIsError","yup","locationState","urlSearchParams","useOAuth2","kwargs"],"mappings":"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"}
@@ -1,2 +0,0 @@
1
- "use strict";const e=require("react/jsx-runtime"),m=require("@mui/material"),T=require("react"),Z=require("./api-G8CV5bUa.cjs"),ee=require("./api-DIgp_6Vr.cjs"),O=require("formik"),_=require("yup"),E=require("./utils/form.cjs.js"),g=require("./utils/general.cjs.js"),te=require("./dayjs.min-BDMWgl2D.cjs"),w=require("@mui/x-date-pickers"),re=require("@mui/x-date-pickers/AdapterDayjs"),I=require("@mui/icons-material");require("@reduxjs/toolkit/query/react");require("@reduxjs/toolkit");require("js-cookie");const oe=require("./schemas-hIW9-H6-.cjs");require("./urls-2gheISSO.cjs");const R=({useLazyListQuery:r,filterOptions:t,getOptionLabel:n,getOptionKey:o=l=>l.id,searchKey:s,...i})=>{const[l,d]=T.useState(""),[a,{isLoading:u,isError:c}]=r(),[{limit:f,offset:p},x]=ee.usePagination(),[{options:b,hasMore:F},S]=T.useState({options:{},hasMore:!0});T.useEffect(()=>{const j={limit:f,offset:p,...t};l&&(j[s]=l),a(j,!0).unwrap().then(({data:C,offset:q,limit:N,count:V})=>{S(({options:X})=>{const k={...X};return C.forEach(L=>{k[o(L)]=L}),{options:k,hasMore:q+N<V}})}).catch(C=>{C&&console.error(C)})},[a,f,p,s,l,...Object.values(t||{})]);let h=Object.keys(b);if(!h.length)return e.jsx(e.Fragment,{});typeof o(Object.values(b)[0])=="number"&&(h=h.map(Number));function y(){x(({page:j,limit:C})=>({page:j+1,limit:C}))}const P=({children:j,...C},q)=>{const N=T.Children.toArray(j);return u?N.push(e.jsx(m.CircularProgress,{},"is-loading")):(c&&N.push(e.jsx(Z.SyncError,{},"is-error")),F&&N.push(e.jsx(m.Button,{onClick:y,children:"Load more"},"load-more"))),e.jsx("ul",{...C,ref:q,onScroll:V=>{!u&&V.currentTarget.clientHeight+V.currentTarget.scrollTop>=V.currentTarget.scrollHeight&&y()},children:N})};return e.jsx(B,{options:h,getOptionLabel:j=>n(b[j]),onInputChange:(j,C,q)=>{d(q==="input"?C:"")},ListboxComponent:T.forwardRef(P),...i})},B=({textFieldProps:r,options:t,validateOptions:n,...o})=>{const{id:s,name:i,required:l,...d}=r,a=i.split("."),u="not a valid option";let c=typeof t[0]=="string"?_.string().oneOf(t,u):_.number().oneOf(t,u);l&&(c=c.required());const f={name:i,type:typeof t[0]=="string"?"text":"number",validate:E.schemaToFieldValidator(c,n)};return e.jsx(O.Field,{...f,children:({form:p,meta:x})=>{const b=g.getNestedProperty(p.values,a),F=g.getNestedProperty(p.touched,a),S=g.getNestedProperty(p.errors,a);return e.jsx(m.Autocomplete,{options:t,defaultValue:x.initialValue===""?void 0:x.initialValue,renderInput:({id:h,...y})=>e.jsx(m.TextField,{id:s??i,name:i,required:l,type:"text",value:b,error:F&&!!S,helperText:F&&S,...d,...y}),onChange:(h,y)=>{p.setFieldValue(i,y??void 0,!0)},onBlur:p.handleBlur,...o})}})},M=({id:r,name:t,formControlLabelProps:n,required:o=!1,errorMessage:s="this is a required field",validateOptions:i,...l})=>{const d=t.split(".");let a=_.bool();o&&(a=a.oneOf([!0],s));const u={name:t,type:"checkbox",validate:E.schemaToFieldValidator(a,i)};return e.jsx(O.Field,{...u,children:({form:c,meta:f})=>{const p=g.getNestedProperty(c.touched,d),x=g.getNestedProperty(c.errors,d),b=g.getNestedProperty(c.values,d),F=p&&!!x;return e.jsxs(m.FormControl,{error:F,required:o,children:[e.jsx(m.FormControlLabel,{control:e.jsx(m.Checkbox,{defaultChecked:f.initialValue,id:r??t,name:t,value:b,onChange:c.handleChange,onBlur:c.handleBlur,...l}),...n}),F&&e.jsx(m.FormHelperText,{children:x})]})}})},U=({textFieldProps:r,...t})=>{const{name:n="country",label:o="Country",placeholder:s="Select your country",...i}=r||{};return e.jsx(B,{options:g.COUNTRY_ISO_CODES,getOptionLabel:l=>g.COUNTRY_ISO_CODE_MAPPING[l],textFieldProps:{name:n,label:o,placeholder:s,...i},...t})},Y=({name:r,required:t,minDate:n,maxDate:o,validateOptions:s,...i})=>{const l=r.split(".");function d(c){return c.locale("en-gb").format("L")}let a=_.date();t&&(a=a.required()),n&&(a=a.min(n,`this field must be after or equal to ${d(n)}`)),o&&(a=a.max(o,`this field must be before or equal to ${d(o)}`));const u={name:r,type:"date",validate:E.schemaToFieldValidator(a,s)};return e.jsx(O.Field,{...u,children:({form:c})=>{const f=g.getNestedProperty(c.errors,l),p=g.getNestedProperty(c.touched,l);let x=g.getNestedProperty(c.values,l);x=x?te.dayjs(x):null;function b(F){c.setFieldValue(r,F&&F.isValid()?F.format("YYYY-MM-DD"):null,!0)}return e.jsx(w.LocalizationProvider,{dateAdapter:re.AdapterDayjs,adapterLocale:"en-gb",children:e.jsx(w.DatePicker,{name:r,value:x,minDate:n,maxDate:o,onChange:b,slotProps:{textField:{id:r,onChange:F=>{b(F)},onBlur:c.handleBlur,required:t,error:p&&!!f,helperText:p&&f}},...i})})}})},v=({id:r,name:t,schema:n,type:o="text",required:s=!1,dirty:i=!1,unique:l=!1,uniqueCaseInsensitive:d=!1,split:a,validateOptions:u,...c})=>{const[f,p]=T.useState(""),x=t.split(".");function b(){let h=n;if(h=s?h.required():h.optional(),i&&!a&&(h=h.notOneOf([f],"cannot be initial value")),!a)return h;let y=_.array().of(h);return y=s?y.required().min(1):y.optional(),(l||d)&&(y=y.test({message:"cannot have duplicates",test:P=>Array.isArray(P)&&P.length>=2&&P.every(j=>typeof j=="string")?new Set(d?P.map(j=>j.toLowerCase()):P).size===P.length:!0})),i&&(y=y.notOneOf([f],"cannot be initial value")),y}const F={name:t,type:o,validate:E.schemaToFieldValidator(b(),u)},S=({form:h})=>{const y=g.getNestedProperty(h.initialValues,x),P=g.getNestedProperty(h.values,x),j=g.getNestedProperty(h.errors,x),C=g.getNestedProperty(h.touched,x);return T.useEffect(()=>{p(y)},[y]),T.useEffect(()=>{h.setFieldValue(t,a&&typeof P=="string"?P.split(a):P,!0)},[P]),e.jsx(m.TextField,{id:r??t,name:t,type:o,required:s,value:P,onChange:h.handleChange,onBlur:h.handleBlur,error:C&&!!j,helperText:C&&j,...c})};return e.jsx(O.Field,{...F,children:S})},D=({name:r="email",label:t="Email address",placeholder:n="Enter your email address",InputProps:o={},...s})=>e.jsx(v,{type:"email",schema:_.string().email(),name:r,label:t,placeholder:n,InputProps:{endAdornment:e.jsx(m.InputAdornment,{position:"end",children:e.jsx(I.EmailOutlined,{})}),...o},...s}),H=({name:r="first_name",label:t="First name",placeholder:n="Enter your first name",InputProps:o={},...s})=>e.jsx(v,{schema:oe.user.first_name,name:r,label:t,placeholder:n,InputProps:{endAdornment:e.jsx(m.InputAdornment,{position:"end",children:e.jsx(I.PersonOutlined,{})}),...o},...s}),z={behavior:"smooth",block:"start"},ne=({scrollIntoViewOptions:r=z,...t})=>{const n=T.useRef(null);return T.useEffect(()=>{n.current&&n.current.scrollIntoView(r)},[r]),e.jsx(m.FormHelperText,{ref:n,error:!0,...t})},K=({children:r,scrollIntoViewOptions:t=z,nonFieldErrorsProps:n,fieldRefs:o=[],...s})=>e.jsx(O.Formik,{...s,children:i=>{const l=!!Object.keys(i.errors).length,d=l&&typeof i.errors.__all__=="string";if(l&&!d&&i.isSubmitting&&o.length){const a=g.getKeyPaths(i.errors),u=o.find(({name:c})=>a.includes(c))?.inputRef.current;u&&u.scrollIntoView(t)}return e.jsxs(e.Fragment,{children:[d&&e.jsx(ne,{...n,children:i.errors.__all__}),e.jsx(O.Form,{children:typeof r=="function"?r(i):r})]})}}),se=({useMutation:r,submitOptions:t,...n})=>{const[o]=r();return e.jsx(K,{...n,onSubmit:E.submitForm(o,n.initialValues,t)})},$=r=>"onSubmit"in r?e.jsx(K,{...r}):se(r),G=({name:r="otp",label:t="OTP",placeholder:n="Enter your OTP",...o})=>e.jsx(v,{name:r,label:t,schema:_.string().matches(/^[0-9]{6}$/,"Must be exactly 6 digits."),placeholder:n,required:!0,...o}),ie=({id:r,repeatName:t,setValue:n,fieldProps:o,name:s,label:i,placeholder:l,type:d,...a})=>{const{form:u}=o,c=s.split("."),f=g.getNestedProperty(u.values,c),p=t.split("."),x=g.getNestedProperty(u.values,p),b=g.getNestedProperty(u.touched,p),F=g.getNestedProperty(u.errors,p);return T.useEffect(()=>{n(f)},[n,f]),e.jsx(m.TextField,{required:!0,type:d,label:i??`Repeat ${s.replace("_"," ")}`,placeholder:l??`Enter your ${s.replace("_"," ")} again`,id:r??t,name:t,value:x,onChange:u.handleChange,onBlur:u.handleBlur,error:b&&!!F,helperText:b&&F,...a})},A=({name:r,type:t="text",validateOptions:n,...o})=>{const[s,i]=T.useState(""),l=`${r}_repeat`,d={name:l,type:t,validate:E.schemaToFieldValidator(_.string().required().equals([s],"does not match"),n)};return e.jsx(O.Field,{...d,children:a=>e.jsx(ie,{name:r,type:t,repeatName:l,setValue:i,fieldProps:a,...o})})},W=({name:r="password",label:t="Password",placeholder:n="Enter your password",schema:o=_.string(),InputProps:s={},withRepeatField:i=!1,repeatFieldProps:l={},...d})=>{const[a,u]=T.useState(!1),c=a?"text":"password",f=e.jsx(m.InputAdornment,{position:"end",children:e.jsx(m.IconButton,{onClick:()=>{u(p=>!p)},edge:"end",children:a?e.jsx(I.Visibility,{}):e.jsx(I.VisibilityOff,{})})});return e.jsxs(e.Fragment,{children:[e.jsx(v,{autoComplete:"off",type:c,name:r,label:t,schema:o,placeholder:n,InputProps:{endAdornment:f,...s},...d}),i&&e.jsx(A,{name:r,type:c,...l,InputProps:{endAdornment:f,...l.InputProps}})]})},J=({children:r="Submit",...t})=>{function n(o,s){s=s||{};for(const i in o){const l=o[i];s[i]=l instanceof Object&&l.constructor===Object?n(l,s):!0}return s}return e.jsx(O.Field,{name:"submit",type:"submit",children:({form:o})=>e.jsx(m.Button,{type:"button",onClick:()=>{o.setTouched(n(o.values),!0).then(s=>{const i=!!(s&&Object.keys(s).length);o.setSubmitting(i),i||o.submitForm()})},...t,children:r})})},Q=({textFieldProps:r,...t})=>{const{name:n="uk_county",label:o="UK county",placeholder:s="Select your UK county",...i}=r||{};return e.jsx(B,{options:g.UK_COUNTIES,textFieldProps:{name:n,label:o,placeholder:s,...i},...t})},le=Object.freeze(Object.defineProperty({__proto__:null,ApiAutocompleteField:R,AutocompleteField:B,CheckboxField:M,CountryField:U,DatePickerField:Y,EmailField:D,FirstNameField:H,Form:$,OtpField:G,PasswordField:W,RepeatField:A,SubmitButton:J,TextField:v,UkCountyField:Q},Symbol.toStringTag,{value:"Module"}));exports.ApiAutocompleteField=R;exports.AutocompleteField=B;exports.CheckboxField=M;exports.CountryField=U;exports.DatePickerField=Y;exports.EmailField=D;exports.FirstNameField=H;exports.Form=$;exports.OtpField=G;exports.PasswordField=W;exports.RepeatField=A;exports.SubmitButton=J;exports.TextField=v;exports.UkCountyField=Q;exports.index=le;
2
- //# sourceMappingURL=index-Da4T5FYK.cjs.map
@@ -1,2 +0,0 @@
1
- "use strict";var v=Object.create;var h=Object.defineProperty;var w=Object.getOwnPropertyDescriptor;var T=Object.getOwnPropertyNames;var A=Object.getPrototypeOf,k=Object.prototype.hasOwnProperty;var E=(e,t,r,c)=>{if(t&&typeof t=="object"||typeof t=="function")for(let o of T(t))!k.call(e,o)&&o!==r&&h(e,o,{get:()=>t[o],enumerable:!(c=w(t,o))||c.enumerable});return e};var i=(e,t,r)=>(r=e!=null?v(A(e)):{},E(t||!e||!e.__esModule?h(r,"default",{value:e,enumerable:!0}):r,e));Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const n=require("react/jsx-runtime"),f=require("react-router"),C=require("react"),M=require("@emotion/cache"),y=require("./DefaultRoutes.cjs.js");require("@mui/material");require("@emotion/react");require("react-redux");;/* empty css */const _="codeforlife",D={name:_};function j({key:e="css",prepend:t=!0,...r}={}){return M({key:e,prepend:t,...r})}const x=!0;async function F({App:e,routes:t,catchAllRoute:r=x,createEmotionCacheOptions:c,...o}){const{default:s}=await import("@emotion/server/create-instance"),{renderToString:a}=await import("react-dom/server"),{default:u}=await import("node:fs/promises"),S=await u.readFile(`./node_modules/${D.name}/dist/style.css`,"utf-8");function q(R){const l=j(c),d=s(l),m=a(n.jsx(C.StrictMode,{children:n.jsx(e,{emotionCache:l,...o,children:n.jsx(f.StaticRouter,{location:R,children:n.jsx(y,{catchAll:r,children:t})})})})),g=d.extractCriticalToChunks(m),p=d.constructStyleTagsFromChunks(g);return{html:m,head:`${p}<style data-cfl>${S}</style>`}}return{render:q}}async function L({App:e,routes:t,catchAllRoute:r=x,createEmotionCacheOptions:c,...o}){const s=await import("react-dom/client"),{hydrateRoot:a}=s.default||s,u=j(c);a(document.getElementById("root"),n.jsx(C.StrictMode,{children:n.jsx(e,{emotionCache:u,...o,children:n.jsx(f.BrowserRouter,{children:n.jsx(y,{catchAll:r,children:t})})})}))}exports.client=L;exports.server=F;
2
- //# sourceMappingURL=entry.cjs.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"entry.cjs.js","sources":["../../src/server/entry.tsx"],"sourcesContent":["/**\n * © Ocado Group\n * Created on 20/10/2025 at 17:45:17(+01:00).\n *\n * The client and server entrypoints when doing server-side rendering.\n *\n * Helpful links:\n * https://mui.com/material-ui/guides/server-rendering/\n * https://github.com/remix-run/react-router/tree/main/examples/ssr\n */\n\nimport { BrowserRouter, StaticRouter } from \"react-router\"\nimport { type FC, StrictMode } from \"react\"\nimport createCache, {\n type Options as CreateEmotionCacheOptions,\n} from \"@emotion/cache\"\n\nimport DefaultRoutes, { type DefaultRoutesProps } from \"./DefaultRoutes\"\nimport { type AppProps } from \"./App\"\nimport packageJson from \"../../package.json\"\n\n/**\n * Creates a new Emotion cache instance.\n */\nfunction createEmotionCache(\n {\n key = \"css\", // ensures all styles are generated with this prefix\n prepend = true, // loads MUI-styles first so we can override them easily\n ...otherOptions\n } = {} as CreateEmotionCacheOptions,\n) {\n return createCache({ key, prepend, ...otherOptions })\n}\n\nexport type EntryAppProps = Pick<AppProps, \"emotionCache\" | \"children\">\n\nexport type EntryKwArgs = {\n App: FC<EntryAppProps>\n routes: DefaultRoutesProps[\"children\"]\n catchAllRoute?: DefaultRoutesProps[\"catchAll\"]\n createEmotionCacheOptions?: CreateEmotionCacheOptions\n}\n\nconst DEFAULT_CATCH_ALL: DefaultRoutesProps[\"catchAll\"] = true\n\nexport async function server({\n App,\n routes,\n catchAllRoute = DEFAULT_CATCH_ALL,\n createEmotionCacheOptions,\n ...appProps\n}: EntryKwArgs) {\n const { default: createEmotionServer } = await import(\n \"@emotion/server/create-instance\"\n )\n const { renderToString } = await import(\"react-dom/server\")\n const { default: fs } = await import(\"node:fs/promises\")\n\n const cflStyle = await fs.readFile(\n `./node_modules/${packageJson.name}/dist/style.css`,\n \"utf-8\",\n )\n\n function render(path: string) {\n const emotionCache = createEmotionCache(createEmotionCacheOptions)\n const emotionServer = createEmotionServer(emotionCache)\n\n const html = renderToString(\n <StrictMode>\n <App emotionCache={emotionCache} {...appProps}>\n <StaticRouter location={path}>\n <DefaultRoutes catchAll={catchAllRoute}>{routes}</DefaultRoutes>\n </StaticRouter>\n </App>\n </StrictMode>,\n )\n\n const emotionChunks = emotionServer.extractCriticalToChunks(html)\n const emotionCss = emotionServer.constructStyleTagsFromChunks(emotionChunks)\n\n return {\n html,\n head: `${emotionCss}<style data-cfl>${cflStyle}</style>`,\n }\n }\n\n return { render }\n}\n\nexport async function client({\n App,\n routes,\n catchAllRoute = DEFAULT_CATCH_ALL,\n createEmotionCacheOptions,\n ...appProps\n}: EntryKwArgs) {\n const reactDomClientModule = await import(\"react-dom/client\")\n\n // Check for the .default property to handle CJS/ESM interop.\n // 'hydrateRoot' will be on the module itself OR on the .default object.\n const { hydrateRoot } = reactDomClientModule.default || reactDomClientModule\n\n const emotionCache = createEmotionCache(createEmotionCacheOptions)\n\n hydrateRoot(\n document.getElementById(\"root\") as HTMLElement,\n <StrictMode>\n <App emotionCache={emotionCache} {...appProps}>\n <BrowserRouter>\n <DefaultRoutes catchAll={catchAllRoute}>{routes}</DefaultRoutes>\n </BrowserRouter>\n </App>\n </StrictMode>,\n )\n}\n"],"names":["createEmotionCache","key","prepend","otherOptions","createCache","DEFAULT_CATCH_ALL","server","App","routes","catchAllRoute","createEmotionCacheOptions","appProps","createEmotionServer","renderToString","fs","cflStyle","packageJson","render","path","emotionCache","emotionServer","html","StrictMode","jsx","StaticRouter","DefaultRoutes","emotionChunks","emotionCss","client","reactDomClientModule","hydrateRoot","BrowserRouter"],"mappings":"uzBAwBA,SAASA,EACP,CACE,IAAAC,EAAM,MACN,QAAAC,EAAU,GACV,GAAGC,CACL,EAAI,GACJ,CACA,OAAOC,EAAY,CAAE,IAAAH,EAAK,QAAAC,EAAS,GAAGC,EAAc,CACtD,CAWA,MAAME,EAAoD,GAE1D,eAAsBC,EAAO,CAC3B,IAAAC,EACA,OAAAC,EACA,cAAAC,EAAgBJ,EAChB,0BAAAK,EACA,GAAGC,CACL,EAAgB,CACd,KAAM,CAAE,QAASC,GAAwB,KAAM,QAC7C,iCACF,EACM,CAAE,eAAAC,CAAA,EAAmB,KAAM,QAAO,kBAAkB,EACpD,CAAE,QAASC,GAAO,KAAM,QAAO,kBAAkB,EAEjDC,EAAW,MAAMD,EAAG,SACxB,kBAAkBE,EAAY,IAAI,kBAClC,OAAA,EAGF,SAASC,EAAOC,EAAc,CAC5B,MAAMC,EAAenB,EAAmBU,CAAyB,EAC3DU,EAAgBR,EAAoBO,CAAY,EAEhDE,EAAOR,QACVS,EAAAA,WAAA,CACC,SAAAC,EAAAA,IAAChB,GAAI,aAAAY,EAA6B,GAAGR,EACnC,SAAAY,EAAAA,IAACC,EAAAA,aAAA,CAAa,SAAUN,EACtB,eAACO,EAAA,CAAc,SAAUhB,EAAgB,SAAAD,CAAA,CAAO,CAAA,CAClD,EACF,CAAA,CACF,CAAA,EAGIkB,EAAgBN,EAAc,wBAAwBC,CAAI,EAC1DM,EAAaP,EAAc,6BAA6BM,CAAa,EAE3E,MAAO,CACL,KAAAL,EACA,KAAM,GAAGM,CAAU,mBAAmBZ,CAAQ,UAAA,CAElD,CAEA,MAAO,CAAE,OAAAE,CAAA,CACX,CAEA,eAAsBW,EAAO,CAC3B,IAAArB,EACA,OAAAC,EACA,cAAAC,EAAgBJ,EAChB,0BAAAK,EACA,GAAGC,CACL,EAAgB,CACd,MAAMkB,EAAuB,KAAM,QAAO,kBAAkB,EAItD,CAAE,YAAAC,CAAA,EAAgBD,EAAqB,SAAWA,EAElDV,EAAenB,EAAmBU,CAAyB,EAEjEoB,EACE,SAAS,eAAe,MAAM,QAC7BR,EAAAA,WAAA,CACC,SAAAC,MAAChB,EAAA,CAAI,aAAAY,EAA6B,GAAGR,EACnC,SAAAY,MAACQ,EAAAA,cAAA,CACC,SAAAR,EAAAA,IAACE,GAAc,SAAUhB,EAAgB,SAAAD,CAAA,CAAO,EAClD,EACF,CAAA,CACF,CAAA,CAEJ"}
@@ -1,2 +0,0 @@
1
- export * from '../src/server/entry'
2
- export {}
@@ -1,62 +0,0 @@
1
- import { jsx as t } from "react/jsx-runtime";
2
- import { BrowserRouter as T, StaticRouter as g } from "react-router";
3
- import { StrictMode as u } from "react";
4
- import k from "@emotion/cache";
5
- import h from "./DefaultRoutes.es.js";
6
- import "@mui/material";
7
- import "@emotion/react";
8
- import "react-redux";
9
- /* empty css */
10
- const E = "codeforlife", R = {
11
- name: E
12
- };
13
- function f({
14
- key: o = "css",
15
- // ensures all styles are generated with this prefix
16
- prepend: e = !0,
17
- // loads MUI-styles first so we can override them easily
18
- ...r
19
- } = {}) {
20
- return k({ key: o, prepend: e, ...r });
21
- }
22
- const p = !0;
23
- async function j({
24
- App: o,
25
- routes: e,
26
- catchAllRoute: r = p,
27
- createEmotionCacheOptions: c,
28
- ...i
29
- }) {
30
- const { default: n } = await import("@emotion/server/create-instance"), { renderToString: a } = await import("react-dom/server"), { default: s } = await import("node:fs/promises"), C = await s.readFile(
31
- `./node_modules/${R.name}/dist/style.css`,
32
- "utf-8"
33
- );
34
- function y(S) {
35
- const l = f(c), m = n(l), d = a(
36
- /* @__PURE__ */ t(u, { children: /* @__PURE__ */ t(o, { emotionCache: l, ...i, children: /* @__PURE__ */ t(g, { location: S, children: /* @__PURE__ */ t(h, { catchAll: r, children: e }) }) }) })
37
- ), w = m.extractCriticalToChunks(d), A = m.constructStyleTagsFromChunks(w);
38
- return {
39
- html: d,
40
- head: `${A}<style data-cfl>${C}</style>`
41
- };
42
- }
43
- return { render: y };
44
- }
45
- async function H({
46
- App: o,
47
- routes: e,
48
- catchAllRoute: r = p,
49
- createEmotionCacheOptions: c,
50
- ...i
51
- }) {
52
- const n = await import("react-dom/client"), { hydrateRoot: a } = n.default || n, s = f(c);
53
- a(
54
- document.getElementById("root"),
55
- /* @__PURE__ */ t(u, { children: /* @__PURE__ */ t(o, { emotionCache: s, ...i, children: /* @__PURE__ */ t(T, { children: /* @__PURE__ */ t(h, { catchAll: r, children: e }) }) }) })
56
- );
57
- }
58
- export {
59
- H as client,
60
- j as server
61
- };
62
- //# sourceMappingURL=entry.es.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"entry.es.js","sources":["../../src/server/entry.tsx"],"sourcesContent":["/**\n * © Ocado Group\n * Created on 20/10/2025 at 17:45:17(+01:00).\n *\n * The client and server entrypoints when doing server-side rendering.\n *\n * Helpful links:\n * https://mui.com/material-ui/guides/server-rendering/\n * https://github.com/remix-run/react-router/tree/main/examples/ssr\n */\n\nimport { BrowserRouter, StaticRouter } from \"react-router\"\nimport { type FC, StrictMode } from \"react\"\nimport createCache, {\n type Options as CreateEmotionCacheOptions,\n} from \"@emotion/cache\"\n\nimport DefaultRoutes, { type DefaultRoutesProps } from \"./DefaultRoutes\"\nimport { type AppProps } from \"./App\"\nimport packageJson from \"../../package.json\"\n\n/**\n * Creates a new Emotion cache instance.\n */\nfunction createEmotionCache(\n {\n key = \"css\", // ensures all styles are generated with this prefix\n prepend = true, // loads MUI-styles first so we can override them easily\n ...otherOptions\n } = {} as CreateEmotionCacheOptions,\n) {\n return createCache({ key, prepend, ...otherOptions })\n}\n\nexport type EntryAppProps = Pick<AppProps, \"emotionCache\" | \"children\">\n\nexport type EntryKwArgs = {\n App: FC<EntryAppProps>\n routes: DefaultRoutesProps[\"children\"]\n catchAllRoute?: DefaultRoutesProps[\"catchAll\"]\n createEmotionCacheOptions?: CreateEmotionCacheOptions\n}\n\nconst DEFAULT_CATCH_ALL: DefaultRoutesProps[\"catchAll\"] = true\n\nexport async function server({\n App,\n routes,\n catchAllRoute = DEFAULT_CATCH_ALL,\n createEmotionCacheOptions,\n ...appProps\n}: EntryKwArgs) {\n const { default: createEmotionServer } = await import(\n \"@emotion/server/create-instance\"\n )\n const { renderToString } = await import(\"react-dom/server\")\n const { default: fs } = await import(\"node:fs/promises\")\n\n const cflStyle = await fs.readFile(\n `./node_modules/${packageJson.name}/dist/style.css`,\n \"utf-8\",\n )\n\n function render(path: string) {\n const emotionCache = createEmotionCache(createEmotionCacheOptions)\n const emotionServer = createEmotionServer(emotionCache)\n\n const html = renderToString(\n <StrictMode>\n <App emotionCache={emotionCache} {...appProps}>\n <StaticRouter location={path}>\n <DefaultRoutes catchAll={catchAllRoute}>{routes}</DefaultRoutes>\n </StaticRouter>\n </App>\n </StrictMode>,\n )\n\n const emotionChunks = emotionServer.extractCriticalToChunks(html)\n const emotionCss = emotionServer.constructStyleTagsFromChunks(emotionChunks)\n\n return {\n html,\n head: `${emotionCss}<style data-cfl>${cflStyle}</style>`,\n }\n }\n\n return { render }\n}\n\nexport async function client({\n App,\n routes,\n catchAllRoute = DEFAULT_CATCH_ALL,\n createEmotionCacheOptions,\n ...appProps\n}: EntryKwArgs) {\n const reactDomClientModule = await import(\"react-dom/client\")\n\n // Check for the .default property to handle CJS/ESM interop.\n // 'hydrateRoot' will be on the module itself OR on the .default object.\n const { hydrateRoot } = reactDomClientModule.default || reactDomClientModule\n\n const emotionCache = createEmotionCache(createEmotionCacheOptions)\n\n hydrateRoot(\n document.getElementById(\"root\") as HTMLElement,\n <StrictMode>\n <App emotionCache={emotionCache} {...appProps}>\n <BrowserRouter>\n <DefaultRoutes catchAll={catchAllRoute}>{routes}</DefaultRoutes>\n </BrowserRouter>\n </App>\n </StrictMode>,\n )\n}\n"],"names":["createEmotionCache","key","prepend","otherOptions","createCache","DEFAULT_CATCH_ALL","server","App","routes","catchAllRoute","createEmotionCacheOptions","appProps","createEmotionServer","renderToString","fs","cflStyle","packageJson","render","path","emotionCache","emotionServer","html","StrictMode","jsx","StaticRouter","DefaultRoutes","emotionChunks","emotionCss","client","reactDomClientModule","hydrateRoot","BrowserRouter"],"mappings":";;;;;;;;;;;;AAwBA,SAASA,EACP;AAAA,EACE,KAAAC,IAAM;AAAA;AAAA,EACN,SAAAC,IAAU;AAAA;AAAA,EACV,GAAGC;AACL,IAAI,IACJ;AACA,SAAOC,EAAY,EAAE,KAAAH,GAAK,SAAAC,GAAS,GAAGC,GAAc;AACtD;AAWA,MAAME,IAAoD;AAE1D,eAAsBC,EAAO;AAAA,EAC3B,KAAAC;AAAA,EACA,QAAAC;AAAA,EACA,eAAAC,IAAgBJ;AAAA,EAChB,2BAAAK;AAAA,EACA,GAAGC;AACL,GAAgB;AACd,QAAM,EAAE,SAASC,MAAwB,MAAM,OAC7C,iCACF,GACM,EAAE,gBAAAC,EAAA,IAAmB,MAAM,OAAO,kBAAkB,GACpD,EAAE,SAASC,MAAO,MAAM,OAAO,kBAAkB,GAEjDC,IAAW,MAAMD,EAAG;AAAA,IACxB,kBAAkBE,EAAY,IAAI;AAAA,IAClC;AAAA,EAAA;AAGF,WAASC,EAAOC,GAAc;AAC5B,UAAMC,IAAenB,EAAmBU,CAAyB,GAC3DU,IAAgBR,EAAoBO,CAAY,GAEhDE,IAAOR;AAAA,wBACVS,GAAA,EACC,UAAA,gBAAAC,EAAChB,KAAI,cAAAY,GAA6B,GAAGR,GACnC,UAAA,gBAAAY,EAACC,GAAA,EAAa,UAAUN,GACtB,4BAACO,GAAA,EAAc,UAAUhB,GAAgB,UAAAD,EAAA,CAAO,EAAA,CAClD,GACF,EAAA,CACF;AAAA,IAAA,GAGIkB,IAAgBN,EAAc,wBAAwBC,CAAI,GAC1DM,IAAaP,EAAc,6BAA6BM,CAAa;AAE3E,WAAO;AAAA,MACL,MAAAL;AAAA,MACA,MAAM,GAAGM,CAAU,mBAAmBZ,CAAQ;AAAA,IAAA;AAAA,EAElD;AAEA,SAAO,EAAE,QAAAE,EAAA;AACX;AAEA,eAAsBW,EAAO;AAAA,EAC3B,KAAArB;AAAA,EACA,QAAAC;AAAA,EACA,eAAAC,IAAgBJ;AAAA,EAChB,2BAAAK;AAAA,EACA,GAAGC;AACL,GAAgB;AACd,QAAMkB,IAAuB,MAAM,OAAO,kBAAkB,GAItD,EAAE,aAAAC,EAAA,IAAgBD,EAAqB,WAAWA,GAElDV,IAAenB,EAAmBU,CAAyB;AAEjE,EAAAoB;AAAA,IACE,SAAS,eAAe,MAAM;AAAA,sBAC7BR,GAAA,EACC,UAAA,gBAAAC,EAAChB,GAAA,EAAI,cAAAY,GAA6B,GAAGR,GACnC,UAAA,gBAAAY,EAACQ,GAAA,EACC,UAAA,gBAAAR,EAACE,KAAc,UAAUhB,GAAgB,UAAAD,EAAA,CAAO,GAClD,GACF,EAAA,CACF;AAAA,EAAA;AAEJ;"}
@@ -1,18 +0,0 @@
1
- import { FC } from 'react';
2
- import { Options as CreateEmotionCacheOptions } from '@emotion/cache';
3
- import { DefaultRoutesProps } from './DefaultRoutes';
4
- import { AppProps } from './App';
5
- export type EntryAppProps = Pick<AppProps, "emotionCache" | "children">;
6
- export type EntryKwArgs = {
7
- App: FC<EntryAppProps>;
8
- routes: DefaultRoutesProps["children"];
9
- catchAllRoute?: DefaultRoutesProps["catchAll"];
10
- createEmotionCacheOptions?: CreateEmotionCacheOptions;
11
- };
12
- export declare function server({ App, routes, catchAllRoute, createEmotionCacheOptions, ...appProps }: EntryKwArgs): Promise<{
13
- render: (path: string) => {
14
- html: string;
15
- head: string;
16
- };
17
- }>;
18
- export declare function client({ App, routes, catchAllRoute, createEmotionCacheOptions, ...appProps }: EntryKwArgs): Promise<void>;