@gusnips/react 0.9.24 → 0.9.26

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 (116) hide show
  1. package/README.md +173 -36
  2. package/dist/api-client.d.ts +51 -51
  3. package/dist/api-client.d.ts.map +1 -1
  4. package/dist/api-client.js +3 -3
  5. package/dist/api-error.d.ts +11 -11
  6. package/dist/api-error.js +11 -11
  7. package/dist/auth-email.d.ts +40 -0
  8. package/dist/auth-email.d.ts.map +1 -0
  9. package/dist/auth-email.js +106 -0
  10. package/dist/auth-email.js.map +1 -0
  11. package/dist/auth-store.d.ts +23 -23
  12. package/dist/auth-store.js +13 -13
  13. package/dist/commands.d.ts +80 -0
  14. package/dist/commands.d.ts.map +1 -0
  15. package/dist/commands.js +192 -0
  16. package/dist/commands.js.map +1 -0
  17. package/dist/copy.d.ts +3 -3
  18. package/dist/copy.js +3 -3
  19. package/dist/deploy-recovery.d.ts +40 -40
  20. package/dist/deploy-recovery.js +40 -40
  21. package/dist/describe-error.d.ts +68 -68
  22. package/dist/describe-error.d.ts.map +1 -1
  23. package/dist/describe-error.js +5 -5
  24. package/dist/error-boundary.d.ts +12 -12
  25. package/dist/guards.d.ts +15 -15
  26. package/dist/guards.js +3 -3
  27. package/dist/hydrate.d.ts +15 -16
  28. package/dist/hydrate.d.ts.map +1 -1
  29. package/dist/hydrate.js +9 -9
  30. package/dist/hydrate.js.map +1 -1
  31. package/dist/i18n.d.ts +15 -16
  32. package/dist/i18n.d.ts.map +1 -1
  33. package/dist/i18n.js +5 -6
  34. package/dist/i18n.js.map +1 -1
  35. package/dist/index.d.ts +1 -0
  36. package/dist/index.d.ts.map +1 -1
  37. package/dist/index.js +1 -0
  38. package/dist/index.js.map +1 -1
  39. package/dist/internal-path.d.ts +8 -7
  40. package/dist/internal-path.d.ts.map +1 -1
  41. package/dist/internal-path.js +8 -7
  42. package/dist/internal-path.js.map +1 -1
  43. package/dist/prerender-contract.d.ts +7 -7
  44. package/dist/prerender-contract.js +7 -7
  45. package/dist/query.d.ts +16 -17
  46. package/dist/query.d.ts.map +1 -1
  47. package/dist/query.js +2 -2
  48. package/dist/query.js.map +1 -1
  49. package/dist/sse.d.ts +19 -20
  50. package/dist/sse.d.ts.map +1 -1
  51. package/dist/sse.js +18 -19
  52. package/dist/sse.js.map +1 -1
  53. package/dist/states.d.ts +12 -12
  54. package/dist/states.d.ts.map +1 -1
  55. package/dist/supabase-session.d.ts +47 -48
  56. package/dist/supabase-session.d.ts.map +1 -1
  57. package/dist/supabase-session.js +35 -35
  58. package/dist/supabase-session.js.map +1 -1
  59. package/dist/theme.d.ts +4 -4
  60. package/dist/theme.js +4 -4
  61. package/dist/ui/class-name.d.ts +3 -4
  62. package/dist/ui/class-name.d.ts.map +1 -1
  63. package/dist/ui/class-name.js +3 -4
  64. package/dist/ui/class-name.js.map +1 -1
  65. package/dist/ui/combobox.d.ts +11 -11
  66. package/dist/ui/combobox.d.ts.map +1 -1
  67. package/dist/ui/dialog.d.ts +5 -5
  68. package/dist/ui/dialog.js +2 -2
  69. package/dist/ui/drawer.d.ts +10 -10
  70. package/dist/ui/drawer.d.ts.map +1 -1
  71. package/dist/ui/drawer.js +2 -2
  72. package/dist/ui/input.d.ts +2 -2
  73. package/dist/ui/input.js +2 -2
  74. package/dist/ui/menu.d.ts +9 -9
  75. package/dist/ui/menu.d.ts.map +1 -1
  76. package/dist/ui/menu.js +4 -4
  77. package/dist/ui/menu.js.map +1 -1
  78. package/dist/ui/select.d.ts +12 -12
  79. package/dist/ui/select.d.ts.map +1 -1
  80. package/dist/ui/select.js +3 -3
  81. package/dist/ui/tabs.d.ts +14 -15
  82. package/dist/ui/tabs.d.ts.map +1 -1
  83. package/dist/ui/tabs.js +13 -14
  84. package/dist/ui/tabs.js.map +1 -1
  85. package/package.json +5 -1
  86. package/src/api-client.ts +51 -51
  87. package/src/api-error.ts +11 -11
  88. package/src/auth-email.test.ts +145 -0
  89. package/src/auth-email.ts +112 -0
  90. package/src/auth-store.ts +23 -23
  91. package/src/commands-hook.test.ts +444 -0
  92. package/src/commands.test.ts +245 -0
  93. package/src/commands.ts +268 -0
  94. package/src/copy.ts +3 -3
  95. package/src/deploy-recovery.ts +40 -40
  96. package/src/describe-error.ts +68 -68
  97. package/src/error-boundary.tsx +12 -12
  98. package/src/guards.tsx +15 -15
  99. package/src/hydrate.ts +15 -16
  100. package/src/i18n.ts +15 -16
  101. package/src/index.ts +2 -0
  102. package/src/internal-path.ts +8 -7
  103. package/src/prerender-contract.ts +7 -7
  104. package/src/query.ts +16 -17
  105. package/src/sse.ts +19 -20
  106. package/src/states.ts +12 -12
  107. package/src/supabase-session.ts +46 -47
  108. package/src/theme.ts +4 -4
  109. package/src/ui/class-name.ts +3 -4
  110. package/src/ui/combobox.tsx +11 -11
  111. package/src/ui/dialog.tsx +5 -5
  112. package/src/ui/drawer.tsx +10 -10
  113. package/src/ui/input.tsx +2 -2
  114. package/src/ui/menu.tsx +8 -8
  115. package/src/ui/select.tsx +12 -12
  116. package/src/ui/tabs.tsx +14 -15
@@ -2,27 +2,27 @@ import { Component, type ErrorInfo, type ReactNode } from "react";
2
2
  /**
3
3
  * The last stop before a white screen.
4
4
  *
5
- * React unmounts the whole tree when a render throws, and an app with no boundary anywhere
6
- * answers that with a blank page: no words, no navigation, no reload — the most complete dead
7
- * end a product can produce, and the one the never-dead-end rule cannot reach, because by then
8
- * there is no component left to render a state from.
5
+ * React unmounts the whole tree when a render throws, and an app with no boundary anywhere answers
6
+ * that with a blank page: no words, no navigation, no reload. That is the most complete dead end a
7
+ * product can produce, and the one the never-dead-end rule cannot reach, because by then there is
8
+ * no component left to render a state from.
9
9
  *
10
10
  * It is deliberately dumb. No retry loop, no error reporting, no reset on a timer: it catches,
11
11
  * it hands the error to a `fallback` the app draws in its own words, and it offers `reset`.
12
12
  * Every donor that baked its own UI in here had to keep a second copy for its second surface;
13
13
  * a render prop has no such problem, and the brand stays in the product where it belongs.
14
14
  *
15
- * A class, because `getDerivedStateFromError` has no hook equivalent — this is the one thing in
16
- * the kit React still has no other way to express.
15
+ * A class, because `getDerivedStateFromError` has no hook equivalent. This is the one thing in the
16
+ * kit React still has no other way to express.
17
17
  */
18
18
  export interface ErrorBoundaryFallbackProps {
19
19
  error: Error;
20
20
  /** Put the children back. */
21
21
  reset: () => void;
22
22
  /**
23
- * True when the throw was a failed lazy-chunk import — a deploy landed while this tab was
24
- * open, so the fix is a reload and NOT a retry (a rejected dynamic import rethrows on
25
- * re-render forever). Draw the "updating" screen, not the crash screen.
23
+ * True when the throw was a failed lazy-chunk import because a deploy landed while this tab was
24
+ * open, so the fix is a reload and NOT a retry (a rejected dynamic import rethrows on re-render
25
+ * forever). Draw the "updating" screen, not the crash screen.
26
26
  */
27
27
  isChunkError: boolean;
28
28
  }
@@ -30,9 +30,9 @@ export interface ErrorBoundaryProps {
30
30
  /** Drawn instead of the children once something has thrown. */
31
31
  fallback: (props: ErrorBoundaryFallbackProps) => ReactNode;
32
32
  /**
33
- * Changing this value clears the error and remounts the children — pass the route, so
34
- * navigating away from a screen that broke actually leaves it rather than carrying its
35
- * wreckage to every page after it.
33
+ * Changing this value clears the error and remounts the children. Pass the route, so navigating
34
+ * away from a screen that broke actually leaves it rather than carrying its wreckage to every
35
+ * page after it.
36
36
  */
37
37
  resetKey?: string;
38
38
  /** Called once per catch. Report to whatever the app reports to. */
package/dist/guards.d.ts CHANGED
@@ -2,9 +2,9 @@ import type { ReactNode } from "react";
2
2
  /**
3
3
  * Route guards.
4
4
  *
5
- * Two donors wrote these four, gave two of them the same names, and explained them in nearly
6
- * the same words. What differed was one line — and that line is invariant 4, so it is the
7
- * reason this file exists rather than being copied a ninth time.
5
+ * Two donors wrote these four, gave two of them the same names, and explained them in nearly the
6
+ * same words. What differed was one line. That line is invariant 4, so it is the reason this file
7
+ * exists rather than being copied a ninth time.
8
8
  *
9
9
  * These are factories because the destinations are the app's: `paths.signIn` is not something a
10
10
  * package can know, and one donor hardcoded `/login` in four places for exactly that reason.
@@ -21,18 +21,18 @@ export interface SessionState {
21
21
  /**
22
22
  * The answer to a "who is this?" query, in the three states it actually has.
23
23
  *
24
- * This shape is invariant 4. A guard reading `!me?.isStaff` collapses "pending", "failed" and
25
- * "no" into one branch — so an operator arriving while `/auth/me` is 500ing is told the page
26
- * does not exist. Wrong cause, no retry, and no request id to quote to support. One donor hit
27
- * that and fixed it; the other still has the collapsed version.
24
+ * This shape is invariant 4. A guard reading `!me?.isStaff` collapses "pending", "failed" and "no"
25
+ * into one branch, so an operator arriving while `/auth/me` is 500ing is told the page does not
26
+ * exist. Wrong cause, no retry, and no request id to quote to support. One donor hit that and fixed
27
+ * it; the other still has the collapsed version.
28
28
  *
29
29
  * `"pending"` and not `"loading"` for one measured reason: it is react-query's own word for this
30
30
  * state since v5, and with the words matching a `UseQueryResult<TMe>` satisfies this type
31
- * STRUCTURALLY — `createRequireProfile(useMe, …)` takes the hook directly, no adapter. With
32
- * `"loading"` it does not typecheck and every adopter hand-writes the same six-line mapping;
33
- * eight of the twelve repos this serves are on react-query, and the first migration wrote that
34
- * mapping before anyone noticed. Nothing here imports react-query at runtime — the type stays
35
- * structural, so an app on SWR or a plain `useState` still answers it in three lines.
31
+ * STRUCTURALLY: `createRequireProfile(useMe, …)` takes the hook directly, no adapter. With
32
+ * `"loading"` it does not typecheck and every adopter hand-writes the same six-line mapping; eight
33
+ * of the twelve repos this serves are on react-query, and the first migration wrote that mapping
34
+ * before anyone noticed. Nothing here imports react-query at runtime. The type stays structural, so
35
+ * an app on SWR or a plain `useState` still answers it in three lines.
36
36
  */
37
37
  export type MeQuery<TMe> = {
38
38
  status: "pending";
@@ -50,8 +50,8 @@ export interface GuardOptions {
50
50
  /** Query parameter carrying the route a sign-in interrupted. */
51
51
  export declare const AUTH_RETURN_PARAM = "next";
52
52
  /**
53
- * Signed in, or off to sign in — remembering where they were headed, so the redirect afterwards
54
- * lands on the page they actually wanted rather than the home screen.
53
+ * Require sign-in and remember where they were headed, so the redirect afterwards lands on the page
54
+ * they actually wanted rather than the home screen.
55
55
  */
56
56
  export declare function createRequireAuth(useSession: () => SessionState, signInPath: string, { loading }: GuardOptions): ({ children }: {
57
57
  children: ReactNode;
@@ -61,7 +61,7 @@ export declare function createRequireAnonymous(useSession: () => SessionState, h
61
61
  children: ReactNode;
62
62
  }) => import("react").JSX.Element;
63
63
  /**
64
- * A gate on something the profile says — suspended, staff, on a given plan.
64
+ * A gate on a profile field, such as whether the person is suspended, staff or on a given plan.
65
65
  *
66
66
  * `allow` gets the profile and answers yes or no. `onDenied` draws the refusal; `onError` draws
67
67
  * the failure, and they are SEPARATE arguments on purpose. That separation is the whole point
package/dist/guards.js CHANGED
@@ -8,8 +8,8 @@ function signInUrl(signInPath, returnTo) {
8
8
  return `${signInPath}${separator}${AUTH_RETURN_PARAM}=${encodeURIComponent(returnTo)}`;
9
9
  }
10
10
  /**
11
- * Signed in, or off to sign in — remembering where they were headed, so the redirect afterwards
12
- * lands on the page they actually wanted rather than the home screen.
11
+ * Require sign-in and remember where they were headed, so the redirect afterwards lands on the page
12
+ * they actually wanted rather than the home screen.
13
13
  */
14
14
  export function createRequireAuth(useSession, signInPath, { loading }) {
15
15
  return function RequireAuth({ children }) {
@@ -46,7 +46,7 @@ export function createRequireAnonymous(useSession, homePath, { loading }) {
46
46
  };
47
47
  }
48
48
  /**
49
- * A gate on something the profile says — suspended, staff, on a given plan.
49
+ * A gate on a profile field, such as whether the person is suspended, staff or on a given plan.
50
50
  *
51
51
  * `allow` gets the profile and answers yes or no. `onDenied` draws the refusal; `onError` draws
52
52
  * the failure, and they are SEPARATE arguments on purpose. That separation is the whole point
package/dist/hydrate.d.ts CHANGED
@@ -1,18 +1,17 @@
1
1
  /**
2
2
  * The browser half of prerendering: deciding whether to hydrate or to mount fresh.
3
3
  *
4
- * Three separate repos invented all of this independently — same constant name, same string
5
- * value, same decision, and near-identical explaining comments. That is not a coincidence worth
6
- * deduping; it is one lesson learned three times, and it belongs somewhere it can be learned
7
- * once.
4
+ * Three separate repos invented all of this independently, with the same constant name, string
5
+ * value and decision, and near-identical explaining comments. That is not a coincidence worth
6
+ * deduping; it is one lesson learned three times, and it belongs somewhere it can be learned once.
8
7
  *
9
8
  * The constants themselves live in `prerender-contract.ts`, which imports nothing, because the
10
9
  * BUILD needs them too and must not pull `react-dom/client` into a Node process to get a string.
11
10
  *
12
11
  * This module sits behind `@gusnips/react/hydrate` rather than in the barrel for the same reason
13
- * one rung further out: it is the package's ONLY `react-dom` import, and a React Native app has
14
- * no react-dom to give. Leaving it in the barrel made `react-dom` a required peer and shut the
15
- * whole package out of every phone — for one function a phone would never call.
12
+ * one rung further out: it is the package's ONLY `react-dom` import, and a React Native app has no
13
+ * react-dom to give. Leaving it in the barrel made `react-dom` a required peer and shut the whole
14
+ * package out of every phone for one function a phone would never call.
16
15
  */
17
16
  import type { ReactNode } from "react";
18
17
  export { PRERENDERED_ROUTE_ATTR, SHELL_ROUTE } from "./prerender-contract.ts";
@@ -20,16 +19,16 @@ export { PRERENDERED_ROUTE_ATTR, SHELL_ROUTE } from "./prerender-contract.ts";
20
19
  * Hydrate the render this file IS, and mount fresh over anything else.
21
20
  *
22
21
  * "Does the root have children" is the wrong question, and getting it wrong is silent. A static
23
- * host answers every address it does not publish with the nearest `404.html` — and that file has
24
- * the not-found page rendered INTO it — so an address served from a shell arrives at a full root
25
- * holding somebody else's markup. Hydrating that is React reconciling two different pages: it
26
- * recovers by throwing the whole tree away and says so in the console, which is a page that
27
- * works and a bug nobody sees. The file names the route it is a render of, so we can simply ask.
22
+ * host answers every address it does not publish with the nearest `404.html`, which has the
23
+ * not-found page rendered INTO it. An address served from a shell arrives at a full root holding
24
+ * somebody else's markup. Hydrating that is React reconciling two different pages: it recovers by
25
+ * throwing the whole tree away and says so in the console, which is a page that works and a bug
26
+ * nobody sees. The file names the route it is a render of, so we can simply ask.
28
27
  *
29
- * `route` is passed in rather than read from `window.location` on purpose. A localized app
30
- * serves `/pt/pricing` from a file rendered for `/pricing`, with the locale carried in the
31
- * router's `basename` — so the address and the route are different strings, and only the caller
32
- * knows which one the build wrote.
28
+ * `route` is passed in rather than read from `window.location` on purpose. A localized app serves
29
+ * `/pt/pricing` from a file rendered for `/pricing`, with the locale carried in the router's
30
+ * `basename`, so the address and the route are different strings, and only the caller knows which
31
+ * one the build wrote.
33
32
  *
34
33
  * **A trailing slash is not a different page.** The router renders `/precos/` and `/precos` alike,
35
34
  * and which one is in the address bar is the host's call: a host serving `precos/index.html`
@@ -1 +1 @@
1
- {"version":3,"file":"hydrate.d.ts","sourceRoot":"","sources":["../src/hydrate.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AACH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAIvC,OAAO,EAAE,sBAAsB,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAE9E;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI,CAI3F"}
1
+ {"version":3,"file":"hydrate.d.ts","sourceRoot":"","sources":["../src/hydrate.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AACH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAIvC,OAAO,EAAE,sBAAsB,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAE9E;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI,CAI3F"}
package/dist/hydrate.js CHANGED
@@ -5,16 +5,16 @@ export { PRERENDERED_ROUTE_ATTR, SHELL_ROUTE } from "./prerender-contract.js";
5
5
  * Hydrate the render this file IS, and mount fresh over anything else.
6
6
  *
7
7
  * "Does the root have children" is the wrong question, and getting it wrong is silent. A static
8
- * host answers every address it does not publish with the nearest `404.html` — and that file has
9
- * the not-found page rendered INTO it — so an address served from a shell arrives at a full root
10
- * holding somebody else's markup. Hydrating that is React reconciling two different pages: it
11
- * recovers by throwing the whole tree away and says so in the console, which is a page that
12
- * works and a bug nobody sees. The file names the route it is a render of, so we can simply ask.
8
+ * host answers every address it does not publish with the nearest `404.html`, which has the
9
+ * not-found page rendered INTO it. An address served from a shell arrives at a full root holding
10
+ * somebody else's markup. Hydrating that is React reconciling two different pages: it recovers by
11
+ * throwing the whole tree away and says so in the console, which is a page that works and a bug
12
+ * nobody sees. The file names the route it is a render of, so we can simply ask.
13
13
  *
14
- * `route` is passed in rather than read from `window.location` on purpose. A localized app
15
- * serves `/pt/pricing` from a file rendered for `/pricing`, with the locale carried in the
16
- * router's `basename` — so the address and the route are different strings, and only the caller
17
- * knows which one the build wrote.
14
+ * `route` is passed in rather than read from `window.location` on purpose. A localized app serves
15
+ * `/pt/pricing` from a file rendered for `/pricing`, with the locale carried in the router's
16
+ * `basename`, so the address and the route are different strings, and only the caller knows which
17
+ * one the build wrote.
18
18
  *
19
19
  * **A trailing slash is not a different page.** The router renders `/precos/` and `/precos` alike,
20
20
  * and which one is in the address bar is the host's call: a host serving `precos/index.html`
@@ -1 +1 @@
1
- {"version":3,"file":"hydrate.js","sourceRoot":"","sources":["../src/hydrate.ts"],"names":[],"mappings":"AAiBA,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC3D,OAAO,EAAE,sBAAsB,EAAE,MAAM,yBAAyB,CAAC;AAEjE,OAAO,EAAE,sBAAsB,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAE9E;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,MAAM,UAAU,cAAc,CAAC,MAAe,EAAE,IAAe,EAAE,KAAoB;IACnF,MAAM,QAAQ,GAAG,MAAM,CAAC,YAAY,CAAC,sBAAsB,CAAC,CAAC;IAC7D,IAAI,KAAK,KAAK,IAAI,IAAI,QAAQ,KAAK,IAAI,IAAI,QAAQ,CAAC,QAAQ,EAAE,KAAK,CAAC;QAAE,WAAW,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;;QAC3F,UAAU,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;AACvC,CAAC;AAED,4DAA4D;AAC5D,SAAS,QAAQ,CAAC,CAAS,EAAE,CAAS;IACpC,MAAM,IAAI,GAAG,CAAC,IAAY,EAAU,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;IACrE,OAAO,IAAI,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,CAAC,CAAC;AAC7B,CAAC"}
1
+ {"version":3,"file":"hydrate.js","sourceRoot":"","sources":["../src/hydrate.ts"],"names":[],"mappings":"AAgBA,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC3D,OAAO,EAAE,sBAAsB,EAAE,MAAM,yBAAyB,CAAC;AAEjE,OAAO,EAAE,sBAAsB,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAE9E;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,MAAM,UAAU,cAAc,CAAC,MAAe,EAAE,IAAe,EAAE,KAAoB;IACnF,MAAM,QAAQ,GAAG,MAAM,CAAC,YAAY,CAAC,sBAAsB,CAAC,CAAC;IAC7D,IAAI,KAAK,KAAK,IAAI,IAAI,QAAQ,KAAK,IAAI,IAAI,QAAQ,CAAC,QAAQ,EAAE,KAAK,CAAC;QAAE,WAAW,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;;QAC3F,UAAU,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;AACvC,CAAC;AAED,4DAA4D;AAC5D,SAAS,QAAQ,CAAC,CAAS,EAAE,CAAS;IACpC,MAAM,IAAI,GAAG,CAAC,IAAY,EAAU,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;IACrE,OAAO,IAAI,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,CAAC,CAAC;AAC7B,CAAC"}
package/dist/i18n.d.ts CHANGED
@@ -8,8 +8,7 @@
8
8
  * ```
9
9
  *
10
10
  * Keeping the options here is what stops a console, a storefront and a docs site in the same
11
- * product from drifting apart on the details below — each of which is a bug somebody already
12
- * shipped.
11
+ * product from drifting apart on the details below. Each is a bug somebody already shipped.
13
12
  */
14
13
  export interface I18nInitOptions {
15
14
  /** The language everything falls back to. */
@@ -27,10 +26,10 @@ export interface I18nInitOptions {
27
26
  /**
28
27
  * The query parameter that hands a language ACROSS an origin, e.g. `"lang"`.
29
28
  *
30
- * When set it is detected FIRST, ahead of storage and the browser — it is the only one of the
29
+ * When set it is detected FIRST, ahead of storage and the browser. It is the only one of the
31
30
  * three that somebody chose on purpose and just now. A reader who picked Português on the
32
- * storefront and followed a link into the app means it more than their laptop's locale does.
33
- * It is cached on arrival, so it decides once and no URL inside the app has to carry it.
31
+ * storefront and followed a link into the app means it more than their laptop's locale does. It
32
+ * is cached on arrival, so it decides once and no URL inside the app has to carry it.
34
33
  *
35
34
  * Only one donor had this. The other has the same split-origin layout and the same problem.
36
35
  */
@@ -38,15 +37,15 @@ export interface I18nInitOptions {
38
37
  /**
39
38
  * Who WRITES {@link storageKey}. The detector, by default.
40
39
  *
41
- * Pass `"app"` when your own language control writes it. That is not a preference — it is what
42
- * a "follow the browser" option costs. Going back to following the browser means clearing the
43
- * key and calling `changeLanguage(undefined)`, which re-runs detection; a detector that caches
44
- * then writes the language it just detected straight back into the key it was told to clear.
45
- * The choice re-pins itself and nothing can reach that state again.
40
+ * Pass `"app"` when your own language control writes it. A "follow the browser" option needs
41
+ * this. Going back to following the browser means clearing the key and calling
42
+ * `changeLanguage(undefined)`, which re-runs detection; a detector that caches then writes the
43
+ * language it just detected straight back into the key it was told to clear. The choice re-pins
44
+ * itself and nothing can reach that state again.
46
45
  *
47
46
  * Three repos on this stack, three answers: one lets the detector write, one writes it from its
48
- * own control, and one does both — harmless there only because it offers no "follow the
49
- * browser" state. So the rule, rather than the default: one writer per key.
47
+ * own control, and one does both. Doing both is harmless there only because it offers no "follow
48
+ * the browser" state. So the rule, rather than the default: one writer per key.
50
49
  */
51
50
  storageWriter?: "detector" | "app";
52
51
  }
@@ -73,13 +72,13 @@ export declare function i18nInitOptions({ fallbackLng, supportedLngs, storageKey
73
72
  * i18next ever sees it.
74
73
  *
75
74
  * Done here rather than through interpolation because i18next v26 has no global interpolation
76
- * defaults, and these strings are often resolved by dynamic key — so a wrapping `t()` would not
75
+ * defaults, and these strings are often resolved by dynamic key, so a wrapping `t()` would not
77
76
  * reach them. The point is that a rename or a domain move is ONE edit in the brand constants
78
77
  * instead of a sweep across every locale file.
79
78
  *
80
- * Returns a fresh tree; the input is untouched. The placeholder names come from `vars`, so
81
- * adding one needs no change here — two donors hardcoded their own list in the regex and both
82
- * had to remember to update it.
79
+ * Returns a fresh tree; the input is untouched. The placeholder names come from `vars`, so adding
80
+ * one needs no change here. Two donors hardcoded their own list in the regex and both had to
81
+ * remember to update it.
83
82
  */
84
83
  export declare function applyBrandVars<T>(resources: T, vars: Record<string, string>): T;
85
84
  //# sourceMappingURL=i18n.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"i18n.d.ts","sourceRoot":"","sources":["../src/i18n.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,MAAM,WAAW,eAAe;IAC9B,6CAA6C;IAC7C,WAAW,EAAE,MAAM,CAAC;IACpB,6EAA6E;IAC7E,aAAa,EAAE,SAAS,MAAM,EAAE,CAAC;IACjC;;;;;;OAMG;IACH,UAAU,EAAE,MAAM,CAAC;IACnB;;;;;;;;;OASG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;;;;;;;;;;;OAYG;IACH,aAAa,CAAC,EAAE,UAAU,GAAG,KAAK,CAAC;CACpC;AAED,wBAAgB,eAAe,CAAC,EAC9B,WAAW,EACX,aAAa,EACb,UAAU,EACV,QAAQ,EACR,aAA0B,GAC3B,EAAE,eAAe;;;;;;;;;uCAOK,MAAM,KAAG,MAAM;;;;;;;;EAkCrC;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,cAAc,CAAC,CAAC,EAAE,SAAS,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,CAAC,CAmB/E"}
1
+ {"version":3,"file":"i18n.d.ts","sourceRoot":"","sources":["../src/i18n.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,MAAM,WAAW,eAAe;IAC9B,6CAA6C;IAC7C,WAAW,EAAE,MAAM,CAAC;IACpB,6EAA6E;IAC7E,aAAa,EAAE,SAAS,MAAM,EAAE,CAAC;IACjC;;;;;;OAMG;IACH,UAAU,EAAE,MAAM,CAAC;IACnB;;;;;;;;;OASG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;;;;;;;;;;;OAYG;IACH,aAAa,CAAC,EAAE,UAAU,GAAG,KAAK,CAAC;CACpC;AAED,wBAAgB,eAAe,CAAC,EAC9B,WAAW,EACX,aAAa,EACb,UAAU,EACV,QAAQ,EACR,aAA0B,GAC3B,EAAE,eAAe;;;;;;;;;uCAOK,MAAM,KAAG,MAAM;;;;;;;;EAkCrC;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,cAAc,CAAC,CAAC,EAAE,SAAS,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,CAAC,CAmB/E"}
package/dist/i18n.js CHANGED
@@ -8,8 +8,7 @@
8
8
  * ```
9
9
  *
10
10
  * Keeping the options here is what stops a console, a storefront and a docs site in the same
11
- * product from drifting apart on the details below — each of which is a bug somebody already
12
- * shipped.
11
+ * product from drifting apart on the details below. Each is a bug somebody already shipped.
13
12
  */
14
13
  export function i18nInitOptions({ fallbackLng, supportedLngs, storageKey, queryKey, storageWriter = "detector", }) {
15
14
  // i18next picks the first EXACT match anywhere in the detected list before it tries a base
@@ -55,13 +54,13 @@ export function i18nInitOptions({ fallbackLng, supportedLngs, storageKey, queryK
55
54
  * i18next ever sees it.
56
55
  *
57
56
  * Done here rather than through interpolation because i18next v26 has no global interpolation
58
- * defaults, and these strings are often resolved by dynamic key — so a wrapping `t()` would not
57
+ * defaults, and these strings are often resolved by dynamic key, so a wrapping `t()` would not
59
58
  * reach them. The point is that a rename or a domain move is ONE edit in the brand constants
60
59
  * instead of a sweep across every locale file.
61
60
  *
62
- * Returns a fresh tree; the input is untouched. The placeholder names come from `vars`, so
63
- * adding one needs no change here — two donors hardcoded their own list in the regex and both
64
- * had to remember to update it.
61
+ * Returns a fresh tree; the input is untouched. The placeholder names come from `vars`, so adding
62
+ * one needs no change here. Two donors hardcoded their own list in the regex and both had to
63
+ * remember to update it.
65
64
  */
66
65
  export function applyBrandVars(resources, vars) {
67
66
  const names = Object.keys(vars);
package/dist/i18n.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"i18n.js","sourceRoot":"","sources":["../src/i18n.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"i18n.js","sourceRoot":"","sources":["../src/i18n.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AA0CH,MAAM,UAAU,eAAe,CAAC,EAC9B,WAAW,EACX,aAAa,EACb,UAAU,EACV,QAAQ,EACR,aAAa,GAAG,UAAU,GACV;IAChB,2FAA2F;IAC3F,+FAA+F;IAC/F,iGAAiG;IACjG,gGAAgG;IAChG,iGAAiG;IACjG,+CAA+C;IAC/C,MAAM,MAAM,GAAG,CAAC,GAAW,EAAU,EAAE;QACrC,MAAM,KAAK,GAAG,GAAG,CAAC,WAAW,EAAE,CAAC;QAChC,MAAM,IAAI,GAAG,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;QACjC,OAAO,CACL,aAAa,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,WAAW,EAAE,KAAK,KAAK,CAAC;YACxD,aAAa,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,KAAK,IAAI,CAAC;YACtE,GAAG,CACJ,CAAC;IACJ,CAAC,CAAC;IAEF,OAAO;QACL,WAAW;QACX,aAAa,EAAE,CAAC,GAAG,aAAa,CAAC;QACjC,IAAI,EAAE,aAAsB;QAC5B,aAAa,EAAE,EAAE,WAAW,EAAE,KAAK,EAAE,EAAE,yBAAyB;QAChE,SAAS,EAAE;YACT,KAAK,EAAE,QAAQ;gBACb,CAAC,CAAC,CAAC,aAAa,EAAE,cAAc,EAAE,WAAW,CAAC;gBAC9C,CAAC,CAAC,CAAC,cAAc,EAAE,WAAW,CAAC;YACjC,8EAA8E;YAC9E,MAAM,EAAE,aAAa,KAAK,UAAU,CAAC,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,EAAE;YAC5D,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,iBAAiB,EAAE,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACpD,kBAAkB,EAAE,UAAU;YAC9B,uBAAuB,EAAE,MAAM;SAChC;QACD,KAAK,EAAE,EAAE,WAAW,EAAE,KAAK,EAAE;QAC7B,gGAAgG;QAChG,4FAA4F;QAC5F,4FAA4F;QAC5F,sFAAsF;QACtF,wFAAwF;QACxF,2FAA2F;QAC3F,8FAA8F;KAC/F,CAAC;AACJ,CAAC;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,cAAc,CAAI,SAAY,EAAE,IAA4B;IAC1E,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAChC,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,SAAS,CAAC;IACzC,MAAM,OAAO,GAAG,IAAI,MAAM,CACxB,UAAU,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,qBAAqB,EAAE,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,SAAS,EACvF,GAAG,CACJ,CAAC;IAEF,MAAM,IAAI,GAAG,CAAC,CAAS,EAAU,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC,EAAE,IAAY,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;IAE9F,MAAM,IAAI,GAAG,CAAC,KAAc,EAAW,EAAE;QACvC,IAAI,OAAO,KAAK,KAAK,QAAQ;YAAE,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC;QAClD,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;YAAE,OAAO,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QACjD,IAAI,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ;YACpC,OAAO,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QACjF,OAAO,KAAK,CAAC;IACf,CAAC,CAAC;IAEF,OAAO,IAAI,CAAC,SAAS,CAAM,CAAC;AAC9B,CAAC"}
package/dist/index.d.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  export { cn } from "./cn.ts";
2
2
  export { copyText, useCopy, type CopyOptions, type CopyState } from "./copy.ts";
3
3
  export { returnPathFromLocation, safeInternalPath, type PathParts } from "./internal-path.ts";
4
+ export { forgetAuthEmail, recallAuthEmail, rememberAuthEmail } from "./auth-email.ts";
4
5
  export { ApiError, isAbortError } from "./api-error.ts";
5
6
  export { retryAfterSecs } from "@gusnips/http/retry";
6
7
  export { createApiClient, type ApiClient, type ApiClientOptions, type RefreshResult, type RequestOptions, type SessionAdapter, } from "./api-client.ts";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAgCA,OAAO,EAAE,EAAE,EAAE,MAAM,SAAS,CAAC;AAC7B,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,KAAK,WAAW,EAAE,KAAK,SAAS,EAAE,MAAM,WAAW,CAAC;AAChF,OAAO,EAAE,sBAAsB,EAAE,gBAAgB,EAAE,KAAK,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAE9F,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AACxD,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,EACL,eAAe,EACf,KAAK,SAAS,EACd,KAAK,gBAAgB,EACrB,KAAK,aAAa,EAClB,KAAK,cAAc,EACnB,KAAK,cAAc,GACpB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,eAAe,EAAE,aAAa,EAAE,KAAK,QAAQ,EAAE,MAAM,UAAU,CAAC;AAEzE,OAAO,EACL,aAAa,EACb,SAAS,EACT,YAAY,EACZ,WAAW,EACX,KAAK,oBAAoB,EACzB,KAAK,SAAS,GACf,MAAM,YAAY,CAAC;AAEpB,OAAO,EACL,aAAa,EACb,KAAK,0BAA0B,EAC/B,KAAK,kBAAkB,GACxB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EACL,oBAAoB,EACpB,YAAY,EACZ,KAAK,cAAc,EACnB,KAAK,QAAQ,EACb,KAAK,YAAY,EACjB,KAAK,SAAS,EACd,KAAK,qBAAqB,EAC1B,KAAK,2BAA2B,EAChC,KAAK,YAAY,EACjB,KAAK,SAAS,GACf,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EACL,0BAA0B,EAC1B,gBAAgB,EAChB,oBAAoB,EACpB,YAAY,EACZ,gBAAgB,EAChB,UAAU,GACX,MAAM,sBAAsB,CAAC;AAK9B,OAAO,EAAE,sBAAsB,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAE9E,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,KAAK,eAAe,EAAE,MAAM,WAAW,CAAC;AAElF,YAAY,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAgCA,OAAO,EAAE,EAAE,EAAE,MAAM,SAAS,CAAC;AAC7B,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,KAAK,WAAW,EAAE,KAAK,SAAS,EAAE,MAAM,WAAW,CAAC;AAChF,OAAO,EAAE,sBAAsB,EAAE,gBAAgB,EAAE,KAAK,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAE9F,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AAEtF,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AACxD,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,EACL,eAAe,EACf,KAAK,SAAS,EACd,KAAK,gBAAgB,EACrB,KAAK,aAAa,EAClB,KAAK,cAAc,EACnB,KAAK,cAAc,GACpB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,eAAe,EAAE,aAAa,EAAE,KAAK,QAAQ,EAAE,MAAM,UAAU,CAAC;AAEzE,OAAO,EACL,aAAa,EACb,SAAS,EACT,YAAY,EACZ,WAAW,EACX,KAAK,oBAAoB,EACzB,KAAK,SAAS,GACf,MAAM,YAAY,CAAC;AAEpB,OAAO,EACL,aAAa,EACb,KAAK,0BAA0B,EAC/B,KAAK,kBAAkB,GACxB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EACL,oBAAoB,EACpB,YAAY,EACZ,KAAK,cAAc,EACnB,KAAK,QAAQ,EACb,KAAK,YAAY,EACjB,KAAK,SAAS,EACd,KAAK,qBAAqB,EAC1B,KAAK,2BAA2B,EAChC,KAAK,YAAY,EACjB,KAAK,SAAS,GACf,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EACL,0BAA0B,EAC1B,gBAAgB,EAChB,oBAAoB,EACpB,YAAY,EACZ,gBAAgB,EAChB,UAAU,GACX,MAAM,sBAAsB,CAAC;AAK9B,OAAO,EAAE,sBAAsB,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAE9E,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,KAAK,eAAe,EAAE,MAAM,WAAW,CAAC;AAElF,YAAY,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC"}
package/dist/index.js CHANGED
@@ -32,6 +32,7 @@
32
32
  export { cn } from "./cn.js";
33
33
  export { copyText, useCopy } from "./copy.js";
34
34
  export { returnPathFromLocation, safeInternalPath } from "./internal-path.js";
35
+ export { forgetAuthEmail, recallAuthEmail, rememberAuthEmail } from "./auth-email.js";
35
36
  export { ApiError, isAbortError } from "./api-error.js";
36
37
  export { retryAfterSecs } from "@gusnips/http/retry";
37
38
  export { createApiClient, } from "./api-client.js";
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,kEAAkE;AAClE,EAAE;AACF,2CAA2C;AAC3C,EAAE;AACF,+FAA+F;AAC/F,gGAAgG;AAChG,+FAA+F;AAC/F,iGAAiG;AACjG,0BAA0B;AAC1B,EAAE;AACF,qEAAqE;AACrE,8DAA8D;AAC9D,uEAAuE;AACvE,gEAAgE;AAChE,4EAA4E;AAC5E,4FAA4F;AAC5F,8FAA8F;AAC9F,EAAE;AACF,2FAA2F;AAC3F,iGAAiG;AACjG,+FAA+F;AAC/F,gGAAgG;AAChG,4EAA4E;AAC5E,EAAE;AACF,2FAA2F;AAC3F,iGAAiG;AACjG,qFAAqF;AACrF,6FAA6F;AAC7F,iGAAiG;AACjG,yFAAyF;AACzF,uBAAuB;AAEvB,OAAO,EAAE,EAAE,EAAE,MAAM,SAAS,CAAC;AAC7B,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAoC,MAAM,WAAW,CAAC;AAChF,OAAO,EAAE,sBAAsB,EAAE,gBAAgB,EAAkB,MAAM,oBAAoB,CAAC;AAE9F,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AACxD,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,EACL,eAAe,GAMhB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,eAAe,EAAE,aAAa,EAAiB,MAAM,UAAU,CAAC;AAEzE,OAAO,EACL,aAAa,EACb,SAAS,EACT,YAAY,EACZ,WAAW,GAGZ,MAAM,YAAY,CAAC;AAEpB,OAAO,EACL,aAAa,GAGd,MAAM,qBAAsB,CAAC;AAC9B,OAAO,EACL,oBAAoB,EACpB,YAAY,GASb,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EACL,0BAA0B,EAC1B,gBAAgB,EAChB,oBAAoB,EACpB,YAAY,EACZ,gBAAgB,EAChB,UAAU,GACX,MAAM,sBAAsB,CAAC;AAE9B,iGAAiG;AACjG,kGAAkG;AAClG,6FAA6F;AAC7F,OAAO,EAAE,sBAAsB,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAE9E,OAAO,EAAE,cAAc,EAAE,eAAe,EAAwB,MAAM,WAAW,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,kEAAkE;AAClE,EAAE;AACF,2CAA2C;AAC3C,EAAE;AACF,+FAA+F;AAC/F,gGAAgG;AAChG,+FAA+F;AAC/F,iGAAiG;AACjG,0BAA0B;AAC1B,EAAE;AACF,qEAAqE;AACrE,8DAA8D;AAC9D,uEAAuE;AACvE,gEAAgE;AAChE,4EAA4E;AAC5E,4FAA4F;AAC5F,8FAA8F;AAC9F,EAAE;AACF,2FAA2F;AAC3F,iGAAiG;AACjG,+FAA+F;AAC/F,gGAAgG;AAChG,4EAA4E;AAC5E,EAAE;AACF,2FAA2F;AAC3F,iGAAiG;AACjG,qFAAqF;AACrF,6FAA6F;AAC7F,iGAAiG;AACjG,yFAAyF;AACzF,uBAAuB;AAEvB,OAAO,EAAE,EAAE,EAAE,MAAM,SAAS,CAAC;AAC7B,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAoC,MAAM,WAAW,CAAC;AAChF,OAAO,EAAE,sBAAsB,EAAE,gBAAgB,EAAkB,MAAM,oBAAoB,CAAC;AAE9F,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AAEtF,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AACxD,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,EACL,eAAe,GAMhB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,eAAe,EAAE,aAAa,EAAiB,MAAM,UAAU,CAAC;AAEzE,OAAO,EACL,aAAa,EACb,SAAS,EACT,YAAY,EACZ,WAAW,GAGZ,MAAM,YAAY,CAAC;AAEpB,OAAO,EACL,aAAa,GAGd,MAAM,qBAAsB,CAAC;AAC9B,OAAO,EACL,oBAAoB,EACpB,YAAY,GASb,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EACL,0BAA0B,EAC1B,gBAAgB,EAChB,oBAAoB,EACpB,YAAY,EACZ,gBAAgB,EAChB,UAAU,GACX,MAAM,sBAAsB,CAAC;AAE9B,iGAAiG;AACjG,kGAAkG;AAClG,6FAA6F;AAC7F,OAAO,EAAE,sBAAsB,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAE9E,OAAO,EAAE,cAAc,EAAE,eAAe,EAAwB,MAAM,WAAW,CAAC"}
@@ -2,9 +2,9 @@
2
2
  * A route the browser can follow without leaving the current origin.
3
3
  *
4
4
  * Return targets cross a trust boundary: query strings, history state and storage are all writable
5
- * by somebody outside the app. `startsWith("/")` is not enough — URL parsers read both `//host`
6
- * and `/\\host` as another origin, and strip tabs or newlines before making the same decision.
7
- * Parsing against a fixed origin applies the browser's own rules rather than trying to copy them.
5
+ * by somebody outside the app. `startsWith("/")` is not enough: URL parsers read both `//host` and
6
+ * `/\\host` as another origin, and strip tabs or newlines before making the same decision. Parsing
7
+ * against a fixed origin applies the browser's own rules rather than trying to copy them.
8
8
  */
9
9
  export declare function safeInternalPath(value: unknown): string | null;
10
10
  /** Anything shaped like the current page: `window.location` and react-router's `useLocation()`. */
@@ -18,14 +18,15 @@ export interface PathParts {
18
18
  *
19
19
  * The fragment is the half that is easy to get wrong, and getting it wrong leaks a credential. A
20
20
  * Supabase client with no `flowType` uses the IMPLICIT flow, which returns the session in the
21
- * fragment — `#access_token=…&refresh_token=…`. A return target is recorded in a query string, and
22
- * a query string is not a fragment: it rides in `Referer`, it is written to every access log on the
21
+ * fragment, `#access_token=…&refresh_token=…`. A return target is recorded in a query string, and a
22
+ * query string is not a fragment: it rides in `Referer`, it is written to every access log on the
23
23
  * way, and it stays in history. So a fragment carrying a credential is dropped and the page is
24
24
  * kept, because the page is the part worth returning to and the anchor is the part that is
25
25
  * dangerous.
26
26
  *
27
- * Total on purpose — the caller is handing over its OWN address, which is on this origin by
28
- * construction. Use `safeInternalPath` for the other direction, where someone else wrote the value.
27
+ * Accepts every caller address on purpose. The caller is handing over its OWN address, which is on
28
+ * this origin by construction. Use `safeInternalPath` for the other direction, where someone else
29
+ * wrote the value.
29
30
  */
30
31
  export declare function returnPathFromLocation({ pathname, search, hash }: PathParts): string;
31
32
  //# sourceMappingURL=internal-path.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"internal-path.d.ts","sourceRoot":"","sources":["../src/internal-path.ts"],"names":[],"mappings":"AAUA;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI,CAU9D;AAiBD,mGAAmG;AACnG,MAAM,WAAW,SAAS;IACxB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;CACd;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,sBAAsB,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE,SAAS,GAAG,MAAM,CAKpF"}
1
+ {"version":3,"file":"internal-path.d.ts","sourceRoot":"","sources":["../src/internal-path.ts"],"names":[],"mappings":"AAUA;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI,CAU9D;AAiBD,mGAAmG;AACnG,MAAM,WAAW,SAAS;IACxB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;CACd;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,sBAAsB,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE,SAAS,GAAG,MAAM,CAKpF"}
@@ -11,9 +11,9 @@ function containsControl(value) {
11
11
  * A route the browser can follow without leaving the current origin.
12
12
  *
13
13
  * Return targets cross a trust boundary: query strings, history state and storage are all writable
14
- * by somebody outside the app. `startsWith("/")` is not enough — URL parsers read both `//host`
15
- * and `/\\host` as another origin, and strip tabs or newlines before making the same decision.
16
- * Parsing against a fixed origin applies the browser's own rules rather than trying to copy them.
14
+ * by somebody outside the app. `startsWith("/")` is not enough: URL parsers read both `//host` and
15
+ * `/\\host` as another origin, and strip tabs or newlines before making the same decision. Parsing
16
+ * against a fixed origin applies the browser's own rules rather than trying to copy them.
17
17
  */
18
18
  export function safeInternalPath(value) {
19
19
  if (typeof value !== "string" || !value.startsWith("/") || containsControl(value))
@@ -47,14 +47,15 @@ const CREDENTIAL_FRAGMENT_KEYS = [
47
47
  *
48
48
  * The fragment is the half that is easy to get wrong, and getting it wrong leaks a credential. A
49
49
  * Supabase client with no `flowType` uses the IMPLICIT flow, which returns the session in the
50
- * fragment — `#access_token=…&refresh_token=…`. A return target is recorded in a query string, and
51
- * a query string is not a fragment: it rides in `Referer`, it is written to every access log on the
50
+ * fragment, `#access_token=…&refresh_token=…`. A return target is recorded in a query string, and a
51
+ * query string is not a fragment: it rides in `Referer`, it is written to every access log on the
52
52
  * way, and it stays in history. So a fragment carrying a credential is dropped and the page is
53
53
  * kept, because the page is the part worth returning to and the anchor is the part that is
54
54
  * dangerous.
55
55
  *
56
- * Total on purpose — the caller is handing over its OWN address, which is on this origin by
57
- * construction. Use `safeInternalPath` for the other direction, where someone else wrote the value.
56
+ * Accepts every caller address on purpose. The caller is handing over its OWN address, which is on
57
+ * this origin by construction. Use `safeInternalPath` for the other direction, where someone else
58
+ * wrote the value.
58
59
  */
59
60
  export function returnPathFromLocation({ pathname, search, hash }) {
60
61
  const fragment = hash.startsWith("#") ? hash.slice(1) : hash;
@@ -1 +1 @@
1
- {"version":3,"file":"internal-path.js","sourceRoot":"","sources":["../src/internal-path.ts"],"names":[],"mappings":"AAAA,MAAM,eAAe,GAAG,0BAA0B,CAAC;AAEnD,SAAS,eAAe,CAAC,KAAa;IACpC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;QAChC,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,KAAK,IAAI;YAAE,OAAO,IAAI,CAAC;IACjD,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,gBAAgB,CAAC,KAAc;IAC7C,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,eAAe,CAAC,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IAE/F,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,KAAK,EAAE,eAAe,CAAC,CAAC;QAC5C,IAAI,GAAG,CAAC,MAAM,KAAK,eAAe;YAAE,OAAO,IAAI,CAAC;QAChD,OAAO,GAAG,GAAG,CAAC,QAAQ,GAAG,GAAG,CAAC,MAAM,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC;IACnD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED;;;;;GAKG;AACH,MAAM,wBAAwB,GAAG;IAC/B,cAAc;IACd,eAAe;IACf,UAAU;IACV,gBAAgB;IAChB,wBAAwB;IACxB,YAAY;CACb,CAAC;AASF;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,sBAAsB,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAa;IAC1E,MAAM,QAAQ,GAAG,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IAC7D,MAAM,MAAM,GAAG,IAAI,eAAe,CAAC,QAAQ,CAAC,CAAC;IAC7C,MAAM,iBAAiB,GAAG,wBAAwB,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;IAClF,OAAO,GAAG,QAAQ,GAAG,MAAM,GAAG,iBAAiB,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;AAChE,CAAC"}
1
+ {"version":3,"file":"internal-path.js","sourceRoot":"","sources":["../src/internal-path.ts"],"names":[],"mappings":"AAAA,MAAM,eAAe,GAAG,0BAA0B,CAAC;AAEnD,SAAS,eAAe,CAAC,KAAa;IACpC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;QAChC,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,KAAK,IAAI;YAAE,OAAO,IAAI,CAAC;IACjD,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,gBAAgB,CAAC,KAAc;IAC7C,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,eAAe,CAAC,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IAE/F,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,KAAK,EAAE,eAAe,CAAC,CAAC;QAC5C,IAAI,GAAG,CAAC,MAAM,KAAK,eAAe;YAAE,OAAO,IAAI,CAAC;QAChD,OAAO,GAAG,GAAG,CAAC,QAAQ,GAAG,GAAG,CAAC,MAAM,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC;IACnD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED;;;;;GAKG;AACH,MAAM,wBAAwB,GAAG;IAC/B,cAAc;IACd,eAAe;IACf,UAAU;IACV,gBAAgB;IAChB,wBAAwB;IACxB,YAAY;CACb,CAAC;AASF;;;;;;;;;;;;;;GAcG;AACH,MAAM,UAAU,sBAAsB,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAa;IAC1E,MAAM,QAAQ,GAAG,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IAC7D,MAAM,MAAM,GAAG,IAAI,eAAe,CAAC,QAAQ,CAAC,CAAC;IAC7C,MAAM,iBAAiB,GAAG,wBAAwB,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;IAClF,OAAO,GAAG,QAAQ,GAAG,MAAM,GAAG,iBAAiB,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;AAChE,CAAC"}
@@ -1,5 +1,5 @@
1
1
  /**
2
- * The two constants the build and the browser both need — and **nothing else in this file**.
2
+ * The two constants the build and the browser both need. Keep **nothing else in this file**.
3
3
  *
4
4
  * It is separate from `hydrate.ts` for one reason: that module imports `react-dom/client`, and
5
5
  * `@gusnips/vite` needs these constants to WRITE the attribute at build time. If the constants
@@ -11,8 +11,8 @@
11
11
  * string value each time. See `hydrate.ts` for why it exists at all.
12
12
  */
13
13
  /**
14
- * The attribute a prerendered file names its own route in — written by the build, read by the
15
- * browser entry.
14
+ * The attribute where a prerendered file names its own route. The build writes it and the browser
15
+ * entry reads it.
16
16
  *
17
17
  * One constant because the writer and the reader are in different builds, and a typo between
18
18
  * them would show up only as a silent full re-render: a page that works, and a bug nobody sees.
@@ -21,10 +21,10 @@ export declare const PRERENDERED_ROUTE_ATTR = "data-prerendered-route";
21
21
  /**
22
22
  * What a 404 shell writes instead of a route.
23
23
  *
24
- * It is the pattern that actually matched — the catch-all — and it can never equal an address,
25
- * which is the property that matters: every route a static host answers from the shell mounts
26
- * fresh rather than hydrating the not-found page over itself. A real 404 pays one redundant
27
- * client render for that, and keeps the markup a crawler reads.
24
+ * It is the catch-all pattern that actually matched, and it can never equal an address, which is
25
+ * the property that matters: every route a static host answers from the shell mounts fresh rather
26
+ * than hydrating the not-found page over itself. A real 404 pays one redundant client render for
27
+ * that, and keeps the markup a crawler reads.
28
28
  */
29
29
  export declare const SHELL_ROUTE = "*";
30
30
  //# sourceMappingURL=prerender-contract.d.ts.map
@@ -1,5 +1,5 @@
1
1
  /**
2
- * The two constants the build and the browser both need — and **nothing else in this file**.
2
+ * The two constants the build and the browser both need. Keep **nothing else in this file**.
3
3
  *
4
4
  * It is separate from `hydrate.ts` for one reason: that module imports `react-dom/client`, and
5
5
  * `@gusnips/vite` needs these constants to WRITE the attribute at build time. If the constants
@@ -11,8 +11,8 @@
11
11
  * string value each time. See `hydrate.ts` for why it exists at all.
12
12
  */
13
13
  /**
14
- * The attribute a prerendered file names its own route in — written by the build, read by the
15
- * browser entry.
14
+ * The attribute where a prerendered file names its own route. The build writes it and the browser
15
+ * entry reads it.
16
16
  *
17
17
  * One constant because the writer and the reader are in different builds, and a typo between
18
18
  * them would show up only as a silent full re-render: a page that works, and a bug nobody sees.
@@ -21,10 +21,10 @@ export const PRERENDERED_ROUTE_ATTR = "data-prerendered-route";
21
21
  /**
22
22
  * What a 404 shell writes instead of a route.
23
23
  *
24
- * It is the pattern that actually matched — the catch-all — and it can never equal an address,
25
- * which is the property that matters: every route a static host answers from the shell mounts
26
- * fresh rather than hydrating the not-found page over itself. A real 404 pays one redundant
27
- * client render for that, and keeps the markup a crawler reads.
24
+ * It is the catch-all pattern that actually matched, and it can never equal an address, which is
25
+ * the property that matters: every route a static host answers from the shell mounts fresh rather
26
+ * than hydrating the not-found page over itself. A real 404 pays one redundant client render for
27
+ * that, and keeps the markup a crawler reads.
28
28
  */
29
29
  export const SHELL_ROUTE = "*";
30
30
  //# sourceMappingURL=prerender-contract.js.map