@lucidcms/core
Version:
The core of the Lucid CMS. It's responsible for spinning up the API and serving the CMS.
1 lines • 5.71 kB
Source Map (JSON)
{"version":3,"file":"state.mjs","names":["previewSessionServices.resolve"],"sources":["../../../../src/libs/toolkit/previews/state.ts"],"sourcesContent":["import { previewSessionServices } from \"../../../services/index.js\";\nimport type { PreviewSession } from \"../../../types.js\";\nimport type {\n\tServiceContext,\n\tServiceResponse,\n} from \"../../../utils/services/types.js\";\nimport { runToolkitService } from \"../utils.js\";\n\ntype MaybePromise<T> = T | Promise<T>;\n\nexport type ToolkitPreviewSource = \"query\" | \"stored\" | \"exit\" | null;\n\nexport type ToolkitPreviewStore = {\n\t/** Reads the raw preview token persisted by the frontend adapter. */\n\tget: () => MaybePromise<string | null | undefined>;\n\t/** Persists a validated perspective preview until its server-issued expiry. */\n\tset: (preview: { token: string; expiresAt: string }) => MaybePromise<void>;\n\t/** Clears the frontend's persisted preview. */\n\tclear: () => MaybePromise<void>;\n};\n\nexport type ToolkitPreviewResponseHeaders = {\n\t/** Sets a response header on the host framework's current response. */\n\tset: (name: string, value: string) => MaybePromise<void>;\n};\n\nexport type ToolkitPreviewStateInput = {\n\t/** The current frontend request URL. */\n\turl: string | URL;\n\t/** Framework adapter for perspective-preview persistence. */\n\tsession: ToolkitPreviewStore;\n\t/** Optional framework adapter used to apply preview response protections. */\n\theaders?: ToolkitPreviewResponseHeaders;\n};\n\nexport type ToolkitPreviewState = {\n\tactive: boolean;\n\ttoken: string | null;\n\tsource: ToolkitPreviewSource;\n\tpreview: PreviewSession | null;\n};\n\nconst previewQueryParam = \"preview\";\nconst previewExitValue = \"exit\";\nconst previewContextQueryParam = \"previewContext\";\nconst builderPreviewContext = \"builder\";\n\nconst setPreviewResponseHeaders = async (\n\theaders?: ToolkitPreviewResponseHeaders,\n) => {\n\tif (!headers) return;\n\n\tawait Promise.all([\n\t\theaders.set(\"Cache-Control\", \"private, no-store\"),\n\t\theaders.set(\"Pragma\", \"no-cache\"),\n\t\theaders.set(\"Referrer-Policy\", \"no-referrer\"),\n\t]);\n};\n\nconst state = async (\n\tcontext: ServiceContext,\n\tinput: ToolkitPreviewStateInput,\n): ServiceResponse<ToolkitPreviewState> => {\n\treturn runToolkitService<ToolkitPreviewState>(\n\t\tasync () => {\n\t\t\tconst url = new URL(input.url);\n\t\t\tconst hasQueryValue = url.searchParams.has(previewQueryParam);\n\t\t\tconst isBuilderPreview =\n\t\t\t\turl.searchParams.get(previewContextQueryParam) ===\n\t\t\t\tbuilderPreviewContext;\n\t\t\tconst queryValue = hasQueryValue\n\t\t\t\t? (url.searchParams.get(previewQueryParam) ?? \"\")\n\t\t\t\t: undefined;\n\n\t\t\tif (queryValue === previewExitValue) {\n\t\t\t\tawait setPreviewResponseHeaders(input.headers);\n\t\t\t\tawait input.session.clear();\n\n\t\t\t\treturn {\n\t\t\t\t\terror: undefined,\n\t\t\t\t\tdata: {\n\t\t\t\t\t\tactive: false,\n\t\t\t\t\t\ttoken: null,\n\t\t\t\t\t\tsource: \"exit\",\n\t\t\t\t\t\tpreview: null,\n\t\t\t\t\t},\n\t\t\t\t};\n\t\t\t}\n\n\t\t\tconst storedToken = hasQueryValue ? undefined : await input.session.get();\n\t\t\tconst token = queryValue ?? storedToken ?? null;\n\t\t\tif (token === null) {\n\t\t\t\treturn {\n\t\t\t\t\terror: undefined,\n\t\t\t\t\tdata: {\n\t\t\t\t\t\tactive: false,\n\t\t\t\t\t\ttoken: null,\n\t\t\t\t\t\tsource: null,\n\t\t\t\t\t\tpreview: null,\n\t\t\t\t\t},\n\t\t\t\t};\n\t\t\t}\n\n\t\t\tawait setPreviewResponseHeaders(input.headers);\n\t\t\tconst previewRes = await previewSessionServices.resolve(context, {\n\t\t\t\ttoken,\n\t\t\t});\n\t\t\tif (previewRes.error) {\n\t\t\t\tawait input.session.clear();\n\t\t\t\treturn previewRes;\n\t\t\t}\n\n\t\t\tif (previewRes.data.mode === \"scoped\") {\n\t\t\t\tawait input.session.clear();\n\t\t\t} else if (hasQueryValue && !isBuilderPreview) {\n\t\t\t\tawait input.session.set({\n\t\t\t\t\ttoken,\n\t\t\t\t\texpiresAt: previewRes.data.expiresAt,\n\t\t\t\t});\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\terror: undefined,\n\t\t\t\tdata: {\n\t\t\t\t\tactive: true,\n\t\t\t\t\ttoken,\n\t\t\t\t\tsource: hasQueryValue ? \"query\" : \"stored\",\n\t\t\t\t\tpreview: previewRes.data,\n\t\t\t\t},\n\t\t\t};\n\t\t},\n\t\t{\n\t\t\tname: {\n\t\t\t\tkey: \"core.toolkit.preview.resolve.error.name\",\n\t\t\t\tdefaultMessage: \"Preview Toolkit Error\",\n\t\t\t},\n\t\t\tmessage: {\n\t\t\t\tkey: \"core.toolkit.preview.resolve.error.message\",\n\t\t\t\tdefaultMessage: \"Lucid toolkit could not handle the preview.\",\n\t\t\t},\n\t\t},\n\t);\n};\n\nexport default state;\n"],"mappings":"+GA0CA,MAAM,EAAoB,UAKpB,EAA4B,KACjC,IACI,CACC,GAEL,MAAM,QAAQ,IAAI,CACjB,EAAQ,IAAI,gBAAiB,mBAAmB,EAChD,EAAQ,IAAI,SAAU,UAAU,EAChC,EAAQ,IAAI,kBAAmB,aAAa,CAC7C,CAAC,CACF,EAEM,EAAQ,MACb,EACA,IAEO,EACN,SAAY,CACX,IAAM,EAAM,IAAI,IAAI,EAAM,GAAG,EACvB,EAAgB,EAAI,aAAa,IAAI,CAAiB,EACtD,EACL,EAAI,aAAa,IAAI,gBAAwB,IAC7C,UACK,EAAa,EACf,EAAI,aAAa,IAAI,CAAiB,GAAK,GAC5C,IAAA,GAEH,GAAI,IAAe,OAIlB,OAHA,MAAM,EAA0B,EAAM,OAAO,EAC7C,MAAM,EAAM,QAAQ,MAAM,EAEnB,CACN,MAAO,IAAA,GACP,KAAM,CACL,OAAQ,GACR,MAAO,KACP,OAAQ,OACR,QAAS,IACV,CACD,EAGD,IAAM,EAAc,EAAgB,IAAA,GAAY,MAAM,EAAM,QAAQ,IAAI,EAClE,EAAQ,GAAc,GAAe,KAC3C,GAAI,IAAU,KACb,MAAO,CACN,MAAO,IAAA,GACP,KAAM,CACL,OAAQ,GACR,MAAO,KACP,OAAQ,KACR,QAAS,IACV,CACD,EAGD,MAAM,EAA0B,EAAM,OAAO,EAC7C,IAAM,EAAa,MAAMA,EAA+B,EAAS,CAChE,OACD,CAAC,EAeD,OAdI,EAAW,OACd,MAAM,EAAM,QAAQ,MAAM,EACnB,IAGJ,EAAW,KAAK,OAAS,SAC5B,MAAM,EAAM,QAAQ,MAAM,EAChB,GAAiB,CAAC,GAC5B,MAAM,EAAM,QAAQ,IAAI,CACvB,QACA,UAAW,EAAW,KAAK,SAC5B,CAAC,EAGK,CACN,MAAO,IAAA,GACP,KAAM,CACL,OAAQ,GACR,QACA,OAAQ,EAAgB,QAAU,SAClC,QAAS,EAAW,IACrB,CACD,EACD,EACA,CACC,KAAM,CACL,IAAK,0CACL,eAAgB,uBACjB,EACA,QAAS,CACR,IAAK,6CACL,eAAgB,6CACjB,CACD,CACD"}