@aglyn/shared-util-next 1.0.0-beta.275 → 1.0.0-beta.282

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aglyn/shared-util-next",
3
- "version": "1.0.0-beta.275",
3
+ "version": "1.0.0-beta.282",
4
4
  "license": "Apache-2.0",
5
5
  "homepage": "https://aglyn.com",
6
6
  "repository": {
@@ -24,7 +24,7 @@
24
24
  "./package.json": "./package.json"
25
25
  },
26
26
  "dependencies": {
27
- "@aglyn/shared-util-http": "1.0.0-beta.275",
27
+ "@aglyn/shared-util-http": "1.0.0-beta.282",
28
28
  "@swc/helpers": "0.5.23"
29
29
  },
30
30
  "peerDependencies": {
@@ -67,6 +67,21 @@ export declare function withContinueUrl(path: string, continueUrl: string): stri
67
67
  */
68
68
  export declare function useContinueHref(path: string): string;
69
69
  export declare function useContinueUrlDecoded(): UseContinueUrlDecodedResponse;
70
+ /**
71
+ * The place to come back to after signing in: the path AND its query
72
+ * (AGL-4023).
73
+ *
74
+ * Built from the pathname alone, a signed-out visitor lost everything after
75
+ * the `?` on the way to `/signin`: a hand-off email's plan, add-ons and
76
+ * cadence, and a staff bundle link's `bundle` id, which carries its one-time
77
+ * domain-purchase waiver. Every hop after this one already keeps a query
78
+ * (`safeSameOriginPath`, the auth host's `continue`, {@link withContinueUrl}),
79
+ * so this is the only place it was dropped.
80
+ *
81
+ * No pathname means no place to return to, so a bare query is never
82
+ * returned on its own.
83
+ */
84
+ export declare function continuePathFor(pathname: string, search: string): string;
70
85
  export declare function useContinueUrlEncoded(): string;
71
86
  export declare function useContinueUrl(): UseContinueUrlResponse;
72
87
  export default useContinueUrl;
@@ -139,12 +139,34 @@ export function useContinueUrlDecoded() {
139
139
  pushNext
140
140
  ]);
141
141
  }
142
+ /**
143
+ * The place to come back to after signing in: the path AND its query
144
+ * (AGL-4023).
145
+ *
146
+ * Built from the pathname alone, a signed-out visitor lost everything after
147
+ * the `?` on the way to `/signin`: a hand-off email's plan, add-ons and
148
+ * cadence, and a staff bundle link's `bundle` id, which carries its one-time
149
+ * domain-purchase waiver. Every hop after this one already keeps a query
150
+ * (`safeSameOriginPath`, the auth host's `continue`, {@link withContinueUrl}),
151
+ * so this is the only place it was dropped.
152
+ *
153
+ * No pathname means no place to return to, so a bare query is never
154
+ * returned on its own.
155
+ */ export function continuePathFor(pathname, search) {
156
+ if (!pathname) return '';
157
+ const query = search.replace(/^\?/, '');
158
+ return query ? `${pathname}?${query}` : pathname;
159
+ }
142
160
  export function useContinueUrlEncoded() {
161
+ var _ref;
143
162
  const pathname = usePathname();
163
+ const searchParams = useSearchParams();
164
+ const search = (_ref = searchParams == null ? void 0 : searchParams.toString()) != null ? _ref : '';
144
165
  return useMemo(()=>{
145
- return encodeURIComponent(pathname || '');
166
+ return encodeURIComponent(continuePathFor(pathname || '', search));
146
167
  }, [
147
- pathname
168
+ pathname,
169
+ search
148
170
  ]);
149
171
  }
150
172
  export function useContinueUrl() {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../../../libs/shared/util/next/src/lib/use-continue-url.ts"],"sourcesContent":["/**\n * @license\n * Copyright 2024 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n'use client'\n\nimport { isSameOriginPath } from '@aglyn/shared-util-http/safe-redirect'\nimport { usePathname, useRouter, useSearchParams } from 'next/navigation'\nimport { useCallback, useMemo } from 'react'\n\nexport type UseContinueUrlDecodedRoutePusher = (\n url?: string,\n as?: string,\n options?: { shallow?: boolean; locale?: string | false; scroll?: boolean },\n) => void\n\nexport type UseContinueUrlDecodedResponse = [\n decoded: string,\n pushNext: UseContinueUrlDecodedRoutePusher,\n]\n\nexport type UseContinueUrlResponse = [\n encoded: string,\n decoded: string,\n pushNext: UseContinueUrlDecodedRoutePusher,\n]\n\nexport const ContinueParamName = 'continue'\nexport const continueParam = (value: string) => `${ContinueParamName}=${value}`\n\nconst WORKSPACE_DOMAIN =\n process.env.NEXT_PUBLIC_WORKSPACE_DOMAIN ?? 'aglyn.com'\n\n/**\n * Same-site absolute returns (AGL-465): the auth host signs a user in and\n * must redirect back to the {org}.<workspaceDomain> subdomain they started\n * from, which is a cross-origin URL. Allow it only when the host is within\n * the workspace domain over https, so this stays first-party and never\n * becomes an open redirect.\n */\nconst isSameSiteAbsoluteUrl = (url: string): boolean => {\n try {\n const { protocol, hostname } = new URL(url)\n if (protocol !== 'https:') return false\n return (\n hostname === WORKSPACE_DOMAIN ||\n hostname.endsWith(`.${WORKSPACE_DOMAIN}`)\n )\n } catch {\n return false\n }\n}\n\n/**\n * Only same-app relative paths, or same-site absolute URLs within the\n * workspace domain (AGL-465), may be continued to — anything else absolute\n * or protocol-relative would make the post-auth redirect an open redirect.\n *\n * The relative branch defers to {@link isSameOriginPath} rather than testing\n * the string's shape (AGL-1881). AGL-2486 rejected `\\` here because the\n * WHATWG URL parser treats it as `/` in the authority position, so\n * `/\\evil.com` passed a `startsWith('/') && !startsWith('//')` test and still\n * resolved off-site. That was true but incomplete: the same parser also\n * DELETES every tab, LF and CR before parsing, so `/<TAB>/evil.com` resolves\n * to `https://evil.com/` while containing neither `//` nor `\\`. Enumerating\n * the tricks was the mistake; the shared predicate resolves the value and\n * compares origins, which is the question `window.location.assign` will\n * actually ask.\n *\n * The absolute branch below never had that bug and keeps its own check: once\n * the input is absolute the parser's `hostname` is already ground truth.\n *\n * A `continue` that has survived an external IdP round trip is the case that\n * makes this matter: whatever we put into `state` comes back as untrusted\n * input.\n *\n * `''` is rejected explicitly rather than by accident. `strictNullChecks` is\n * off repo-wide, so an absent param arrives here as an empty string far more\n * often than as `undefined`, and \"no continue\" must read as unsafe so the\n * caller falls back to its own default instead of building `?continue=`.\n */\nexport const isSafeContinueUrl = (url: string): boolean => {\n if (!url) return false\n return isSameOriginPath(url) || isSameSiteAbsoluteUrl(url)\n}\n\n/**\n * Forward the continue URL onto another same-app path (AGL-2486).\n *\n * A signed-out user who deep-links in arrives at `/signin?continue=…`, and\n * every link OUT of that page to another auth route — the SSO button above\n * all — has to carry the value or the destination they were going to is\n * gone. Observed on the SSO button: the url does not carry the\n * continue url and is dropped entirely.\n *\n * Unsafe or absent values append nothing, so a poisoned `continue` degrades\n * to a plain link rather than being laundered one hop further along.\n */\nexport function withContinueUrl(path: string, continueUrl: string): string {\n if (!isSafeContinueUrl(continueUrl)) return path\n const separator = path.includes('?') ? '&' : '?'\n return `${path}${separator}${continueParam(encodeURIComponent(continueUrl))}`\n}\n\n/**\n * `href` for a link out of the current page that keeps the continue URL.\n *\n * Deliberately reads `useSearchParams` directly instead of reusing\n * {@link useContinueUrlDecoded}: that hook also calls `useRouter`, and a\n * link does not navigate imperatively. Pulling the router in would make\n * every page that renders one of these links require an App Router context\n * it does not otherwise need.\n */\nexport function useContinueHref(path: string): string {\n const searchParams = useSearchParams()\n const raw = searchParams?.get(ContinueParamName) ?? ''\n return useMemo(() => withContinueUrl(path, raw), [path, raw])\n}\n\nexport function useContinueUrlDecoded(): UseContinueUrlDecodedResponse {\n const router = useRouter()\n // App Router: query strings live in useSearchParams — useParams only\n // carries dynamic route segments, which is why the continue redirect\n // silently broke after the pages→app migration (AGL-458). `get` already\n // percent-decodes, so no second decode (it would corrupt paths that\n // legitimately contain %-sequences).\n const searchParams = useSearchParams()\n\n const continueUrl = useMemo(() => {\n const url = searchParams?.get(ContinueParamName) ?? ''\n return isSafeContinueUrl(url) ? url : ''\n }, [searchParams])\n\n const pushNext = useCallback(\n (\n url = '/',\n as: string | undefined = undefined,\n options?: {\n shallow?: boolean\n locale?: string | false\n scroll?: boolean\n },\n ): void => {\n const target = continueUrl || url\n // A same-site absolute return (AGL-465) is cross-origin — the App\n // Router's client navigation can't cross origins, so hand it to the\n // browser. Relative paths keep the SPA transition.\n if (/^https?:\\/\\//.test(target)) {\n if (typeof window !== 'undefined') window.location.assign(target)\n return\n }\n return router.push(target, options)\n },\n [router, continueUrl],\n )\n\n return useMemo(() => {\n return [continueUrl, pushNext]\n }, [continueUrl, pushNext])\n}\n\nexport function useContinueUrlEncoded() {\n const pathname = usePathname()\n\n return useMemo(() => {\n return encodeURIComponent(pathname || '')\n }, [pathname])\n}\n\nexport function useContinueUrl(): UseContinueUrlResponse {\n const encoded = useContinueUrlEncoded()\n const [decoded, pushNext] = useContinueUrlDecoded()\n\n return useMemo(\n () => [encoded, decoded, pushNext],\n [encoded, decoded, pushNext],\n )\n}\n\nexport default useContinueUrl\n"],"names":["process","isSameOriginPath","usePathname","useRouter","useSearchParams","useCallback","useMemo","ContinueParamName","continueParam","value","WORKSPACE_DOMAIN","env","NEXT_PUBLIC_WORKSPACE_DOMAIN","isSameSiteAbsoluteUrl","url","protocol","hostname","URL","endsWith","isSafeContinueUrl","withContinueUrl","path","continueUrl","separator","includes","encodeURIComponent","useContinueHref","searchParams","raw","get","useContinueUrlDecoded","router","pushNext","as","undefined","options","target","test","window","location","assign","push","useContinueUrlEncoded","pathname","useContinueUrl","encoded","decoded"],"mappings":"AAAA;;;;;;;;;;;;;;;CAeC,GACD;IA2BEA;AAzBF,SAASC,gBAAgB,QAAQ,wCAAuC;AACxE,SAASC,WAAW,EAAEC,SAAS,EAAEC,eAAe,QAAQ,kBAAiB;AACzE,SAASC,WAAW,EAAEC,OAAO,QAAQ,QAAO;AAmB5C,OAAO,MAAMC,oBAAoB,WAAU;AAC3C,OAAO,MAAMC,gBAAgB,CAACC,QAAkB,GAAGF,kBAAkB,CAAC,EAAEE,OAAO,CAAA;AAE/E,MAAMC,oBACJV,4CAAAA,QAAQW,GAAG,CAACC,4BAA4B,YAAxCZ,4CAA4C;AAE9C;;;;;;CAMC,GACD,MAAMa,wBAAwB,CAACC;IAC7B,IAAI;QACF,MAAM,EAAEC,QAAQ,EAAEC,QAAQ,EAAE,GAAG,IAAIC,IAAIH;QACvC,IAAIC,aAAa,UAAU,OAAO;QAClC,OACEC,aAAaN,oBACbM,SAASE,QAAQ,CAAC,CAAC,CAAC,EAAER,kBAAkB;IAE5C,EAAE,eAAM;QACN,OAAO;IACT;AACF;AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;CA2BC,GACD,OAAO,MAAMS,oBAAoB,CAACL;IAChC,IAAI,CAACA,KAAK,OAAO;IACjB,OAAOb,iBAAiBa,QAAQD,sBAAsBC;AACxD,EAAC;AAED;;;;;;;;;;;CAWC,GACD,OAAO,SAASM,gBAAgBC,IAAY,EAAEC,WAAmB;IAC/D,IAAI,CAACH,kBAAkBG,cAAc,OAAOD;IAC5C,MAAME,YAAYF,KAAKG,QAAQ,CAAC,OAAO,MAAM;IAC7C,OAAO,GAAGH,OAAOE,YAAYf,cAAciB,mBAAmBH,eAAe;AAC/E;AAEA;;;;;;;;CAQC,GACD,OAAO,SAASI,gBAAgBL,IAAY;;IAC1C,MAAMM,eAAevB;IACrB,MAAMwB,cAAMD,gCAAAA,aAAcE,GAAG,CAACtB,qCAAsB;IACpD,OAAOD,QAAQ,IAAMc,gBAAgBC,MAAMO,MAAM;QAACP;QAAMO;KAAI;AAC9D;AAEA,OAAO,SAASE;IACd,MAAMC,SAAS5B;IACf,qEAAqE;IACrE,qEAAqE;IACrE,wEAAwE;IACxE,oEAAoE;IACpE,qCAAqC;IACrC,MAAMwB,eAAevB;IAErB,MAAMkB,cAAchB,QAAQ;;QAC1B,MAAMQ,cAAMa,gCAAAA,aAAcE,GAAG,CAACtB,qCAAsB;QACpD,OAAOY,kBAAkBL,OAAOA,MAAM;IACxC,GAAG;QAACa;KAAa;IAEjB,MAAMK,WAAW3B,YACf,CACES,MAAM,GAAG,EACTmB,KAAyBC,SAAS,EAClCC;QAMA,MAAMC,SAASd,eAAeR;QAC9B,kEAAkE;QAClE,oEAAoE;QACpE,mDAAmD;QACnD,IAAI,eAAeuB,IAAI,CAACD,SAAS;YAC/B,IAAI,OAAOE,WAAW,aAAaA,OAAOC,QAAQ,CAACC,MAAM,CAACJ;YAC1D;QACF;QACA,OAAOL,OAAOU,IAAI,CAACL,QAAQD;IAC7B,GACA;QAACJ;QAAQT;KAAY;IAGvB,OAAOhB,QAAQ;QACb,OAAO;YAACgB;YAAaU;SAAS;IAChC,GAAG;QAACV;QAAaU;KAAS;AAC5B;AAEA,OAAO,SAASU;IACd,MAAMC,WAAWzC;IAEjB,OAAOI,QAAQ;QACb,OAAOmB,mBAAmBkB,YAAY;IACxC,GAAG;QAACA;KAAS;AACf;AAEA,OAAO,SAASC;IACd,MAAMC,UAAUH;IAChB,MAAM,CAACI,SAASd,SAAS,GAAGF;IAE5B,OAAOxB,QACL,IAAM;YAACuC;YAASC;YAASd;SAAS,EAClC;QAACa;QAASC;QAASd;KAAS;AAEhC;AAEA,eAAeY,eAAc"}
1
+ {"version":3,"sources":["../../../../../../../libs/shared/util/next/src/lib/use-continue-url.ts"],"sourcesContent":["/**\n * @license\n * Copyright 2024 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n'use client'\n\nimport { isSameOriginPath } from '@aglyn/shared-util-http/safe-redirect'\nimport { usePathname, useRouter, useSearchParams } from 'next/navigation'\nimport { useCallback, useMemo } from 'react'\n\nexport type UseContinueUrlDecodedRoutePusher = (\n url?: string,\n as?: string,\n options?: { shallow?: boolean; locale?: string | false; scroll?: boolean },\n) => void\n\nexport type UseContinueUrlDecodedResponse = [\n decoded: string,\n pushNext: UseContinueUrlDecodedRoutePusher,\n]\n\nexport type UseContinueUrlResponse = [\n encoded: string,\n decoded: string,\n pushNext: UseContinueUrlDecodedRoutePusher,\n]\n\nexport const ContinueParamName = 'continue'\nexport const continueParam = (value: string) => `${ContinueParamName}=${value}`\n\nconst WORKSPACE_DOMAIN =\n process.env.NEXT_PUBLIC_WORKSPACE_DOMAIN ?? 'aglyn.com'\n\n/**\n * Same-site absolute returns (AGL-465): the auth host signs a user in and\n * must redirect back to the {org}.<workspaceDomain> subdomain they started\n * from, which is a cross-origin URL. Allow it only when the host is within\n * the workspace domain over https, so this stays first-party and never\n * becomes an open redirect.\n */\nconst isSameSiteAbsoluteUrl = (url: string): boolean => {\n try {\n const { protocol, hostname } = new URL(url)\n if (protocol !== 'https:') return false\n return (\n hostname === WORKSPACE_DOMAIN ||\n hostname.endsWith(`.${WORKSPACE_DOMAIN}`)\n )\n } catch {\n return false\n }\n}\n\n/**\n * Only same-app relative paths, or same-site absolute URLs within the\n * workspace domain (AGL-465), may be continued to — anything else absolute\n * or protocol-relative would make the post-auth redirect an open redirect.\n *\n * The relative branch defers to {@link isSameOriginPath} rather than testing\n * the string's shape (AGL-1881). AGL-2486 rejected `\\` here because the\n * WHATWG URL parser treats it as `/` in the authority position, so\n * `/\\evil.com` passed a `startsWith('/') && !startsWith('//')` test and still\n * resolved off-site. That was true but incomplete: the same parser also\n * DELETES every tab, LF and CR before parsing, so `/<TAB>/evil.com` resolves\n * to `https://evil.com/` while containing neither `//` nor `\\`. Enumerating\n * the tricks was the mistake; the shared predicate resolves the value and\n * compares origins, which is the question `window.location.assign` will\n * actually ask.\n *\n * The absolute branch below never had that bug and keeps its own check: once\n * the input is absolute the parser's `hostname` is already ground truth.\n *\n * A `continue` that has survived an external IdP round trip is the case that\n * makes this matter: whatever we put into `state` comes back as untrusted\n * input.\n *\n * `''` is rejected explicitly rather than by accident. `strictNullChecks` is\n * off repo-wide, so an absent param arrives here as an empty string far more\n * often than as `undefined`, and \"no continue\" must read as unsafe so the\n * caller falls back to its own default instead of building `?continue=`.\n */\nexport const isSafeContinueUrl = (url: string): boolean => {\n if (!url) return false\n return isSameOriginPath(url) || isSameSiteAbsoluteUrl(url)\n}\n\n/**\n * Forward the continue URL onto another same-app path (AGL-2486).\n *\n * A signed-out user who deep-links in arrives at `/signin?continue=…`, and\n * every link OUT of that page to another auth route — the SSO button above\n * all — has to carry the value or the destination they were going to is\n * gone. Observed on the SSO button: the url does not carry the\n * continue url and is dropped entirely.\n *\n * Unsafe or absent values append nothing, so a poisoned `continue` degrades\n * to a plain link rather than being laundered one hop further along.\n */\nexport function withContinueUrl(path: string, continueUrl: string): string {\n if (!isSafeContinueUrl(continueUrl)) return path\n const separator = path.includes('?') ? '&' : '?'\n return `${path}${separator}${continueParam(encodeURIComponent(continueUrl))}`\n}\n\n/**\n * `href` for a link out of the current page that keeps the continue URL.\n *\n * Deliberately reads `useSearchParams` directly instead of reusing\n * {@link useContinueUrlDecoded}: that hook also calls `useRouter`, and a\n * link does not navigate imperatively. Pulling the router in would make\n * every page that renders one of these links require an App Router context\n * it does not otherwise need.\n */\nexport function useContinueHref(path: string): string {\n const searchParams = useSearchParams()\n const raw = searchParams?.get(ContinueParamName) ?? ''\n return useMemo(() => withContinueUrl(path, raw), [path, raw])\n}\n\nexport function useContinueUrlDecoded(): UseContinueUrlDecodedResponse {\n const router = useRouter()\n // App Router: query strings live in useSearchParams — useParams only\n // carries dynamic route segments, which is why the continue redirect\n // silently broke after the pages→app migration (AGL-458). `get` already\n // percent-decodes, so no second decode (it would corrupt paths that\n // legitimately contain %-sequences).\n const searchParams = useSearchParams()\n\n const continueUrl = useMemo(() => {\n const url = searchParams?.get(ContinueParamName) ?? ''\n return isSafeContinueUrl(url) ? url : ''\n }, [searchParams])\n\n const pushNext = useCallback(\n (\n url = '/',\n as: string | undefined = undefined,\n options?: {\n shallow?: boolean\n locale?: string | false\n scroll?: boolean\n },\n ): void => {\n const target = continueUrl || url\n // A same-site absolute return (AGL-465) is cross-origin — the App\n // Router's client navigation can't cross origins, so hand it to the\n // browser. Relative paths keep the SPA transition.\n if (/^https?:\\/\\//.test(target)) {\n if (typeof window !== 'undefined') window.location.assign(target)\n return\n }\n return router.push(target, options)\n },\n [router, continueUrl],\n )\n\n return useMemo(() => {\n return [continueUrl, pushNext]\n }, [continueUrl, pushNext])\n}\n\n/**\n * The place to come back to after signing in: the path AND its query\n * (AGL-4023).\n *\n * Built from the pathname alone, a signed-out visitor lost everything after\n * the `?` on the way to `/signin`: a hand-off email's plan, add-ons and\n * cadence, and a staff bundle link's `bundle` id, which carries its one-time\n * domain-purchase waiver. Every hop after this one already keeps a query\n * (`safeSameOriginPath`, the auth host's `continue`, {@link withContinueUrl}),\n * so this is the only place it was dropped.\n *\n * No pathname means no place to return to, so a bare query is never\n * returned on its own.\n */\nexport function continuePathFor(pathname: string, search: string): string {\n if (!pathname) return ''\n const query = search.replace(/^\\?/, '')\n return query ? `${pathname}?${query}` : pathname\n}\n\nexport function useContinueUrlEncoded() {\n const pathname = usePathname()\n const searchParams = useSearchParams()\n const search = searchParams?.toString() ?? ''\n\n return useMemo(() => {\n return encodeURIComponent(continuePathFor(pathname || '', search))\n }, [pathname, search])\n}\n\nexport function useContinueUrl(): UseContinueUrlResponse {\n const encoded = useContinueUrlEncoded()\n const [decoded, pushNext] = useContinueUrlDecoded()\n\n return useMemo(\n () => [encoded, decoded, pushNext],\n [encoded, decoded, pushNext],\n )\n}\n\nexport default useContinueUrl\n"],"names":["process","isSameOriginPath","usePathname","useRouter","useSearchParams","useCallback","useMemo","ContinueParamName","continueParam","value","WORKSPACE_DOMAIN","env","NEXT_PUBLIC_WORKSPACE_DOMAIN","isSameSiteAbsoluteUrl","url","protocol","hostname","URL","endsWith","isSafeContinueUrl","withContinueUrl","path","continueUrl","separator","includes","encodeURIComponent","useContinueHref","searchParams","raw","get","useContinueUrlDecoded","router","pushNext","as","undefined","options","target","test","window","location","assign","push","continuePathFor","pathname","search","query","replace","useContinueUrlEncoded","toString","useContinueUrl","encoded","decoded"],"mappings":"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"}