payload-subscribers-plugin 0.0.15 → 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 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: 60 * 60,
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,
@@ -18,36 +18,46 @@ 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 initSubscriber = async ()=>{
22
- console.log('initSubscriber');
21
+ const initSubscriber = useCallback(async ()=>{
22
+ console.log('initSubscriber', serverURL);
23
23
  setIsLoaded(false);
24
- try {
25
- const authResponse = await fetch('/api/subscriberAuth', {
26
- // body: JSON.stringify({}),
27
- method: 'POST'
28
- });
29
- if (authResponse.ok) {
30
- // Call the server function to get the user data
31
- const authResponseJson = await authResponse.json();
32
- // console.log('authResponseJson', JSON.stringify(authResponseJson, undefined, 2))
33
- const { permissions, subscriber } = authResponseJson;
34
- // console.log(`subscriber = `, subscriber)
35
- // console.log(`permissions = `, permissions)
36
- setPermissions(permissions);
37
- setSubscriber(subscriber);
38
- } else {
39
- setPermissions(null);
40
- setSubscriber(null);
24
+ if (serverURL) {
25
+ try {
26
+ const authResponse = await fetch(`${serverURL}/api/subscriberAuth`, {
27
+ // body: JSON.stringify({}),
28
+ method: 'POST'
29
+ });
30
+ if (authResponse.ok) {
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
+ }
44
+ } else {
45
+ console.log('authResponse not ok', authResponse);
46
+ setPermissions(null);
47
+ setSubscriber(null);
48
+ }
49
+ setIsLoaded(true);
50
+ } catch (error) {
51
+ console.log(`authResponse error`, error);
41
52
  }
42
- } catch (error) {
43
- console.log(`authResponse error`, error);
44
53
  }
45
- setIsLoaded(true);
46
- };
54
+ }, [
55
+ serverURL
56
+ ]);
47
57
  const refreshSubscriber = useCallback(async ()=>{
48
58
  await initSubscriber();
49
59
  }, [
50
- serverURL
60
+ initSubscriber
51
61
  ]);
52
62
  const logOut = useCallback(async ()=>{
53
63
  setIsLoaded(false);
@@ -76,7 +86,9 @@ const SubscriberContext = /*#__PURE__*/ createContext(undefined);
76
86
  }, []);
77
87
  useEffect(()=>{
78
88
  void initSubscriber();
79
- }, []);
89
+ }, [
90
+ initSubscriber
91
+ ]);
80
92
  // Memoize the value to prevent unnecessary re-renders in consumers
81
93
  const contextValue = useMemo(()=>({
82
94
  isLoaded,
@@ -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 initSubscriber = async () => {\n console.log('initSubscriber')\n setIsLoaded(false)\n try {\n const authResponse = await fetch('/api/subscriberAuth', {\n // body: JSON.stringify({}),\n method: 'POST',\n })\n\n if (authResponse.ok) {\n // Call the server function to get the user data\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 } else {\n setPermissions(null)\n setSubscriber(null)\n }\n } catch (error: unknown) {\n console.log(`authResponse error`, error)\n }\n setIsLoaded(true)\n }\n\n const refreshSubscriber = useCallback(async () => {\n await initSubscriber()\n }, [serverURL])\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 }, [])\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","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,iBAAiB;QACrBC,QAAQC,GAAG,CAAC;QACZL,YAAY;QACZ,IAAI;YACF,MAAMM,eAAe,MAAMC,MAAM,uBAAuB;gBACtD,4BAA4B;gBAC5BC,QAAQ;YACV;YAEA,IAAIF,aAAaG,EAAE,EAAE;gBACnB,gDAAgD;gBAChD,MAAMC,mBAAmB,MAAMJ,aAAaK,IAAI;gBAChD,kFAAkF;gBAClF,MAAM,EAAEV,WAAW,EAAEL,UAAU,EAAE,GAAGc;gBACpC,2CAA2C;gBAC3C,6CAA6C;gBAC7CR,eAAeD;gBACfJ,cAAcD;YAChB,OAAO;gBACLM,eAAe;gBACfL,cAAc;YAChB;QACF,EAAE,OAAOe,OAAgB;YACvBR,QAAQC,GAAG,CAAC,CAAC,kBAAkB,CAAC,EAAEO;QACpC;QACAZ,YAAY;IACd;IAEA,MAAMa,oBAAoB5B,YAAY;QACpC,MAAMkB;IACR,GAAG;QAACL;KAAU;IAEd,MAAMgB,SAAS7B,YAAY;QACzBe,YAAY;QACZ,IAAI;YACF,uCAAuC;YACvC,8BAA8B;YAC9B,KAAK;YACL,6CAA6C;YAC7C,cAAc;YACd,oBAAoB;YACpB,yBAAyB;YACzB,KAAK;YACL,oCAAoC;YACpC,MAAMe,iBAAiB,MAAMR,MAAM,eAAe;gBAChDC,QAAQ;YACV;YAEA,gDAAgD;YAEhD,IAAIO,eAAeN,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,EAAE;IAEL,mEAAmE;IACnE,MAAMa,eAAsC3B,QAC1C,IAAO,CAAA;YACLU;YACAe;YACAb;YACAY;YACAjB;QACF,CAAA,GACA;QAACG;QAAUe;QAAQb;QAAaY;QAAmBjB;KAAW;IAGhE,qBAAO,KAACJ,kBAAkByB,QAAQ;QAACC,OAAOF;kBAAerB;;AAC3D;AAEA;;;;;CAKC,GACD,OAAO,SAASwB;IACd,MAAMC,UAAUhC,WAAWI;IAC3B,IAAI4B,YAAY3B,WAAW;QACzB,MAAM,IAAI4B,MAAM;IAClB;IACA,OAAOD;AACT"}
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"}
@@ -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(`${req.payload.config.serverURL}/api/${subscribersCollectionSlug}/logout`, {
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 try {\n const logoutResult = await fetch(\n `${req.payload.config.serverURL}/api/${subscribersCollectionSlug}/logout`,\n {\n headers,\n method: 'POST',\n },\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: ${JSON.stringify(error)}`,\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","logoutResult","fetch","payload","config","serverURL","method","logoutResultData","json","ok","Response","message","now","Date","toISOString","status","errors","map","e","includes","error","join","JSON","stringify","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,IAAI;YACF,MAAMM,eAAe,MAAMC,MACzB,GAAGF,IAAIG,OAAO,CAACC,MAAM,CAACC,SAAS,CAAC,KAAK,EAAEP,0BAA0B,OAAO,CAAC,EACzE;gBACEJ;gBACAY,QAAQ;YACV;YAGF,MAAMC,mBAAmB,MAAMN,aAAaO,IAAI;YAEhD,IAAIP,aAAaQ,EAAE,EAAE;gBACnB,OAAOC,SAASF,IAAI,CAAC;oBACnBG,SAASJ,iBAAiBI,OAAO;oBACjCC,KAAK,IAAIC,OAAOC,WAAW;gBAC7B;YACF;YAEA,IACEb,aAAac,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,EAAEE,KAAKC,SAAS,CAACH,QAAQ;gBAChDR,KAAK,IAAIC,OAAOC,WAAW;YAC7B,GACA;gBACEC,QAAQ;YACV;QAEJ;IACF;IAEA,kEAAkE,GAClE,MAAMS,iBAA2B;QAC/BC,SAAS1B;QACTO,QAAQ;QACRoB,MAAM;IACR;IAEA,OAAOF;AACT;AAEA,eAAe3B,qBAAoB"}
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"}
@@ -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;AACT;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,OAAO,MAAMM,eAAe;IAC1B,OAAO;QAAEC,WAAWR;IAAmB;AACzC,EAAC"}
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.15",
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",