payload-subscribers-plugin 0.0.14 → 0.0.16
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/README.md +1 -1
- package/dist/components/app/Unsubscribe.d.ts +1 -0
- package/dist/components/app/Unsubscribe.js +21 -1
- package/dist/components/app/Unsubscribe.js.map +1 -1
- package/dist/components/app/VerifyMagicLink.d.ts +1 -0
- package/dist/components/app/VerifyMagicLink.js +27 -12
- package/dist/components/app/VerifyMagicLink.js.map +1 -1
- package/dist/contexts/SubscriberProvider.js +28 -17
- package/dist/contexts/SubscriberProvider.js.map +1 -1
- package/dist/endpoints/logout.js +3 -2
- package/dist/endpoints/logout.js.map +1 -1
- package/dist/hooks/useRequestMagicLink.js +7 -2
- package/dist/hooks/useRequestMagicLink.js.map +1 -1
- package/dist/server-functions/serverUrl.js +2 -1
- package/dist/server-functions/serverUrl.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -49,7 +49,7 @@ export default buildConfig({
|
|
|
49
49
|
subscribersCollectionSlug?: CollectionSlug
|
|
50
50
|
|
|
51
51
|
// Provide a custom expiration for magic link tokens. The default is 30 minutes.
|
|
52
|
-
tokenExpiration:
|
|
52
|
+
tokenExpiration: 30 * 60,
|
|
53
53
|
|
|
54
54
|
// Provide your unsubscribe route. This route should include the Unsubscribe component, or implement your own with the useUnsubscribe hook. If not provided, your payload config must have serverURL defined, and the default will be serverURL+'/unsubscribe'
|
|
55
55
|
unsubscribeURL?: string,
|
|
@@ -43,3 +43,4 @@ export type UnsubscribeClasses = {
|
|
|
43
43
|
* @returns Loading status, result message, and children
|
|
44
44
|
*/
|
|
45
45
|
export declare const Unsubscribe: ({ children, classNames, handleUnsubscribe, }: IUnsubscribe) => import("react").JSX.Element;
|
|
46
|
+
export declare const UnsubscribeInSuspense: ({ children, classNames, handleUnsubscribe, }: IUnsubscribe) => import("react").JSX.Element;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
3
3
|
import { useSearchParams } from 'next/navigation.js';
|
|
4
|
-
import { useEffect } from 'react';
|
|
4
|
+
import { Suspense, useEffect } from 'react';
|
|
5
5
|
import { useUnsubscribe } from '../../hooks/useUnsubscribe.js';
|
|
6
6
|
import { mergeClassNames } from './helpers.js';
|
|
7
7
|
import styles from './shared.module.css';
|
|
@@ -22,6 +22,26 @@ import styles from './shared.module.css';
|
|
|
22
22
|
form: '',
|
|
23
23
|
loading: '',
|
|
24
24
|
message: ''
|
|
25
|
+
}, handleUnsubscribe })=>{
|
|
26
|
+
return /*#__PURE__*/ _jsx(Suspense, {
|
|
27
|
+
fallback: /*#__PURE__*/ _jsx("div", {
|
|
28
|
+
children: "Unsubscribing..."
|
|
29
|
+
}),
|
|
30
|
+
children: /*#__PURE__*/ _jsx(UnsubscribeInSuspense, {
|
|
31
|
+
classNames: classNames,
|
|
32
|
+
handleUnsubscribe: handleUnsubscribe,
|
|
33
|
+
children: children
|
|
34
|
+
})
|
|
35
|
+
});
|
|
36
|
+
};
|
|
37
|
+
export const UnsubscribeInSuspense = ({ children, classNames = {
|
|
38
|
+
button: '',
|
|
39
|
+
container: '',
|
|
40
|
+
emailInput: '',
|
|
41
|
+
error: '',
|
|
42
|
+
form: '',
|
|
43
|
+
loading: '',
|
|
44
|
+
message: ''
|
|
25
45
|
}, handleUnsubscribe })=>{
|
|
26
46
|
const { isError, isLoading, result, unsubscribe } = useUnsubscribe({
|
|
27
47
|
handleUnsubscribe
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/components/app/Unsubscribe.tsx"],"sourcesContent":["'use client'\n\nimport { useSearchParams } from 'next/navigation.js'\nimport { useEffect } from 'react'\n\nimport type { UnsubscribeResponse } from '../../endpoints/unsubscribe.js'\n\nexport { UnsubscribeResponse }\nimport { useSubscriber } from '../../exports/ui.js'\nimport { useUnsubscribe } from '../../hooks/useUnsubscribe.js'\nimport { mergeClassNames } from './helpers.js'\nimport styles from './shared.module.css'\n\n// const payload = await getPayload({\n// config: configPromise,\n// })\n\n/**\n * Props for the Unsubscribe component.\n *\n * @property children - Optional React nodes rendered after unsubscribe is attempted\n * @property classNames - Optional CSS class overrides for the component elements\n * @property handleUnsubscribe - Callback when unsubscribe is attempted (success or error)\n */\nexport interface IUnsubscribe {\n children?: React.ReactNode\n classNames?: UnsubscribeClasses\n handleUnsubscribe?: (result: UnsubscribeResponse) => void\n}\n\n/**\n * Optional CSS class overrides for Unsubscribe elements.\n *\n * @property button - Class for buttons\n * @property container - Class for the main container\n * @property emailInput - Class for the email input field\n * @property error - Class for error messages\n * @property form - Class for the form\n * @property loading - Class for loading state\n * @property message - Class for result message text\n */\nexport type UnsubscribeClasses = {\n button?: string\n container?: string\n emailInput?: string\n error?: string\n form?: string\n loading?: string\n message?: string\n}\n\n/**\n * Handles the unsubscribe action, for use with unsubscribe URLs in emails, etc.\n * Uses URL params email and hash to call POST /api/unsubscribe. Displays children after attempt.\n *\n * @param props - Component props (see IUnsubscribe)\n * @param props.children - Optional React nodes rendered after unsubscribe is attempted\n * @param props.classNames - Optional class overrides for the component elements\n * @param props.handleUnsubscribe - Callback when unsubscribe is attempted (success or error)\n * @returns Loading status, result message, and children\n */\nexport const Unsubscribe = ({\n children,\n classNames = {\n button: '',\n container: '',\n emailInput: '',\n error: '',\n form: '',\n loading: '',\n message: '',\n },\n handleUnsubscribe,\n}: IUnsubscribe) => {\n const { isError, isLoading, result, unsubscribe } = useUnsubscribe({ handleUnsubscribe })\n\n const searchParams = useSearchParams()\n const email = searchParams.get('email')\n const hash = searchParams.get('hash')\n\n useEffect(() => {\n async function callUnsubscribe() {\n if (email && hash) {\n await unsubscribe({ email, hash })\n }\n }\n void callUnsubscribe()\n }, [email, hash, unsubscribe])\n\n return (\n <div\n className={mergeClassNames([\n 'subscribers-callUnsubscribe subscribers-container',\n styles.container,\n classNames.container,\n ])}\n >\n {isLoading && (\n <p className={mergeClassNames(['subscribers-loading', styles.loading, classNames.loading])}>\n unsubscribing...\n </p>\n )}\n {!isLoading && (\n <>\n <p\n className={mergeClassNames([\n 'subscribers-message',\n styles.message,\n classNames.message,\n isError ? ['subscribers-error', styles.error, classNames.error] : [],\n ])}\n >\n {result}\n </p>\n <div className={mergeClassNames(['subscribers-form', styles.form, classNames.form])}>\n {children}\n </div>\n </>\n )}\n </div>\n )\n}\n"],"names":["useSearchParams","useEffect","useUnsubscribe","mergeClassNames","styles","Unsubscribe","children","classNames","button","container","emailInput","error","form","loading","message","handleUnsubscribe","isError","isLoading","result","unsubscribe","searchParams","email","get","hash","callUnsubscribe","
|
|
1
|
+
{"version":3,"sources":["../../../src/components/app/Unsubscribe.tsx"],"sourcesContent":["'use client'\n\nimport { useSearchParams } from 'next/navigation.js'\nimport { Suspense, useEffect } from 'react'\n\nimport type { UnsubscribeResponse } from '../../endpoints/unsubscribe.js'\n\nexport { UnsubscribeResponse }\nimport { useSubscriber } from '../../exports/ui.js'\nimport { useUnsubscribe } from '../../hooks/useUnsubscribe.js'\nimport { mergeClassNames } from './helpers.js'\nimport styles from './shared.module.css'\n\n// const payload = await getPayload({\n// config: configPromise,\n// })\n\n/**\n * Props for the Unsubscribe component.\n *\n * @property children - Optional React nodes rendered after unsubscribe is attempted\n * @property classNames - Optional CSS class overrides for the component elements\n * @property handleUnsubscribe - Callback when unsubscribe is attempted (success or error)\n */\nexport interface IUnsubscribe {\n children?: React.ReactNode\n classNames?: UnsubscribeClasses\n handleUnsubscribe?: (result: UnsubscribeResponse) => void\n}\n\n/**\n * Optional CSS class overrides for Unsubscribe elements.\n *\n * @property button - Class for buttons\n * @property container - Class for the main container\n * @property emailInput - Class for the email input field\n * @property error - Class for error messages\n * @property form - Class for the form\n * @property loading - Class for loading state\n * @property message - Class for result message text\n */\nexport type UnsubscribeClasses = {\n button?: string\n container?: string\n emailInput?: string\n error?: string\n form?: string\n loading?: string\n message?: string\n}\n\n/**\n * Handles the unsubscribe action, for use with unsubscribe URLs in emails, etc.\n * Uses URL params email and hash to call POST /api/unsubscribe. Displays children after attempt.\n *\n * @param props - Component props (see IUnsubscribe)\n * @param props.children - Optional React nodes rendered after unsubscribe is attempted\n * @param props.classNames - Optional class overrides for the component elements\n * @param props.handleUnsubscribe - Callback when unsubscribe is attempted (success or error)\n * @returns Loading status, result message, and children\n */\nexport const Unsubscribe = ({\n children,\n classNames = {\n button: '',\n container: '',\n emailInput: '',\n error: '',\n form: '',\n loading: '',\n message: '',\n },\n handleUnsubscribe,\n}: IUnsubscribe) => {\n return (\n <Suspense fallback={<div>Unsubscribing...</div>}>\n <UnsubscribeInSuspense classNames={classNames} handleUnsubscribe={handleUnsubscribe}>\n {children}\n </UnsubscribeInSuspense>\n </Suspense>\n )\n}\n\nexport const UnsubscribeInSuspense = ({\n children,\n classNames = {\n button: '',\n container: '',\n emailInput: '',\n error: '',\n form: '',\n loading: '',\n message: '',\n },\n handleUnsubscribe,\n}: IUnsubscribe) => {\n const { isError, isLoading, result, unsubscribe } = useUnsubscribe({ handleUnsubscribe })\n\n const searchParams = useSearchParams()\n const email = searchParams.get('email')\n const hash = searchParams.get('hash')\n\n useEffect(() => {\n async function callUnsubscribe() {\n if (email && hash) {\n await unsubscribe({ email, hash })\n }\n }\n void callUnsubscribe()\n }, [email, hash, unsubscribe])\n\n return (\n <div\n className={mergeClassNames([\n 'subscribers-callUnsubscribe subscribers-container',\n styles.container,\n classNames.container,\n ])}\n >\n {isLoading && (\n <p className={mergeClassNames(['subscribers-loading', styles.loading, classNames.loading])}>\n unsubscribing...\n </p>\n )}\n {!isLoading && (\n <>\n <p\n className={mergeClassNames([\n 'subscribers-message',\n styles.message,\n classNames.message,\n isError ? ['subscribers-error', styles.error, classNames.error] : [],\n ])}\n >\n {result}\n </p>\n <div className={mergeClassNames(['subscribers-form', styles.form, classNames.form])}>\n {children}\n </div>\n </>\n )}\n </div>\n )\n}\n"],"names":["useSearchParams","Suspense","useEffect","useUnsubscribe","mergeClassNames","styles","Unsubscribe","children","classNames","button","container","emailInput","error","form","loading","message","handleUnsubscribe","fallback","div","UnsubscribeInSuspense","isError","isLoading","result","unsubscribe","searchParams","email","get","hash","callUnsubscribe","className","p"],"mappings":"AAAA;;AAEA,SAASA,eAAe,QAAQ,qBAAoB;AACpD,SAASC,QAAQ,EAAEC,SAAS,QAAQ,QAAO;AAM3C,SAASC,cAAc,QAAQ,gCAA+B;AAC9D,SAASC,eAAe,QAAQ,eAAc;AAC9C,OAAOC,YAAY,sBAAqB;AAwCxC;;;;;;;;;CASC,GACD,OAAO,MAAMC,cAAc,CAAC,EAC1BC,QAAQ,EACRC,aAAa;IACXC,QAAQ;IACRC,WAAW;IACXC,YAAY;IACZC,OAAO;IACPC,MAAM;IACNC,SAAS;IACTC,SAAS;AACX,CAAC,EACDC,iBAAiB,EACJ;IACb,qBACE,KAACf;QAASgB,wBAAU,KAACC;sBAAI;;kBACvB,cAAA,KAACC;YAAsBX,YAAYA;YAAYQ,mBAAmBA;sBAC/DT;;;AAIT,EAAC;AAED,OAAO,MAAMY,wBAAwB,CAAC,EACpCZ,QAAQ,EACRC,aAAa;IACXC,QAAQ;IACRC,WAAW;IACXC,YAAY;IACZC,OAAO;IACPC,MAAM;IACNC,SAAS;IACTC,SAAS;AACX,CAAC,EACDC,iBAAiB,EACJ;IACb,MAAM,EAAEI,OAAO,EAAEC,SAAS,EAAEC,MAAM,EAAEC,WAAW,EAAE,GAAGpB,eAAe;QAAEa;IAAkB;IAEvF,MAAMQ,eAAexB;IACrB,MAAMyB,QAAQD,aAAaE,GAAG,CAAC;IAC/B,MAAMC,OAAOH,aAAaE,GAAG,CAAC;IAE9BxB,UAAU;QACR,eAAe0B;YACb,IAAIH,SAASE,MAAM;gBACjB,MAAMJ,YAAY;oBAAEE;oBAAOE;gBAAK;YAClC;QACF;QACA,KAAKC;IACP,GAAG;QAACH;QAAOE;QAAMJ;KAAY;IAE7B,qBACE,MAACL;QACCW,WAAWzB,gBAAgB;YACzB;YACAC,OAAOK,SAAS;YAChBF,WAAWE,SAAS;SACrB;;YAEAW,2BACC,KAACS;gBAAED,WAAWzB,gBAAgB;oBAAC;oBAAuBC,OAAOS,OAAO;oBAAEN,WAAWM,OAAO;iBAAC;0BAAG;;YAI7F,CAACO,2BACA;;kCACE,KAACS;wBACCD,WAAWzB,gBAAgB;4BACzB;4BACAC,OAAOU,OAAO;4BACdP,WAAWO,OAAO;4BAClBK,UAAU;gCAAC;gCAAqBf,OAAOO,KAAK;gCAAEJ,WAAWI,KAAK;6BAAC,GAAG,EAAE;yBACrE;kCAEAU;;kCAEH,KAACJ;wBAAIW,WAAWzB,gBAAgB;4BAAC;4BAAoBC,OAAOQ,IAAI;4BAAEL,WAAWK,IAAI;yBAAC;kCAC/EN;;;;;;AAMb,EAAC"}
|
|
@@ -51,3 +51,4 @@ export type VerifyMagicLinkClasses = {
|
|
|
51
51
|
* @returns Loading status, error/result message, and children. Shows RequestMagicLink when no token/email.
|
|
52
52
|
*/
|
|
53
53
|
export declare const VerifyMagicLink: ({ children, classNames, handleMagicLinkRequested, handleMagicLinkVerified, verifyData, }: IVerifyMagicLink) => import("react").JSX.Element;
|
|
54
|
+
export declare const VerifyMagicLinkInSuspense: ({ children, classNames, handleMagicLinkRequested, handleMagicLinkVerified, verifyData, }: IVerifyMagicLink) => import("react").JSX.Element;
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
3
3
|
import { useSearchParams } from 'next/navigation.js';
|
|
4
|
-
import { useEffect, useState } from 'react';
|
|
5
|
-
import { RequestMagicLink
|
|
4
|
+
import { Suspense, useEffect, useState } from 'react';
|
|
5
|
+
import { RequestMagicLink } from '../../exports/ui.js';
|
|
6
6
|
import { useRequestMagicLink } from '../../hooks/useRequestMagicLink.js';
|
|
7
7
|
import { useVerifyMagicLink } from '../../hooks/useVerifyMagicLink.js';
|
|
8
8
|
import { mergeClassNames } from './helpers.js';
|
|
@@ -27,24 +27,39 @@ import styles from './shared.module.css';
|
|
|
27
27
|
form: '',
|
|
28
28
|
loading: '',
|
|
29
29
|
message: ''
|
|
30
|
+
}, handleMagicLinkRequested, handleMagicLinkVerified, verifyData })=>{
|
|
31
|
+
return /*#__PURE__*/ _jsx(Suspense, {
|
|
32
|
+
fallback: /*#__PURE__*/ _jsx("div", {
|
|
33
|
+
children: "Verifying..."
|
|
34
|
+
}),
|
|
35
|
+
children: /*#__PURE__*/ _jsx(VerifyMagicLinkInSuspense, {
|
|
36
|
+
classNames: classNames,
|
|
37
|
+
handleMagicLinkRequested: handleMagicLinkRequested,
|
|
38
|
+
handleMagicLinkVerified: handleMagicLinkVerified,
|
|
39
|
+
verifyData: verifyData,
|
|
40
|
+
children: children
|
|
41
|
+
})
|
|
42
|
+
});
|
|
43
|
+
};
|
|
44
|
+
export const VerifyMagicLinkInSuspense = ({ children, classNames = {
|
|
45
|
+
button: '',
|
|
46
|
+
container: '',
|
|
47
|
+
emailInput: '',
|
|
48
|
+
error: '',
|
|
49
|
+
form: '',
|
|
50
|
+
loading: '',
|
|
51
|
+
message: ''
|
|
30
52
|
}, handleMagicLinkRequested, handleMagicLinkVerified, verifyData })=>{
|
|
31
53
|
const searchParams = useSearchParams();
|
|
32
54
|
const email = searchParams.get('email');
|
|
33
55
|
const token = searchParams.get('token');
|
|
34
|
-
const { subscriber } = useSubscriber();
|
|
35
56
|
const { isError: verifyIsError, isLoading: verifyIsLoading, result: verifyResult, verify } = useVerifyMagicLink();
|
|
36
57
|
useEffect(()=>{
|
|
37
|
-
async
|
|
58
|
+
const asyncVerify = async ()=>{
|
|
38
59
|
await verify();
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
void asyncVerify();
|
|
42
|
-
} else {
|
|
43
|
-
setIsError(false);
|
|
44
|
-
setResult('Already logged in');
|
|
45
|
-
}
|
|
60
|
+
};
|
|
61
|
+
void asyncVerify();
|
|
46
62
|
}, [
|
|
47
|
-
subscriber,
|
|
48
63
|
verify
|
|
49
64
|
]);
|
|
50
65
|
useEffect(()=>{
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/components/app/VerifyMagicLink.tsx"],"sourcesContent":["'use client'\n\nimport { useSearchParams } from 'next/navigation.js'\nimport { useEffect, useState } from 'react'\n\nimport type { RequestMagicLinkResponse } from '../../endpoints/requestMagicLink.js'\nimport type { VerifyMagicLinkResponse } from '../../endpoints/verifyMagicLink.js'\n\nexport { VerifyMagicLinkResponse }\nimport { RequestMagicLink, useSubscriber } from '../../exports/ui.js'\nimport { useRequestMagicLink } from '../../hooks/useRequestMagicLink.js'\nimport { useVerifyMagicLink } from '../../hooks/useVerifyMagicLink.js'\nimport { mergeClassNames } from './helpers.js'\nimport styles from './shared.module.css'\n\n// const payload = await getPayload({\n// config: configPromise,\n// })\n\n/**\n * Props for the VerifyMagicLink component.\n *\n * @property children - Optional React nodes rendered after the verify action (e.g. when error)\n * @property classNames - Optional CSS class overrides for the component elements\n * @property handleMagicLinkRequested - Callback when a new magic link is requested\n * @property handleMagicLinkVerified - Callback when the magic link is verified\n * @property verifyData - Optional data for verification (e.g. email/token from URL)\n */\nexport interface IVerifyMagicLink {\n children?: React.ReactNode\n classNames?: VerifyMagicLinkClasses\n handleMagicLinkRequested?: (result: RequestMagicLinkResponse) => void\n handleMagicLinkVerified?: (result: string) => void\n verifyData?: string\n}\n\n/**\n * Optional CSS class overrides for VerifyMagicLink elements.\n *\n * @property button - Class for buttons\n * @property container - Class for the main container\n * @property emailInput - Class for the email input field\n * @property error - Class for error messages\n * @property form - Class for the form\n * @property loading - Class for loading state\n * @property message - Class for result message text\n */\nexport type VerifyMagicLinkClasses = {\n button?: string\n container?: string\n emailInput?: string\n error?: string\n form?: string\n loading?: string\n message?: string\n}\n\n/**\n * Handles the verify step of magic-link flow. When URL has email and token query params, calls\n * POST /api/verifyToken to verify and log in; otherwise shows RequestMagicLink. Supports\n * \"Request another magic link\" and optional callbacks.\n *\n * @param props - Component props (see IVerifyMagicLink)\n * @param props.children - Optional React nodes rendered after the verify action (e.g. when error)\n * @param props.classNames - Optional class overrides for the component elements\n * @param props.handleMagicLinkRequested - Callback when a new magic link is requested\n * @param props.handleMagicLinkVerified - Callback when the magic link is verified\n * @param props.verifyData - Optional data for verification (e.g. email/token from URL)\n * @returns Loading status, error/result message, and children. Shows RequestMagicLink when no token/email.\n */\nexport const VerifyMagicLink = ({\n children,\n classNames = {\n button: '',\n container: '',\n emailInput: '',\n error: '',\n form: '',\n loading: '',\n message: '',\n },\n handleMagicLinkRequested,\n handleMagicLinkVerified,\n verifyData,\n}: IVerifyMagicLink) => {\n const searchParams = useSearchParams()\n const email = searchParams.get('email')\n const token = searchParams.get('token')\n\n const {
|
|
1
|
+
{"version":3,"sources":["../../../src/components/app/VerifyMagicLink.tsx"],"sourcesContent":["'use client'\n\nimport { useSearchParams } from 'next/navigation.js'\nimport { Suspense, useEffect, useState } from 'react'\n\nimport type { RequestMagicLinkResponse } from '../../endpoints/requestMagicLink.js'\nimport type { VerifyMagicLinkResponse } from '../../endpoints/verifyMagicLink.js'\n\nexport { VerifyMagicLinkResponse }\nimport { RequestMagicLink, useSubscriber } from '../../exports/ui.js'\nimport { useRequestMagicLink } from '../../hooks/useRequestMagicLink.js'\nimport { useVerifyMagicLink } from '../../hooks/useVerifyMagicLink.js'\nimport { mergeClassNames } from './helpers.js'\nimport styles from './shared.module.css'\n\n// const payload = await getPayload({\n// config: configPromise,\n// })\n\n/**\n * Props for the VerifyMagicLink component.\n *\n * @property children - Optional React nodes rendered after the verify action (e.g. when error)\n * @property classNames - Optional CSS class overrides for the component elements\n * @property handleMagicLinkRequested - Callback when a new magic link is requested\n * @property handleMagicLinkVerified - Callback when the magic link is verified\n * @property verifyData - Optional data for verification (e.g. email/token from URL)\n */\nexport interface IVerifyMagicLink {\n children?: React.ReactNode\n classNames?: VerifyMagicLinkClasses\n handleMagicLinkRequested?: (result: RequestMagicLinkResponse) => void\n handleMagicLinkVerified?: (result: string) => void\n verifyData?: string\n}\n\n/**\n * Optional CSS class overrides for VerifyMagicLink elements.\n *\n * @property button - Class for buttons\n * @property container - Class for the main container\n * @property emailInput - Class for the email input field\n * @property error - Class for error messages\n * @property form - Class for the form\n * @property loading - Class for loading state\n * @property message - Class for result message text\n */\nexport type VerifyMagicLinkClasses = {\n button?: string\n container?: string\n emailInput?: string\n error?: string\n form?: string\n loading?: string\n message?: string\n}\n\n/**\n * Handles the verify step of magic-link flow. When URL has email and token query params, calls\n * POST /api/verifyToken to verify and log in; otherwise shows RequestMagicLink. Supports\n * \"Request another magic link\" and optional callbacks.\n *\n * @param props - Component props (see IVerifyMagicLink)\n * @param props.children - Optional React nodes rendered after the verify action (e.g. when error)\n * @param props.classNames - Optional class overrides for the component elements\n * @param props.handleMagicLinkRequested - Callback when a new magic link is requested\n * @param props.handleMagicLinkVerified - Callback when the magic link is verified\n * @param props.verifyData - Optional data for verification (e.g. email/token from URL)\n * @returns Loading status, error/result message, and children. Shows RequestMagicLink when no token/email.\n */\nexport const VerifyMagicLink = ({\n children,\n classNames = {\n button: '',\n container: '',\n emailInput: '',\n error: '',\n form: '',\n loading: '',\n message: '',\n },\n handleMagicLinkRequested,\n handleMagicLinkVerified,\n verifyData,\n}: IVerifyMagicLink) => {\n return (\n <Suspense fallback={<div>Verifying...</div>}>\n <VerifyMagicLinkInSuspense\n classNames={classNames}\n handleMagicLinkRequested={handleMagicLinkRequested}\n handleMagicLinkVerified={handleMagicLinkVerified}\n verifyData={verifyData}\n >\n {children}\n </VerifyMagicLinkInSuspense>\n </Suspense>\n )\n}\n\nexport const VerifyMagicLinkInSuspense = ({\n children,\n classNames = {\n button: '',\n container: '',\n emailInput: '',\n error: '',\n form: '',\n loading: '',\n message: '',\n },\n handleMagicLinkRequested,\n handleMagicLinkVerified,\n verifyData,\n}: IVerifyMagicLink) => {\n const searchParams = useSearchParams()\n const email = searchParams.get('email')\n const token = searchParams.get('token')\n\n const {\n isError: verifyIsError,\n isLoading: verifyIsLoading,\n result: verifyResult,\n verify,\n } = useVerifyMagicLink()\n\n useEffect(() => {\n const asyncVerify = async () => {\n await verify()\n }\n void asyncVerify()\n }, [verify])\n\n useEffect(() => {\n setResult(verifyResult)\n setIsError(verifyIsError)\n setIsLoading(verifyIsLoading)\n if (!verifyIsError && handleMagicLinkVerified) {\n handleMagicLinkVerified(verifyResult)\n }\n }, [handleMagicLinkVerified, verifyResult, verifyIsError, verifyIsLoading])\n\n const [result, setResult] = useState<string>()\n const [isError, setIsError] = useState<boolean>(false)\n const [isLoading, setIsLoading] = useState<boolean>(false)\n\n const {\n result: requestResult,\n sendMagicLink,\n status: requestStatus,\n } = useRequestMagicLink({\n handleMagicLinkRequested,\n verifyData,\n })\n\n useEffect(() => {\n setIsError(requestStatus == 'error')\n setResult(requestResult)\n setIsLoading(false)\n }, [requestResult, requestStatus])\n\n const handleRequestAnother = () => {\n if (email) {\n void sendMagicLink(email)\n }\n }\n\n return (\n <>\n {(!email || !token) && <RequestMagicLink classNames={classNames} />}\n {email && token && (\n <div\n className={mergeClassNames([\n 'subscribers-verify subscribers-container',\n styles.container,\n classNames.container,\n ])}\n >\n {isLoading && (\n <p\n className={mergeClassNames([\n 'subscribers-loading',\n styles.loading,\n classNames.loading,\n ])}\n >\n verifying...\n </p>\n )}\n {!isLoading && result && (\n <p\n className={mergeClassNames([\n 'subscribers-message',\n styles.message,\n classNames.message,\n isError ? ['subscribers-error', styles.error, classNames.error] : [],\n ])}\n >\n {result}\n </p>\n )}\n <div className={mergeClassNames(['subscribers-form', styles.form, classNames.form])}>\n {result && isError && (\n <button\n className={mergeClassNames([\n 'subscribers-button',\n styles.button,\n classNames.button,\n ])}\n name={'request'}\n onClick={handleRequestAnother}\n type=\"button\"\n >\n {'Request another magic link'}\n </button>\n )}\n {result && children}\n </div>\n </div>\n )}\n </>\n )\n}\n"],"names":["useSearchParams","Suspense","useEffect","useState","RequestMagicLink","useRequestMagicLink","useVerifyMagicLink","mergeClassNames","styles","VerifyMagicLink","children","classNames","button","container","emailInput","error","form","loading","message","handleMagicLinkRequested","handleMagicLinkVerified","verifyData","fallback","div","VerifyMagicLinkInSuspense","searchParams","email","get","token","isError","verifyIsError","isLoading","verifyIsLoading","result","verifyResult","verify","asyncVerify","setResult","setIsError","setIsLoading","requestResult","sendMagicLink","status","requestStatus","handleRequestAnother","className","p","name","onClick","type"],"mappings":"AAAA;;AAEA,SAASA,eAAe,QAAQ,qBAAoB;AACpD,SAASC,QAAQ,EAAEC,SAAS,EAAEC,QAAQ,QAAQ,QAAO;AAMrD,SAASC,gBAAgB,QAAuB,sBAAqB;AACrE,SAASC,mBAAmB,QAAQ,qCAAoC;AACxE,SAASC,kBAAkB,QAAQ,oCAAmC;AACtE,SAASC,eAAe,QAAQ,eAAc;AAC9C,OAAOC,YAAY,sBAAqB;AA4CxC;;;;;;;;;;;;CAYC,GACD,OAAO,MAAMC,kBAAkB,CAAC,EAC9BC,QAAQ,EACRC,aAAa;IACXC,QAAQ;IACRC,WAAW;IACXC,YAAY;IACZC,OAAO;IACPC,MAAM;IACNC,SAAS;IACTC,SAAS;AACX,CAAC,EACDC,wBAAwB,EACxBC,uBAAuB,EACvBC,UAAU,EACO;IACjB,qBACE,KAACpB;QAASqB,wBAAU,KAACC;sBAAI;;kBACvB,cAAA,KAACC;YACCb,YAAYA;YACZQ,0BAA0BA;YAC1BC,yBAAyBA;YACzBC,YAAYA;sBAEXX;;;AAIT,EAAC;AAED,OAAO,MAAMc,4BAA4B,CAAC,EACxCd,QAAQ,EACRC,aAAa;IACXC,QAAQ;IACRC,WAAW;IACXC,YAAY;IACZC,OAAO;IACPC,MAAM;IACNC,SAAS;IACTC,SAAS;AACX,CAAC,EACDC,wBAAwB,EACxBC,uBAAuB,EACvBC,UAAU,EACO;IACjB,MAAMI,eAAezB;IACrB,MAAM0B,QAAQD,aAAaE,GAAG,CAAC;IAC/B,MAAMC,QAAQH,aAAaE,GAAG,CAAC;IAE/B,MAAM,EACJE,SAASC,aAAa,EACtBC,WAAWC,eAAe,EAC1BC,QAAQC,YAAY,EACpBC,MAAM,EACP,GAAG7B;IAEJJ,UAAU;QACR,MAAMkC,cAAc;YAClB,MAAMD;QACR;QACA,KAAKC;IACP,GAAG;QAACD;KAAO;IAEXjC,UAAU;QACRmC,UAAUH;QACVI,WAAWR;QACXS,aAAaP;QACb,IAAI,CAACF,iBAAiBV,yBAAyB;YAC7CA,wBAAwBc;QAC1B;IACF,GAAG;QAACd;QAAyBc;QAAcJ;QAAeE;KAAgB;IAE1E,MAAM,CAACC,QAAQI,UAAU,GAAGlC;IAC5B,MAAM,CAAC0B,SAASS,WAAW,GAAGnC,SAAkB;IAChD,MAAM,CAAC4B,WAAWQ,aAAa,GAAGpC,SAAkB;IAEpD,MAAM,EACJ8B,QAAQO,aAAa,EACrBC,aAAa,EACbC,QAAQC,aAAa,EACtB,GAAGtC,oBAAoB;QACtBc;QACAE;IACF;IAEAnB,UAAU;QACRoC,WAAWK,iBAAiB;QAC5BN,UAAUG;QACVD,aAAa;IACf,GAAG;QAACC;QAAeG;KAAc;IAEjC,MAAMC,uBAAuB;QAC3B,IAAIlB,OAAO;YACT,KAAKe,cAAcf;QACrB;IACF;IAEA,qBACE;;YACI,CAAA,CAACA,SAAS,CAACE,KAAI,mBAAM,KAACxB;gBAAiBO,YAAYA;;YACpDe,SAASE,uBACR,MAACL;gBACCsB,WAAWtC,gBAAgB;oBACzB;oBACAC,OAAOK,SAAS;oBAChBF,WAAWE,SAAS;iBACrB;;oBAEAkB,2BACC,KAACe;wBACCD,WAAWtC,gBAAgB;4BACzB;4BACAC,OAAOS,OAAO;4BACdN,WAAWM,OAAO;yBACnB;kCACF;;oBAIF,CAACc,aAAaE,wBACb,KAACa;wBACCD,WAAWtC,gBAAgB;4BACzB;4BACAC,OAAOU,OAAO;4BACdP,WAAWO,OAAO;4BAClBW,UAAU;gCAAC;gCAAqBrB,OAAOO,KAAK;gCAAEJ,WAAWI,KAAK;6BAAC,GAAG,EAAE;yBACrE;kCAEAkB;;kCAGL,MAACV;wBAAIsB,WAAWtC,gBAAgB;4BAAC;4BAAoBC,OAAOQ,IAAI;4BAAEL,WAAWK,IAAI;yBAAC;;4BAC/EiB,UAAUJ,yBACT,KAACjB;gCACCiC,WAAWtC,gBAAgB;oCACzB;oCACAC,OAAOI,MAAM;oCACbD,WAAWC,MAAM;iCAClB;gCACDmC,MAAM;gCACNC,SAASJ;gCACTK,MAAK;0CAEJ;;4BAGJhB,UAAUvB;;;;;;;AAMvB,EAAC"}
|
|
@@ -18,36 +18,47 @@ const SubscriberContext = /*#__PURE__*/ createContext(undefined);
|
|
|
18
18
|
// Keep track of if the selection content is loaded yet
|
|
19
19
|
const [isLoaded, setIsLoaded] = useState(false);
|
|
20
20
|
const [permissions, setPermissions] = useState();
|
|
21
|
-
const
|
|
22
|
-
|
|
23
|
-
|
|
21
|
+
const initSubscriber = useCallback(async ()=>{
|
|
22
|
+
console.log('initSubscriber', serverURL);
|
|
23
|
+
setIsLoaded(false);
|
|
24
|
+
if (serverURL) {
|
|
24
25
|
try {
|
|
25
|
-
const authResponse = await fetch(
|
|
26
|
+
const authResponse = await fetch(`${serverURL}/api/subscriberAuth`, {
|
|
26
27
|
// body: JSON.stringify({}),
|
|
27
28
|
method: 'POST'
|
|
28
29
|
});
|
|
29
30
|
if (authResponse.ok) {
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
31
|
+
try {
|
|
32
|
+
const authResponseJson = await authResponse.json();
|
|
33
|
+
// console.log('authResponseJson', JSON.stringify(authResponseJson, undefined, 2))
|
|
34
|
+
const { permissions, subscriber } = authResponseJson;
|
|
35
|
+
console.log(`subscriber = `, subscriber);
|
|
36
|
+
// console.log(`permissions = `, permissions)
|
|
37
|
+
setPermissions(permissions);
|
|
38
|
+
setSubscriber(subscriber);
|
|
39
|
+
} catch (error) {
|
|
40
|
+
console.log('authResponse error, with json:', error);
|
|
41
|
+
const authResponseText = await authResponse.text();
|
|
42
|
+
console.log('authResponse error, text:', authResponseText);
|
|
43
|
+
}
|
|
38
44
|
} else {
|
|
45
|
+
console.log('authResponse not ok', authResponse);
|
|
39
46
|
setPermissions(null);
|
|
40
47
|
setSubscriber(null);
|
|
41
48
|
}
|
|
49
|
+
setIsLoaded(true);
|
|
42
50
|
} catch (error) {
|
|
43
51
|
console.log(`authResponse error`, error);
|
|
44
52
|
}
|
|
45
|
-
|
|
46
|
-
};
|
|
47
|
-
await initSubscriber();
|
|
53
|
+
}
|
|
48
54
|
}, [
|
|
49
55
|
serverURL
|
|
50
56
|
]);
|
|
57
|
+
const refreshSubscriber = useCallback(async ()=>{
|
|
58
|
+
await initSubscriber();
|
|
59
|
+
}, [
|
|
60
|
+
initSubscriber
|
|
61
|
+
]);
|
|
51
62
|
const logOut = useCallback(async ()=>{
|
|
52
63
|
setIsLoaded(false);
|
|
53
64
|
try {
|
|
@@ -74,9 +85,9 @@ const SubscriberContext = /*#__PURE__*/ createContext(undefined);
|
|
|
74
85
|
setIsLoaded(true);
|
|
75
86
|
}, []);
|
|
76
87
|
useEffect(()=>{
|
|
77
|
-
void
|
|
88
|
+
void initSubscriber();
|
|
78
89
|
}, [
|
|
79
|
-
|
|
90
|
+
initSubscriber
|
|
80
91
|
]);
|
|
81
92
|
// Memoize the value to prevent unnecessary re-renders in consumers
|
|
82
93
|
const contextValue = useMemo(()=>({
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/contexts/SubscriberProvider.tsx"],"sourcesContent":["'use client'\n\nimport { PayloadSDK } from '@payloadcms/sdk'\nimport { type ReactNode, useCallback, useEffect } from 'react'\nimport { createContext, useContext, useMemo, useState } from 'react'\n\nimport type { Config, OptInChannel, Subscriber } from '../copied/payload-types.js'\n\nimport { useServerUrl } from '../react-hooks/useServerUrl.js'\n\n/** Value provided by SubscriberProvider: current subscriber, auth state, and actions. */\nexport type SubscriberContextType = {\n isLoaded: boolean\n logOut: () => void\n permissions: any\n refreshSubscriber: () => void\n subscriber: ({ optIns?: null | OptInChannel[] } & Omit<Subscriber, 'optIns'>) | null\n}\n\nconst SubscriberContext = createContext<SubscriberContextType | undefined>(undefined)\n\n/** Props for SubscriberProvider. */\ninterface ProviderProps {\n children?: ReactNode\n}\n\n/**\n * Provider that fetches and holds the current subscriber auth state (via POST /api/subscriberAuth).\n * Exposes subscriber, permissions, refreshSubscriber, and logOut to descendants. Must wrap any\n * component that uses useSubscriber().\n *\n * @param props.children - React tree to wrap\n * @returns SubscriberContext.Provider with current auth state and actions\n */\nexport function SubscriberProvider({ children }: ProviderProps) {\n // eslint-disable-next-line\n const [subscriber, setSubscriber] = useState<null | (Subscriber & { optIns: OptInChannel[] })>(\n null,\n )\n\n const { serverURL } = useServerUrl()\n\n // Keep track of if the selection content is loaded yet\n const [isLoaded, setIsLoaded] = useState(false)\n\n const [permissions, setPermissions] = useState<any>()\n\n const
|
|
1
|
+
{"version":3,"sources":["../../src/contexts/SubscriberProvider.tsx"],"sourcesContent":["'use client'\n\nimport { PayloadSDK } from '@payloadcms/sdk'\nimport { type ReactNode, useCallback, useEffect } from 'react'\nimport { createContext, useContext, useMemo, useState } from 'react'\n\nimport type { Config, OptInChannel, Subscriber } from '../copied/payload-types.js'\n\nimport { useServerUrl } from '../react-hooks/useServerUrl.js'\n\n/** Value provided by SubscriberProvider: current subscriber, auth state, and actions. */\nexport type SubscriberContextType = {\n isLoaded: boolean\n logOut: () => void\n permissions: any\n refreshSubscriber: () => void\n subscriber: ({ optIns?: null | OptInChannel[] } & Omit<Subscriber, 'optIns'>) | null\n}\n\nconst SubscriberContext = createContext<SubscriberContextType | undefined>(undefined)\n\n/** Props for SubscriberProvider. */\ninterface ProviderProps {\n children?: ReactNode\n}\n\n/**\n * Provider that fetches and holds the current subscriber auth state (via POST /api/subscriberAuth).\n * Exposes subscriber, permissions, refreshSubscriber, and logOut to descendants. Must wrap any\n * component that uses useSubscriber().\n *\n * @param props.children - React tree to wrap\n * @returns SubscriberContext.Provider with current auth state and actions\n */\nexport function SubscriberProvider({ children }: ProviderProps) {\n // eslint-disable-next-line\n const [subscriber, setSubscriber] = useState<null | (Subscriber & { optIns: OptInChannel[] })>(\n null,\n )\n\n const { serverURL } = useServerUrl()\n\n // Keep track of if the selection content is loaded yet\n const [isLoaded, setIsLoaded] = useState(false)\n\n const [permissions, setPermissions] = useState<any>()\n\n const initSubscriber = useCallback(async () => {\n console.log('initSubscriber', serverURL)\n setIsLoaded(false)\n if (serverURL) {\n try {\n const authResponse = await fetch(`${serverURL}/api/subscriberAuth`, {\n // body: JSON.stringify({}),\n method: 'POST',\n })\n\n if (authResponse.ok) {\n try {\n const authResponseJson = await authResponse.json()\n // console.log('authResponseJson', JSON.stringify(authResponseJson, undefined, 2))\n const { permissions, subscriber } = authResponseJson\n console.log(`subscriber = `, subscriber)\n // console.log(`permissions = `, permissions)\n setPermissions(permissions)\n setSubscriber(subscriber)\n } catch (error) {\n console.log('authResponse error, with json:', error)\n const authResponseText = await authResponse.text()\n console.log('authResponse error, text:', authResponseText)\n }\n } else {\n console.log('authResponse not ok', authResponse)\n setPermissions(null)\n setSubscriber(null)\n }\n setIsLoaded(true)\n } catch (error: unknown) {\n console.log(`authResponse error`, error)\n }\n }\n }, [serverURL])\n\n const refreshSubscriber = useCallback(async () => {\n await initSubscriber()\n }, [initSubscriber])\n\n const logOut = useCallback(async () => {\n setIsLoaded(false)\n try {\n // const sdk = new PayloadSDK<Config>({\n // baseURL: serverURL || '',\n // })\n // const logoutResponse = await sdk.request({\n // json: {},\n // method: 'POST',\n // path: '/api/logout',\n // })\n // Unsure why sdk isn't working here\n const logoutResponse = await fetch('/api/logout', {\n method: 'POST',\n })\n\n // console.log(`logoutResponse`, logoutResponse)\n\n if (logoutResponse.ok) {\n setSubscriber(null)\n setPermissions(null)\n }\n } catch (error: unknown) {\n console.log(`logoutResponse error`, error)\n }\n setIsLoaded(true)\n }, [])\n\n useEffect(() => {\n void initSubscriber()\n }, [initSubscriber])\n\n // Memoize the value to prevent unnecessary re-renders in consumers\n const contextValue: SubscriberContextType = useMemo(\n () => ({\n isLoaded,\n logOut,\n permissions,\n refreshSubscriber,\n subscriber,\n }),\n [isLoaded, logOut, permissions, refreshSubscriber, subscriber],\n )\n\n return <SubscriberContext.Provider value={contextValue}>{children}</SubscriberContext.Provider>\n}\n\n/**\n * Consumes SubscriberContext. Use only inside a SubscriberProvider.\n *\n * @returns Current subscriber (or null), permissions, isLoaded, refreshSubscriber, and logOut\n * @throws Error if used outside SubscriberProvider\n */\nexport function useSubscriber() {\n const context = useContext(SubscriberContext)\n if (context === undefined) {\n throw new Error('useSubscriber must be used within a SubscriberProvider')\n }\n return context\n}\n"],"names":["useCallback","useEffect","createContext","useContext","useMemo","useState","useServerUrl","SubscriberContext","undefined","SubscriberProvider","children","subscriber","setSubscriber","serverURL","isLoaded","setIsLoaded","permissions","setPermissions","initSubscriber","console","log","authResponse","fetch","method","ok","authResponseJson","json","error","authResponseText","text","refreshSubscriber","logOut","logoutResponse","contextValue","Provider","value","useSubscriber","context","Error"],"mappings":"AAAA;;AAGA,SAAyBA,WAAW,EAAEC,SAAS,QAAQ,QAAO;AAC9D,SAASC,aAAa,EAAEC,UAAU,EAAEC,OAAO,EAAEC,QAAQ,QAAQ,QAAO;AAIpE,SAASC,YAAY,QAAQ,iCAAgC;AAW7D,MAAMC,kCAAoBL,cAAiDM;AAO3E;;;;;;;CAOC,GACD,OAAO,SAASC,mBAAmB,EAAEC,QAAQ,EAAiB;IAC5D,2BAA2B;IAC3B,MAAM,CAACC,YAAYC,cAAc,GAAGP,SAClC;IAGF,MAAM,EAAEQ,SAAS,EAAE,GAAGP;IAEtB,uDAAuD;IACvD,MAAM,CAACQ,UAAUC,YAAY,GAAGV,SAAS;IAEzC,MAAM,CAACW,aAAaC,eAAe,GAAGZ;IAEtC,MAAMa,iBAAiBlB,YAAY;QACjCmB,QAAQC,GAAG,CAAC,kBAAkBP;QAC9BE,YAAY;QACZ,IAAIF,WAAW;YACb,IAAI;gBACF,MAAMQ,eAAe,MAAMC,MAAM,GAAGT,UAAU,mBAAmB,CAAC,EAAE;oBAClE,4BAA4B;oBAC5BU,QAAQ;gBACV;gBAEA,IAAIF,aAAaG,EAAE,EAAE;oBACnB,IAAI;wBACF,MAAMC,mBAAmB,MAAMJ,aAAaK,IAAI;wBAChD,kFAAkF;wBAClF,MAAM,EAAEV,WAAW,EAAEL,UAAU,EAAE,GAAGc;wBACpCN,QAAQC,GAAG,CAAC,CAAC,aAAa,CAAC,EAAET;wBAC7B,6CAA6C;wBAC7CM,eAAeD;wBACfJ,cAAcD;oBAChB,EAAE,OAAOgB,OAAO;wBACdR,QAAQC,GAAG,CAAC,kCAAkCO;wBAC9C,MAAMC,mBAAmB,MAAMP,aAAaQ,IAAI;wBAChDV,QAAQC,GAAG,CAAC,6BAA6BQ;oBAC3C;gBACF,OAAO;oBACLT,QAAQC,GAAG,CAAC,uBAAuBC;oBACnCJ,eAAe;oBACfL,cAAc;gBAChB;gBACAG,YAAY;YACd,EAAE,OAAOY,OAAgB;gBACvBR,QAAQC,GAAG,CAAC,CAAC,kBAAkB,CAAC,EAAEO;YACpC;QACF;IACF,GAAG;QAACd;KAAU;IAEd,MAAMiB,oBAAoB9B,YAAY;QACpC,MAAMkB;IACR,GAAG;QAACA;KAAe;IAEnB,MAAMa,SAAS/B,YAAY;QACzBe,YAAY;QACZ,IAAI;YACF,uCAAuC;YACvC,8BAA8B;YAC9B,KAAK;YACL,6CAA6C;YAC7C,cAAc;YACd,oBAAoB;YACpB,yBAAyB;YACzB,KAAK;YACL,oCAAoC;YACpC,MAAMiB,iBAAiB,MAAMV,MAAM,eAAe;gBAChDC,QAAQ;YACV;YAEA,gDAAgD;YAEhD,IAAIS,eAAeR,EAAE,EAAE;gBACrBZ,cAAc;gBACdK,eAAe;YACjB;QACF,EAAE,OAAOU,OAAgB;YACvBR,QAAQC,GAAG,CAAC,CAAC,oBAAoB,CAAC,EAAEO;QACtC;QACAZ,YAAY;IACd,GAAG,EAAE;IAELd,UAAU;QACR,KAAKiB;IACP,GAAG;QAACA;KAAe;IAEnB,mEAAmE;IACnE,MAAMe,eAAsC7B,QAC1C,IAAO,CAAA;YACLU;YACAiB;YACAf;YACAc;YACAnB;QACF,CAAA,GACA;QAACG;QAAUiB;QAAQf;QAAac;QAAmBnB;KAAW;IAGhE,qBAAO,KAACJ,kBAAkB2B,QAAQ;QAACC,OAAOF;kBAAevB;;AAC3D;AAEA;;;;;CAKC,GACD,OAAO,SAAS0B;IACd,MAAMC,UAAUlC,WAAWI;IAC3B,IAAI8B,YAAY7B,WAAW;QACzB,MAAM,IAAI8B,MAAM;IAClB;IACA,OAAOD;AACT"}
|
package/dist/endpoints/logout.js
CHANGED
|
@@ -10,8 +10,9 @@ import { defaultCollectionSlug } from '../collections/Subscribers.js';
|
|
|
10
10
|
*/ function createEndpointLogout({ subscribersCollectionSlug = defaultCollectionSlug }) {
|
|
11
11
|
const logoutHandler = async (req)=>{
|
|
12
12
|
const headers = await nextHeaders();
|
|
13
|
+
const collectionLogoutEndpoint = `${req.payload.config.serverURL}/api/${subscribersCollectionSlug}/logout`;
|
|
13
14
|
try {
|
|
14
|
-
const logoutResult = await fetch(
|
|
15
|
+
const logoutResult = await fetch(collectionLogoutEndpoint, {
|
|
15
16
|
headers,
|
|
16
17
|
method: 'POST'
|
|
17
18
|
});
|
|
@@ -39,7 +40,7 @@ import { defaultCollectionSlug } from '../collections/Subscribers.js';
|
|
|
39
40
|
} catch (error) {
|
|
40
41
|
// throw new Error(`Logout failed: ${error instanceof Error ? error.message : 'Unknown error'}`)
|
|
41
42
|
return Response.json({
|
|
42
|
-
error: `Logout failed: ${JSON.stringify(error)}`,
|
|
43
|
+
error: `Logout failed: ${collectionLogoutEndpoint} : ${JSON.stringify(error, undefined, 2)}`,
|
|
43
44
|
now: new Date().toISOString()
|
|
44
45
|
}, {
|
|
45
46
|
status: 400
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/endpoints/logout.ts"],"sourcesContent":["import type { CollectionSlug, Endpoint, PayloadHandler } from 'payload'\n\nimport { headers as nextHeaders } from 'next/headers.js'\n\nimport { defaultCollectionSlug } from '../collections/Subscribers.js'\n\nexport type LogoutResponse =\n | {\n error: string\n now: string\n }\n | {\n message: string\n now: string\n }\n\n/**\n * Factory that creates the logout endpoint config and handler.\n * Clears the current subscriber session by delegating to Payload's collection logout.\n *\n * @param options - Config options for the endpoint\n * @param options.subscribersCollectionSlug - Collection slug for subscribers (default from Subscribers collection)\n * @returns Payload Endpoint config for POST /logout\n */\nfunction createEndpointLogout({\n subscribersCollectionSlug = defaultCollectionSlug,\n}: {\n subscribersCollectionSlug: CollectionSlug\n}): Endpoint {\n const logoutHandler: PayloadHandler = async (req) => {\n const headers = await nextHeaders()\n\n
|
|
1
|
+
{"version":3,"sources":["../../src/endpoints/logout.ts"],"sourcesContent":["import type { CollectionSlug, Endpoint, PayloadHandler } from 'payload'\n\nimport { headers as nextHeaders } from 'next/headers.js'\n\nimport { defaultCollectionSlug } from '../collections/Subscribers.js'\n\nexport type LogoutResponse =\n | {\n error: string\n now: string\n }\n | {\n message: string\n now: string\n }\n\n/**\n * Factory that creates the logout endpoint config and handler.\n * Clears the current subscriber session by delegating to Payload's collection logout.\n *\n * @param options - Config options for the endpoint\n * @param options.subscribersCollectionSlug - Collection slug for subscribers (default from Subscribers collection)\n * @returns Payload Endpoint config for POST /logout\n */\nfunction createEndpointLogout({\n subscribersCollectionSlug = defaultCollectionSlug,\n}: {\n subscribersCollectionSlug: CollectionSlug\n}): Endpoint {\n const logoutHandler: PayloadHandler = async (req) => {\n const headers = await nextHeaders()\n\n const collectionLogoutEndpoint = `${req.payload.config.serverURL}/api/${subscribersCollectionSlug}/logout`\n try {\n const logoutResult = await fetch(collectionLogoutEndpoint, {\n headers,\n method: 'POST',\n })\n\n const logoutResultData = await logoutResult.json()\n\n if (logoutResult.ok) {\n return Response.json({\n message: logoutResultData.message,\n now: new Date().toISOString(),\n } as LogoutResponse)\n }\n\n if (\n logoutResult.status == 400 &&\n logoutResultData.errors?.map((e: { message: string }) => e.message).includes('No User')\n ) {\n return Response.json(\n {\n error: `Logout failed: 'No User'`,\n now: new Date().toISOString(),\n } as LogoutResponse,\n {\n status: 400,\n },\n )\n }\n return Response.json(\n {\n error: `Logout failed: ${\n logoutResultData.errors\n ? logoutResultData.errors?.map((e: { message: string }) => e.message).join(' // ')\n : JSON.stringify(logoutResultData)\n }`,\n now: new Date().toISOString(),\n } as LogoutResponse,\n {\n status: 400,\n },\n )\n } catch (error) {\n // throw new Error(`Logout failed: ${error instanceof Error ? error.message : 'Unknown error'}`)\n return Response.json(\n {\n error: `Logout failed: ${collectionLogoutEndpoint} : ${JSON.stringify(error, undefined, 2)}`,\n now: new Date().toISOString(),\n } as LogoutResponse,\n {\n status: 400,\n },\n )\n }\n }\n\n /** Endpoint config for subscriber logout. Mount as POST /logout. */\n const logoutEndpoint: Endpoint = {\n handler: logoutHandler,\n method: 'post',\n path: '/logout',\n }\n\n return logoutEndpoint\n}\n\nexport default createEndpointLogout\n"],"names":["headers","nextHeaders","defaultCollectionSlug","createEndpointLogout","subscribersCollectionSlug","logoutHandler","req","collectionLogoutEndpoint","payload","config","serverURL","logoutResult","fetch","method","logoutResultData","json","ok","Response","message","now","Date","toISOString","status","errors","map","e","includes","error","join","JSON","stringify","undefined","logoutEndpoint","handler","path"],"mappings":"AAEA,SAASA,WAAWC,WAAW,QAAQ,kBAAiB;AAExD,SAASC,qBAAqB,QAAQ,gCAA+B;AAYrE;;;;;;;CAOC,GACD,SAASC,qBAAqB,EAC5BC,4BAA4BF,qBAAqB,EAGlD;IACC,MAAMG,gBAAgC,OAAOC;QAC3C,MAAMN,UAAU,MAAMC;QAEtB,MAAMM,2BAA2B,GAAGD,IAAIE,OAAO,CAACC,MAAM,CAACC,SAAS,CAAC,KAAK,EAAEN,0BAA0B,OAAO,CAAC;QAC1G,IAAI;YACF,MAAMO,eAAe,MAAMC,MAAML,0BAA0B;gBACzDP;gBACAa,QAAQ;YACV;YAEA,MAAMC,mBAAmB,MAAMH,aAAaI,IAAI;YAEhD,IAAIJ,aAAaK,EAAE,EAAE;gBACnB,OAAOC,SAASF,IAAI,CAAC;oBACnBG,SAASJ,iBAAiBI,OAAO;oBACjCC,KAAK,IAAIC,OAAOC,WAAW;gBAC7B;YACF;YAEA,IACEV,aAAaW,MAAM,IAAI,OACvBR,iBAAiBS,MAAM,EAAEC,IAAI,CAACC,IAA2BA,EAAEP,OAAO,EAAEQ,SAAS,YAC7E;gBACA,OAAOT,SAASF,IAAI,CAClB;oBACEY,OAAO,CAAC,wBAAwB,CAAC;oBACjCR,KAAK,IAAIC,OAAOC,WAAW;gBAC7B,GACA;oBACEC,QAAQ;gBACV;YAEJ;YACA,OAAOL,SAASF,IAAI,CAClB;gBACEY,OAAO,CAAC,eAAe,EACrBb,iBAAiBS,MAAM,GACnBT,iBAAiBS,MAAM,EAAEC,IAAI,CAACC,IAA2BA,EAAEP,OAAO,EAAEU,KAAK,UACzEC,KAAKC,SAAS,CAAChB,mBACnB;gBACFK,KAAK,IAAIC,OAAOC,WAAW;YAC7B,GACA;gBACEC,QAAQ;YACV;QAEJ,EAAE,OAAOK,OAAO;YACd,gGAAgG;YAChG,OAAOV,SAASF,IAAI,CAClB;gBACEY,OAAO,CAAC,eAAe,EAAEpB,yBAAyB,GAAG,EAAEsB,KAAKC,SAAS,CAACH,OAAOI,WAAW,IAAI;gBAC5FZ,KAAK,IAAIC,OAAOC,WAAW;YAC7B,GACA;gBACEC,QAAQ;YACV;QAEJ;IACF;IAEA,kEAAkE,GAClE,MAAMU,iBAA2B;QAC/BC,SAAS5B;QACTQ,QAAQ;QACRqB,MAAM;IACR;IAEA,OAAOF;AACT;AAEA,eAAe7B,qBAAoB"}
|
|
@@ -31,23 +31,28 @@ import { useServerUrl } from '../react-hooks/useServerUrl.js';
|
|
|
31
31
|
const { emailResult, error } = emailTokenResponseJson;
|
|
32
32
|
if (error) {
|
|
33
33
|
setStatus('error');
|
|
34
|
-
setResult(`An error occured. Please try again. \n ${error?.error ? error.error : error}`);
|
|
34
|
+
setResult(`An error occured. Please try again. \n ${JSON.stringify(error?.error ? error.error : error, undefined, 2)}`);
|
|
35
|
+
console.log('emailToken error result: ', result);
|
|
35
36
|
} else if (emailResult) {
|
|
36
37
|
setStatus('sent');
|
|
37
38
|
setResult('An email has been sent containing your magic link.');
|
|
39
|
+
console.log('emailToken error result: ', result);
|
|
38
40
|
} else {
|
|
39
41
|
setStatus('error');
|
|
40
42
|
setResult(`An error occured. Please try again. \nResult unknown`);
|
|
43
|
+
console.log('emailToken error result: ', result);
|
|
41
44
|
}
|
|
42
45
|
} else {
|
|
43
46
|
try {
|
|
44
47
|
const emailTokenResponseJson = await emailTokenResponse.json();
|
|
45
48
|
setStatus('error');
|
|
46
|
-
setResult(`An error occured. Please try again. \n${emailTokenResponseJson?.error ? emailTokenResponseJson.error : emailTokenResponseJson}`);
|
|
49
|
+
setResult(`An error occured. Please try again. \n${JSON.stringify(emailTokenResponseJson?.error ? emailTokenResponseJson.error : emailTokenResponseJson, undefined, 2)}`);
|
|
50
|
+
console.log('emailToken error result: ', result);
|
|
47
51
|
} catch (ignore) {
|
|
48
52
|
const emailTokenResponseText = await emailTokenResponse.text();
|
|
49
53
|
setStatus('error');
|
|
50
54
|
setResult(`An error occured. Please try again. \n${emailTokenResponseText}`);
|
|
55
|
+
console.log('emailToken error result: ', result);
|
|
51
56
|
}
|
|
52
57
|
}
|
|
53
58
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/hooks/useRequestMagicLink.tsx"],"sourcesContent":["'use client'\n\nimport { useState } from 'react'\n\nimport type { RequestMagicLinkResponse } from '../endpoints/requestMagicLink.js'\n\nimport { useServerUrl } from '../react-hooks/useServerUrl.js'\n\nexport { RequestMagicLinkResponse }\n\n/**\n * Options for the useRequestMagicLink hook.\n *\n * @property handleMagicLinkRequested - Callback when a magic link is successfully requested\n * @property verifyData - Optional data sent with the request (e.g. for verification redirect)\n */\nexport interface IUseRequestMagicLinkOptions {\n handleMagicLinkRequested?: (result: RequestMagicLinkResponse) => void\n verifyData?: string\n}\n\n/**\n * Return value of useRequestMagicLink.\n *\n * @property result - Success or error message from the last request\n * @property sendMagicLink - Sends a magic link email for the given address\n * @property status - Current status: 'default' | 'sending' | 'sent' | 'error'\n */\nexport interface IUseRequestMagicLink {\n result?: string\n sendMagicLink: (email: string) => Promise<void>\n status?: RequestMagicLinkStatusValue\n}\n\nexport type RequestMagicLinkStatusValue = 'default' | 'error' | 'sending' | 'sent'\n\n/**\n * Hook to request a magic-login link by email. Calls POST /api/emailToken and exposes\n * sendMagicLink, plus result message and status for UI.\n *\n * @param options - Hook options (see IUseRequestMagicLinkOptions)\n * @param options.handleMagicLinkRequested - Callback when a magic link is successfully requested\n * @param options.verifyData - Optional data sent with the request (e.g. for verification redirect)\n * @returns sendMagicLink function, result message, and status (see IUseRequestMagicLink)\n */\nexport const useRequestMagicLink = ({\n handleMagicLinkRequested,\n verifyData,\n}: IUseRequestMagicLinkOptions): IUseRequestMagicLink => {\n const { serverURL } = useServerUrl()\n\n const [status, setStatus] = useState<RequestMagicLinkStatusValue>('default')\n const [result, setResult] = useState<string>()\n\n const sendMagicLink = async (email: string): Promise<void> => {\n setStatus('sending')\n const emailTokenResponse = await fetch(`${serverURL ? serverURL : ''}/api/emailToken`, {\n body: JSON.stringify({\n email,\n verifyData,\n }),\n method: 'POST',\n })\n if (emailTokenResponse.ok) {\n const emailTokenResponseJson: RequestMagicLinkResponse = await emailTokenResponse.json()\n if (handleMagicLinkRequested) {\n handleMagicLinkRequested(emailTokenResponseJson)\n }\n // @ts-expect-error One or the other exists\n const { emailResult, error } = emailTokenResponseJson\n if (error) {\n setStatus('error')\n setResult(`An error occured. Please try again. \\n ${error?.error ? error.error : error}
|
|
1
|
+
{"version":3,"sources":["../../src/hooks/useRequestMagicLink.tsx"],"sourcesContent":["'use client'\n\nimport { useState } from 'react'\n\nimport type { RequestMagicLinkResponse } from '../endpoints/requestMagicLink.js'\n\nimport { useServerUrl } from '../react-hooks/useServerUrl.js'\n\nexport { RequestMagicLinkResponse }\n\n/**\n * Options for the useRequestMagicLink hook.\n *\n * @property handleMagicLinkRequested - Callback when a magic link is successfully requested\n * @property verifyData - Optional data sent with the request (e.g. for verification redirect)\n */\nexport interface IUseRequestMagicLinkOptions {\n handleMagicLinkRequested?: (result: RequestMagicLinkResponse) => void\n verifyData?: string\n}\n\n/**\n * Return value of useRequestMagicLink.\n *\n * @property result - Success or error message from the last request\n * @property sendMagicLink - Sends a magic link email for the given address\n * @property status - Current status: 'default' | 'sending' | 'sent' | 'error'\n */\nexport interface IUseRequestMagicLink {\n result?: string\n sendMagicLink: (email: string) => Promise<void>\n status?: RequestMagicLinkStatusValue\n}\n\nexport type RequestMagicLinkStatusValue = 'default' | 'error' | 'sending' | 'sent'\n\n/**\n * Hook to request a magic-login link by email. Calls POST /api/emailToken and exposes\n * sendMagicLink, plus result message and status for UI.\n *\n * @param options - Hook options (see IUseRequestMagicLinkOptions)\n * @param options.handleMagicLinkRequested - Callback when a magic link is successfully requested\n * @param options.verifyData - Optional data sent with the request (e.g. for verification redirect)\n * @returns sendMagicLink function, result message, and status (see IUseRequestMagicLink)\n */\nexport const useRequestMagicLink = ({\n handleMagicLinkRequested,\n verifyData,\n}: IUseRequestMagicLinkOptions): IUseRequestMagicLink => {\n const { serverURL } = useServerUrl()\n\n const [status, setStatus] = useState<RequestMagicLinkStatusValue>('default')\n const [result, setResult] = useState<string>()\n\n const sendMagicLink = async (email: string): Promise<void> => {\n setStatus('sending')\n const emailTokenResponse = await fetch(`${serverURL ? serverURL : ''}/api/emailToken`, {\n body: JSON.stringify({\n email,\n verifyData,\n }),\n method: 'POST',\n })\n if (emailTokenResponse.ok) {\n const emailTokenResponseJson: RequestMagicLinkResponse = await emailTokenResponse.json()\n if (handleMagicLinkRequested) {\n handleMagicLinkRequested(emailTokenResponseJson)\n }\n // @ts-expect-error One or the other exists\n const { emailResult, error } = emailTokenResponseJson\n if (error) {\n setStatus('error')\n setResult(\n `An error occured. Please try again. \\n ${JSON.stringify(error?.error ? error.error : error, undefined, 2)}`,\n )\n console.log('emailToken error result: ', result)\n } else if (emailResult) {\n setStatus('sent')\n setResult('An email has been sent containing your magic link.')\n console.log('emailToken error result: ', result)\n } else {\n setStatus('error')\n setResult(`An error occured. Please try again. \\nResult unknown`)\n console.log('emailToken error result: ', result)\n }\n } else {\n try {\n const emailTokenResponseJson = await emailTokenResponse.json()\n setStatus('error')\n setResult(\n `An error occured. Please try again. \\n${JSON.stringify(emailTokenResponseJson?.error ? emailTokenResponseJson.error : emailTokenResponseJson, undefined, 2)}`,\n )\n console.log('emailToken error result: ', result)\n } catch (ignore) {\n const emailTokenResponseText = await emailTokenResponse.text()\n setStatus('error')\n setResult(`An error occured. Please try again. \\n${emailTokenResponseText}`)\n console.log('emailToken error result: ', result)\n }\n }\n }\n return {\n result,\n sendMagicLink,\n status,\n }\n}\n"],"names":["useState","useServerUrl","useRequestMagicLink","handleMagicLinkRequested","verifyData","serverURL","status","setStatus","result","setResult","sendMagicLink","email","emailTokenResponse","fetch","body","JSON","stringify","method","ok","emailTokenResponseJson","json","emailResult","error","undefined","console","log","ignore","emailTokenResponseText","text"],"mappings":"AAAA;AAEA,SAASA,QAAQ,QAAQ,QAAO;AAIhC,SAASC,YAAY,QAAQ,iCAAgC;AA8B7D;;;;;;;;CAQC,GACD,OAAO,MAAMC,sBAAsB,CAAC,EAClCC,wBAAwB,EACxBC,UAAU,EACkB;IAC5B,MAAM,EAAEC,SAAS,EAAE,GAAGJ;IAEtB,MAAM,CAACK,QAAQC,UAAU,GAAGP,SAAsC;IAClE,MAAM,CAACQ,QAAQC,UAAU,GAAGT;IAE5B,MAAMU,gBAAgB,OAAOC;QAC3BJ,UAAU;QACV,MAAMK,qBAAqB,MAAMC,MAAM,GAAGR,YAAYA,YAAY,GAAG,eAAe,CAAC,EAAE;YACrFS,MAAMC,KAAKC,SAAS,CAAC;gBACnBL;gBACAP;YACF;YACAa,QAAQ;QACV;QACA,IAAIL,mBAAmBM,EAAE,EAAE;YACzB,MAAMC,yBAAmD,MAAMP,mBAAmBQ,IAAI;YACtF,IAAIjB,0BAA0B;gBAC5BA,yBAAyBgB;YAC3B;YACA,2CAA2C;YAC3C,MAAM,EAAEE,WAAW,EAAEC,KAAK,EAAE,GAAGH;YAC/B,IAAIG,OAAO;gBACTf,UAAU;gBACVE,UACE,CAAC,uCAAuC,EAAEM,KAAKC,SAAS,CAACM,OAAOA,QAAQA,MAAMA,KAAK,GAAGA,OAAOC,WAAW,IAAI;gBAE9GC,QAAQC,GAAG,CAAC,6BAA6BjB;YAC3C,OAAO,IAAIa,aAAa;gBACtBd,UAAU;gBACVE,UAAU;gBACVe,QAAQC,GAAG,CAAC,6BAA6BjB;YAC3C,OAAO;gBACLD,UAAU;gBACVE,UAAU,CAAC,oDAAoD,CAAC;gBAChEe,QAAQC,GAAG,CAAC,6BAA6BjB;YAC3C;QACF,OAAO;YACL,IAAI;gBACF,MAAMW,yBAAyB,MAAMP,mBAAmBQ,IAAI;gBAC5Db,UAAU;gBACVE,UACE,CAAC,sCAAsC,EAAEM,KAAKC,SAAS,CAACG,wBAAwBG,QAAQH,uBAAuBG,KAAK,GAAGH,wBAAwBI,WAAW,IAAI;gBAEhKC,QAAQC,GAAG,CAAC,6BAA6BjB;YAC3C,EAAE,OAAOkB,QAAQ;gBACf,MAAMC,yBAAyB,MAAMf,mBAAmBgB,IAAI;gBAC5DrB,UAAU;gBACVE,UAAU,CAAC,sCAAsC,EAAEkB,wBAAwB;gBAC3EH,QAAQC,GAAG,CAAC,6BAA6BjB;YAC3C;QACF;IACF;IACA,OAAO;QACLA;QACAE;QACAJ;IACF;AACF,EAAC"}
|
|
@@ -3,7 +3,7 @@ const getServerSideURL = ()=>{
|
|
|
3
3
|
const serverSideURL = process.env.NEXT_PUBLIC_VERCEL_URL ? `https://${process.env.NEXT_PUBLIC_VERCEL_URL}` : process.env.VERCEL_PROJECT_PRODUCTION_URL ? `https://${process.env.VERCEL_PROJECT_PRODUCTION_URL}` : process.env.NEXT_PUBLIC_DEV_URL ? `http://${process.env.NEXT_PUBLIC_DEV_URL}` : 'http://localhost:3000';
|
|
4
4
|
// console.log(`process.env.NEXT_PUBLIC_DEV_URL: ${process.env.NEXT_PUBLIC_DEV_URL}`)
|
|
5
5
|
// console.log(`serverSideURL: ${serverSideURL}`)
|
|
6
|
-
return serverSideURL;
|
|
6
|
+
return serverSideURL || '';
|
|
7
7
|
};
|
|
8
8
|
// const canUseDOM = !!(
|
|
9
9
|
// typeof window !== 'undefined' &&
|
|
@@ -22,6 +22,7 @@ const getServerSideURL = ()=>{
|
|
|
22
22
|
// }
|
|
23
23
|
// return getServerSideURL()
|
|
24
24
|
// }
|
|
25
|
+
// eslint-disable-next-line @typescript-eslint/require-await
|
|
25
26
|
export const getServerUrl = async ()=>{
|
|
26
27
|
return {
|
|
27
28
|
serverURL: getServerSideURL()
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/server-functions/serverUrl.ts"],"sourcesContent":["'use server'\n\nconst getServerSideURL = () => {\n const serverSideURL = process.env.NEXT_PUBLIC_VERCEL_URL\n ? `https://${process.env.NEXT_PUBLIC_VERCEL_URL}`\n : process.env.VERCEL_PROJECT_PRODUCTION_URL\n ? `https://${process.env.VERCEL_PROJECT_PRODUCTION_URL}`\n : process.env.NEXT_PUBLIC_DEV_URL\n ? `http://${process.env.NEXT_PUBLIC_DEV_URL}`\n : 'http://localhost:3000'\n // console.log(`process.env.NEXT_PUBLIC_DEV_URL: ${process.env.NEXT_PUBLIC_DEV_URL}`)\n // console.log(`serverSideURL: ${serverSideURL}`)\n return serverSideURL\n}\n\n// const canUseDOM = !!(\n// typeof window !== 'undefined' &&\n// window.document &&\n// window.document.createElement\n// )\n\n// const getClientSideURL = () => {\n// if (canUseDOM) {\n// const protocol = window.location.protocol\n// const domain = window.location.hostname\n// const port = window.location.port\n// // `${window.location.protocol}//${window.location.host}\n// const clientSideURL = `${protocol}//${domain}${port ? `:${port}` : ''}`\n// // console.log(`clientSideURL: ${clientSideURL}`)\n// return clientSideURL\n// }\n\n// return getServerSideURL()\n// }\n\nexport const getServerUrl = async (): Promise<{ serverURL: string }> => {\n return { serverURL: getServerSideURL() }\n}\n"],"names":["getServerSideURL","serverSideURL","process","env","NEXT_PUBLIC_VERCEL_URL","VERCEL_PROJECT_PRODUCTION_URL","NEXT_PUBLIC_DEV_URL","getServerUrl","serverURL"],"mappings":"AAAA;AAEA,MAAMA,mBAAmB;IACvB,MAAMC,gBAAgBC,QAAQC,GAAG,CAACC,sBAAsB,GACpD,CAAC,QAAQ,EAAEF,QAAQC,GAAG,CAACC,sBAAsB,EAAE,GAC/CF,QAAQC,GAAG,CAACE,6BAA6B,GACvC,CAAC,QAAQ,EAAEH,QAAQC,GAAG,CAACE,6BAA6B,EAAE,GACtDH,QAAQC,GAAG,CAACG,mBAAmB,GAC7B,CAAC,OAAO,EAAEJ,QAAQC,GAAG,CAACG,mBAAmB,EAAE,GAC3C;IACR,qFAAqF;IACrF,iDAAiD;IACjD,OAAOL;
|
|
1
|
+
{"version":3,"sources":["../../src/server-functions/serverUrl.ts"],"sourcesContent":["'use server'\n\nconst getServerSideURL = () => {\n const serverSideURL = process.env.NEXT_PUBLIC_VERCEL_URL\n ? `https://${process.env.NEXT_PUBLIC_VERCEL_URL}`\n : process.env.VERCEL_PROJECT_PRODUCTION_URL\n ? `https://${process.env.VERCEL_PROJECT_PRODUCTION_URL}`\n : process.env.NEXT_PUBLIC_DEV_URL\n ? `http://${process.env.NEXT_PUBLIC_DEV_URL}`\n : 'http://localhost:3000'\n // console.log(`process.env.NEXT_PUBLIC_DEV_URL: ${process.env.NEXT_PUBLIC_DEV_URL}`)\n // console.log(`serverSideURL: ${serverSideURL}`)\n return serverSideURL || ''\n}\n\n// const canUseDOM = !!(\n// typeof window !== 'undefined' &&\n// window.document &&\n// window.document.createElement\n// )\n\n// const getClientSideURL = () => {\n// if (canUseDOM) {\n// const protocol = window.location.protocol\n// const domain = window.location.hostname\n// const port = window.location.port\n// // `${window.location.protocol}//${window.location.host}\n// const clientSideURL = `${protocol}//${domain}${port ? `:${port}` : ''}`\n// // console.log(`clientSideURL: ${clientSideURL}`)\n// return clientSideURL\n// }\n\n// return getServerSideURL()\n// }\n\n// eslint-disable-next-line @typescript-eslint/require-await\nexport const getServerUrl = async (): Promise<{ serverURL: string }> => {\n return { serverURL: getServerSideURL() }\n}\n"],"names":["getServerSideURL","serverSideURL","process","env","NEXT_PUBLIC_VERCEL_URL","VERCEL_PROJECT_PRODUCTION_URL","NEXT_PUBLIC_DEV_URL","getServerUrl","serverURL"],"mappings":"AAAA;AAEA,MAAMA,mBAAmB;IACvB,MAAMC,gBAAgBC,QAAQC,GAAG,CAACC,sBAAsB,GACpD,CAAC,QAAQ,EAAEF,QAAQC,GAAG,CAACC,sBAAsB,EAAE,GAC/CF,QAAQC,GAAG,CAACE,6BAA6B,GACvC,CAAC,QAAQ,EAAEH,QAAQC,GAAG,CAACE,6BAA6B,EAAE,GACtDH,QAAQC,GAAG,CAACG,mBAAmB,GAC7B,CAAC,OAAO,EAAEJ,QAAQC,GAAG,CAACG,mBAAmB,EAAE,GAC3C;IACR,qFAAqF;IACrF,iDAAiD;IACjD,OAAOL,iBAAiB;AAC1B;AAEA,wBAAwB;AACxB,qCAAqC;AACrC,uBAAuB;AACvB,kCAAkC;AAClC,IAAI;AAEJ,mCAAmC;AACnC,qBAAqB;AACrB,gDAAgD;AAChD,8CAA8C;AAC9C,wCAAwC;AACxC,+DAA+D;AAC/D,8EAA8E;AAC9E,wDAAwD;AACxD,2BAA2B;AAC3B,MAAM;AAEN,8BAA8B;AAC9B,IAAI;AAEJ,4DAA4D;AAC5D,OAAO,MAAMM,eAAe;IAC1B,OAAO;QAAEC,WAAWR;IAAmB;AACzC,EAAC"}
|
package/package.json
CHANGED
|
@@ -69,7 +69,7 @@
|
|
|
69
69
|
},
|
|
70
70
|
"registry": "https://registry.npmjs.org/",
|
|
71
71
|
"dependencies": {},
|
|
72
|
-
"version": "0.0.
|
|
72
|
+
"version": "0.0.16",
|
|
73
73
|
"scripts": {
|
|
74
74
|
"build": "pnpm copyfiles && pnpm build:types && pnpm build:swc",
|
|
75
75
|
"build:swc": "swc ./src -d ./dist --config-file .swcrc --strip-leading-paths",
|