@preprio/prepr-nextjs
Version:
Next.js package for Prepr CMS preview functionality with advanced debugging and visual editing capabilities
1 lines • 23 kB
Source Map (JSON)
{"version":3,"sources":["../../../package.json","../../../src/middleware/index.ts","../../../src/pages/server/index.ts"],"names":["version","package_default","createPreprMiddleware","request","responseOrOptions","options","_a","_b","_c","_d","response","finalOptions","NextResponse","value","key","referrer","ip","ipAddress","hutkCookie","cookie","segmentCookie","abCookie","PreprError","message","code","context","originalError","getPreprHeaderFromContext","name","headerValue","getPreprUUID","getActiveSegment","getActiveVariant","getPreprHeaders","preprHeaders","headers","validatePreprToken","token","isPreviewMode","extractAccessToken","graphqlUrl","url","pathParts","e","getPreprEnvironmentSegments","__async","validation","getPackageVersion","json","error","getToolbarProps","data","activeSegment","activeVariant","getPreviewBarProps"],"mappings":"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","file":"index.cjs","sourcesContent":["{\n \"name\": \"@preprio/prepr-nextjs\",\n \"version\": \"2.0.1\",\n \"description\": \"Next.js package for Prepr CMS preview functionality with advanced debugging and visual editing capabilities\",\n \"main\": \"dist/react/index.cjs\",\n \"types\": \"./dist/react/index.d.ts\",\n \"module\": \"./dist/react/index.js\",\n \"type\": \"module\",\n \"scripts\": {\n \"build\": \"tsup\",\n \"dev\": \"tsup --watch\",\n \"clean\": \"rm -rf dist\",\n \"check\": \"tsc --noEmit && eslint src --ext .ts,.tsx && prettier --check \\\"src/**/*.{ts,tsx,js,jsx,json,md}\\\"\",\n \"fix\": \"eslint src --ext .ts,.tsx --fix && prettier --write \\\"src/**/*.{ts,tsx,js,jsx,json,md}\\\"\",\n \"changeset\": \"changeset\",\n \"version\": \"changeset version\",\n \"release\": \"pnpm run build && changeset publish\",\n \"prepublishOnly\": \"pnpm run check && pnpm run build\"\n },\n \"exports\": {\n \"./middleware\": {\n \"import\": \"./dist/middleware/index.js\",\n \"types\": \"./dist/middleware/index.d.ts\",\n \"require\": \"./dist/middleware/index.cjs\"\n },\n \"./server\": {\n \"import\": \"./dist/server/index.js\",\n \"types\": \"./dist/server/index.d.ts\",\n \"require\": \"./dist/server/index.cjs\"\n },\n \"./react\": {\n \"import\": \"./dist/react/index.js\",\n \"types\": \"./dist/react/index.d.ts\",\n \"require\": \"./dist/react/index.cjs\"\n },\n \"./pages/server\": {\n \"import\": \"./dist/pages/server/index.js\",\n \"types\": \"./dist/pages/server/index.d.ts\",\n \"require\": \"./dist/pages/server/index.cjs\"\n },\n \"./pages/react\": {\n \"import\": \"./dist/pages/react/index.js\",\n \"types\": \"./dist/pages/react/index.d.ts\",\n \"require\": \"./dist/pages/react/index.cjs\"\n },\n \"./utils\": {\n \"import\": \"./dist/utils/index.js\",\n \"types\": \"./dist/utils/index.d.ts\",\n \"require\": \"./dist/utils/index.cjs\"\n },\n \"./types\": {\n \"import\": \"./dist/types/index.js\",\n \"types\": \"./dist/types/index.d.ts\",\n \"require\": \"./dist/types/index.cjs\"\n },\n \"./index.css\": {\n \"import\": \"./dist/index.css\",\n \"require\": \"./dist/index.css\"\n }\n },\n \"files\": [\n \"dist\",\n \"package.json\"\n ],\n \"keywords\": [\n \"prepr\",\n \"cms\",\n \"nextjs\",\n \"preview\",\n \"visual-editing\",\n \"headless-cms\",\n \"react\",\n \"typescript\",\n \"debug\",\n \"stega\"\n ],\n \"author\": \"Preprio\",\n \"license\": \"MIT\",\n \"packageManager\": \"pnpm@10.5.2\",\n \"devDependencies\": {\n \"@changesets/cli\": \"^2.29.5\",\n \"@eslint/js\": \"^9.25.1\",\n \"@types/node\": \"^20.11.5\",\n \"@types/react\": \"19.1.0\",\n \"@types/react-dom\": \"19.1.2\",\n \"@typescript-eslint/eslint-plugin\": \"^8.31.1\",\n \"@typescript-eslint/parser\": \"^8.31.1\",\n \"autoprefixer\": \"^10.4.21\",\n \"cssnano\": \"^7.0.7\",\n \"eslint\": \"^9.25.1\",\n \"eslint-config-prettier\": \"^10.1.2\",\n \"eslint-plugin-prettier\": \"^5.2.6\",\n \"eslint-plugin-react\": \"^7.37.2\",\n \"eslint-plugin-react-hooks\": \"^5.0.0\",\n \"next\": \"15.3.1\",\n \"postcss\": \"^8\",\n \"prettier\": \"^3.5.3\",\n \"prettier-plugin-tailwindcss\": \"^0.5.12\",\n \"react\": \"^19.1.0\",\n \"react-dom\": \"^19.1.0\",\n \"tailwindcss\": \"^3.4.17\",\n \"tsup\": \"^8.5.0\",\n \"typescript\": \"^5.8.3\"\n },\n \"peerDependencies\": {\n \"next\": \"^15.0.0 || ^14.0.0 || ^13.0.0\",\n \"react\": \"^19.0.0 || ^18.0.0 || ^17.0.0 \",\n \"react-dom\": \"^19.0.0 || ^18.0.0 || ^17.0.0\"\n },\n \"dependencies\": {\n \"@headlessui/react\": \"^2.2.0\",\n \"@vercel/functions\": \"^2.0.0\",\n \"@vercel/stega\": \"^0.1.2\",\n \"clsx\": \"^2.1.1\",\n \"postcss-cli\": \"^11.0.1\",\n \"tailwind-merge\": \"^3.0.1\"\n }\n}\n","import { ipAddress } from '@vercel/functions';\nimport { NextRequest, NextResponse } from 'next/server';\nimport { version } from '../../package.json';\n\nexport interface PreprMiddlewareOptions {\n preview?: boolean;\n}\n\n/**\n * Middleware to set Prepr headers for personalization.\n *\n * @overload\n * @param request - NextRequest object\n * @param options - Options object\n * @returns NextResponse with Prepr headers set\n */\nexport default function createPreprMiddleware(\n request: NextRequest,\n options?: PreprMiddlewareOptions\n): NextResponse;\n\n/**\n * Middleware to set Prepr headers for personalization.\n *\n * @overload\n * @param request - NextRequest object\n * @param response - NextResponse object to chain with\n * @param options - Options object\n * @returns NextResponse with Prepr headers set\n */\nexport default function createPreprMiddleware(\n request: NextRequest,\n response: NextResponse,\n options?: PreprMiddlewareOptions\n): NextResponse;\n\n/**\n * Implementation of createPreprMiddleware with function overloads\n */\nexport default function createPreprMiddleware(\n request: NextRequest,\n responseOrOptions?: NextResponse | PreprMiddlewareOptions,\n options?: PreprMiddlewareOptions\n): NextResponse {\n let response: NextResponse;\n let finalOptions: PreprMiddlewareOptions | undefined;\n\n // Handle overloads\n if (responseOrOptions && 'headers' in responseOrOptions) {\n // Second parameter is NextResponse\n response = responseOrOptions;\n finalOptions = options;\n } else {\n // Second parameter is options or undefined\n response = NextResponse.next();\n finalOptions = responseOrOptions as PreprMiddlewareOptions | undefined;\n }\n\n if (!process.env.PREPR_GRAPHQL_URL) {\n console.error('PREPR_GRAPHQL_URL is not set');\n }\n\n // Map over search params and set headers\n request.nextUrl.searchParams.forEach((value, key) => {\n switch (key) {\n case 'utm_source':\n response.headers.set('Prepr-Context-utm_source', value);\n break;\n case 'utm_medium':\n response.headers.set('Prepr-Context-utm_medium', value);\n break;\n case 'utm_term':\n response.headers.set('Prepr-Context-utm_term', value);\n break;\n case 'utm_content':\n response.headers.set('Prepr-Context-utm_content', value);\n break;\n case 'utm_campaign':\n response.headers.set('Prepr-Context-utm_campaign', value);\n break;\n }\n });\n\n // Set initial referral header\n const referrer = request.headers.get('referer');\n if (referrer) {\n response.headers.set('Prepr-Context-initial_referral', referrer);\n }\n\n // Set Prepr version header\n response.headers.set('Prepr-Package', version);\n\n // Set IP address header\n const ip = ipAddress(request);\n if (ip) {\n response.headers.set('Prepr-Visitor-IP', ip);\n }\n\n // Set HubSpot cookie header\n const hutkCookie = request.cookies.get('hubspotutk')?.value;\n if (hutkCookie) {\n response.headers.set('Prepr-Hubspot-Id', hutkCookie);\n }\n\n // Check for existing Prepr UID cookie or create a new one\n let cookie = request.cookies.get('__prepr_uid')?.value;\n if (!cookie) {\n cookie = crypto.randomUUID();\n response.cookies.set('__prepr_uid', cookie, {\n maxAge: 1 * 365 * 24 * 60, // Set for one year\n });\n response.headers.set('Prepr-Customer-Id-Created', 'true');\n }\n\n // Set the Prepr Customer ID header\n response.headers.set('Prepr-Customer-Id', cookie);\n\n // If preview mode is not enabled, return the response\n if (!finalOptions?.preview || process.env.PREPR_ENV !== 'preview') {\n return response;\n }\n\n // If preview mode is enabled, set additional headers\n response.headers.set('Prepr-Preview-Bar', 'true');\n\n // Set Prepr Preview Segment and AB test cookies\n const segmentCookie = request.cookies.get('Prepr-Segments')?.value;\n if (segmentCookie) {\n response.headers.set('Prepr-Segments', segmentCookie);\n }\n\n const abCookie = request.cookies.get('Prepr-ABtesting')?.value;\n if (abCookie) {\n response.headers.set('Prepr-ABtesting', abCookie);\n }\n\n // Set Prepr Preview Segment and AB test headers from query params\n request.nextUrl.searchParams.forEach((value, key) => {\n if (key === 'prepr_preview_ab') {\n response.headers.set('Prepr-ABtesting', value);\n response.cookies.set('Prepr-ABtesting', value);\n }\n\n if (key === 'prepr_preview_segment') {\n response.headers.set('Prepr-Segments', value);\n response.cookies.set('Prepr-Segments', value);\n }\n });\n\n return response;\n}\n","import { GetServerSidePropsContext, GetStaticPropsContext } from 'next';\nimport {\n PreprToolbarProps,\n PreprSegment,\n PreprHeaderName,\n PreprErrorCode,\n} from '../../types';\nimport pjson from '../../../package.json';\n\n/**\n * Custom error class for Prepr-related errors\n */\nexport class PreprError extends Error {\n constructor(\n message: string,\n public readonly code: PreprErrorCode,\n public readonly context?: string,\n public readonly originalError?: Error\n ) {\n super(message);\n this.name = 'PreprError';\n }\n}\n\n/**\n * Internal helper to get a specific Prepr header value from context\n * @param context - The Next.js context object from getServerSideProps or getStaticProps\n * @param name - The header name to retrieve\n * @returns The header value or null if not found\n */\nfunction getPreprHeaderFromContext(\n context: GetServerSidePropsContext | GetStaticPropsContext,\n name: PreprHeaderName\n): string | null {\n if ('req' in context && context.req) {\n const headers = context.req.headers;\n const headerValue = headers[name.toLowerCase()];\n return typeof headerValue === 'string'\n ? headerValue\n : headerValue?.[0] || null;\n }\n return null;\n}\n\n/**\n * Returns the Prepr Customer ID from the context headers\n * @param context - The Next.js context object\n * @returns Prepr Customer ID\n */\nexport function getPreprUUID(\n context: GetServerSidePropsContext | GetStaticPropsContext\n): string | null {\n return getPreprHeaderFromContext(context, 'prepr-customer-id');\n}\n\n/**\n * Returns the active segment from the context headers\n * @param context - The Next.js context object\n * @returns Active segment\n */\nexport function getActiveSegment(\n context: GetServerSidePropsContext | GetStaticPropsContext\n): string | null {\n return getPreprHeaderFromContext(context, 'Prepr-Segments');\n}\n\n/**\n * Returns the active variant from the context headers\n * @param context - The Next.js context object\n * @returns Active variant\n */\nexport function getActiveVariant(\n context: GetServerSidePropsContext | GetStaticPropsContext\n): string | null {\n return getPreprHeaderFromContext(context, 'Prepr-ABtesting');\n}\n\n/**\n * Helper function to retrieve all Prepr headers from context\n * @param context - The Next.js context object\n * @returns Object with Prepr headers\n */\nexport function getPreprHeaders(\n context: GetServerSidePropsContext | GetStaticPropsContext\n): Record<string, string> {\n const preprHeaders: Record<string, string> = {};\n\n if ('req' in context && context.req) {\n const headers = context.req.headers;\n Object.entries(headers).forEach(([key, value]) => {\n if (key.toLowerCase().startsWith('prepr')) {\n preprHeaders[key] =\n typeof value === 'string' ? value : value?.[0] || '';\n }\n });\n }\n\n return preprHeaders;\n}\n\n/**\n * Validates a Prepr GraphQL token\n * @param token - The token to validate\n * @returns Validation result with error details if invalid\n */\nexport function validatePreprToken(token: string): {\n valid: boolean;\n error?: string;\n} {\n if (!token) {\n return { valid: false, error: 'Token is required' };\n }\n if (!token.startsWith('https://')) {\n return { valid: false, error: 'Token must be a valid HTTPS URL' };\n }\n return { valid: true };\n}\n\n/**\n * Checks if the current environment is in preview mode\n * @returns True if in preview mode\n */\nexport function isPreviewMode(): boolean {\n return process.env.PREPR_ENV === 'preview';\n}\n\n/**\n * Extracts the access token from a Prepr GraphQL URL\n * @param graphqlUrl - The full Prepr GraphQL URL\n * @returns The access token or null if invalid\n * @example\n * ```typescript\n * const token = extractAccessToken('https://graphql.prepr.io/abc123')\n * // Returns: 'abc123'\n * ```\n */\nexport function extractAccessToken(graphqlUrl: string): string | null {\n if (!graphqlUrl) return null;\n\n try {\n const url = new URL(graphqlUrl);\n if (url.hostname !== 'graphql.prepr.io') return null;\n\n const pathParts = url.pathname.split('/');\n const token = pathParts[pathParts.length - 1];\n\n return token && token.length > 0 ? token : null;\n } catch {\n return null;\n }\n}\n\n/**\n * Fetches the segments from the Prepr API\n * @param token Prepr GraphQL URL with scope 'segments'\n * @returns Array of PreprSegment\n * @throws PreprError if the request fails\n */\nexport async function getPreprEnvironmentSegments(\n token: string\n): Promise<PreprSegment[]> {\n const validation = validatePreprToken(token);\n if (!validation.valid) {\n throw new PreprError(\n validation.error!,\n 'INVALID_TOKEN',\n 'getPreprEnvironmentSegments'\n );\n }\n\n try {\n const response = await fetch(token, {\n headers: {\n 'User-Agent': `Prepr-Preview-Bar/${getPackageVersion()}`,\n 'Content-Type': 'application/json',\n },\n method: 'POST',\n body: JSON.stringify({\n query: `{\n _Segments {\n _id\n name\n }\n }`,\n }),\n });\n\n if (!response.ok) {\n throw new PreprError(\n `HTTP ${response.status}: ${response.statusText}`,\n 'HTTP_ERROR',\n 'getPreprEnvironmentSegments'\n );\n }\n\n const json = await response.json();\n\n if (!json || !json.data || !json.data._Segments) {\n throw new PreprError(\n 'Invalid response format from Prepr API',\n 'INVALID_RESPONSE',\n 'getPreprEnvironmentSegments'\n );\n }\n\n return json.data._Segments as PreprSegment[];\n } catch (error) {\n if (error instanceof PreprError) {\n throw error;\n }\n throw new PreprError(\n 'Failed to fetch segments from Prepr API',\n 'FETCH_ERROR',\n 'getPreprEnvironmentSegments',\n error instanceof Error ? error : new Error(String(error))\n );\n }\n}\n\n/**\n * Fetches all the necessary toolbar props for Pages directory\n * @param token Prepr GraphQL URL with scope 'segments'\n * @param context The Next.js context object from getServerSideProps\n * @returns Object with activeSegment, activeVariant and data\n */\nexport async function getToolbarProps(\n token: string,\n context: GetServerSidePropsContext | GetStaticPropsContext\n): Promise<PreprToolbarProps> {\n let data: PreprSegment[] = [];\n let activeSegment: string | null = null;\n let activeVariant: string | null = null;\n\n // Prevent unnecessary function calling in production\n if (isPreviewMode()) {\n try {\n data = await getPreprEnvironmentSegments(token);\n activeSegment = getActiveSegment(context);\n activeVariant = getActiveVariant(context);\n } catch (error) {\n // In preview mode, we should still return props even if API fails\n console.error('Failed to fetch toolbar props:', error);\n // Return empty data to prevent toolbar from crashing\n data = [];\n }\n }\n\n return {\n activeSegment,\n activeVariant,\n data,\n };\n}\n\n/**\n * Alias for getToolbarProps for consistency with App Router API\n */\nexport const getPreviewBarProps = getToolbarProps;\n\nfunction getPackageVersion() {\n return pjson.version;\n}\n\n// Re-export the middleware for convenience\nexport { default as createPreprMiddleware } from '../../middleware';\n"]}