@delmaredigital/payload-puck 0.1.1 → 0.1.3

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.
Files changed (38) hide show
  1. package/LICENSE +21 -73
  2. package/README.md +1 -22
  3. package/package.json +3 -2
  4. package/dist/AccordionClient.js.map +0 -1
  5. package/dist/AccordionClient.mjs.map +0 -1
  6. package/dist/AnimatedWrapper.js.map +0 -1
  7. package/dist/AnimatedWrapper.mjs.map +0 -1
  8. package/dist/admin/client.js.map +0 -1
  9. package/dist/admin/client.mjs.map +0 -1
  10. package/dist/admin/index.js.map +0 -1
  11. package/dist/admin/index.mjs.map +0 -1
  12. package/dist/api/index.js.map +0 -1
  13. package/dist/api/index.mjs.map +0 -1
  14. package/dist/components/index.css.map +0 -1
  15. package/dist/components/index.js.map +0 -1
  16. package/dist/components/index.mjs.map +0 -1
  17. package/dist/config/config.editor.css.map +0 -1
  18. package/dist/config/config.editor.js.map +0 -1
  19. package/dist/config/config.editor.mjs.map +0 -1
  20. package/dist/config/index.js.map +0 -1
  21. package/dist/config/index.mjs.map +0 -1
  22. package/dist/editor/index.js.map +0 -1
  23. package/dist/editor/index.mjs.map +0 -1
  24. package/dist/fields/index.css.map +0 -1
  25. package/dist/fields/index.js.map +0 -1
  26. package/dist/fields/index.mjs.map +0 -1
  27. package/dist/index.js.map +0 -1
  28. package/dist/index.mjs.map +0 -1
  29. package/dist/layouts/index.js.map +0 -1
  30. package/dist/layouts/index.mjs.map +0 -1
  31. package/dist/plugin/index.js.map +0 -1
  32. package/dist/plugin/index.mjs.map +0 -1
  33. package/dist/render/index.js.map +0 -1
  34. package/dist/render/index.mjs.map +0 -1
  35. package/dist/theme/index.js.map +0 -1
  36. package/dist/theme/index.mjs.map +0 -1
  37. package/dist/utils/index.js.map +0 -1
  38. package/dist/utils/index.mjs.map +0 -1
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../src/theme/defaults.ts","../../src/theme/utils.ts","../../src/theme/context.tsx","../../src/theme/example.ts"],"names":["createContext","useMemo","jsx","useContext"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Default Theme Values\n *\n * These defaults ensure backwards compatibility - components render\n * identically to before theming was introduced when no theme is provided.\n */\n\nimport type {\n ButtonVariantStyles,\n BackgroundStyles,\n ColorPreset,\n ResolvedTheme,\n} from './types'\n\n/**\n * Default button variant styles\n * Uses semantic Tailwind classes that map to CSS variables (--primary, --secondary, etc.)\n * This allows consuming apps to customize colors via their theme CSS variables.\n */\nexport const DEFAULT_BUTTON_VARIANTS: ButtonVariantStyles = {\n default: { classes: 'bg-primary text-primary-foreground hover:bg-primary/90' },\n secondary: { classes: 'bg-secondary text-secondary-foreground hover:bg-secondary/80' },\n outline: { classes: 'border border-input bg-background hover:bg-accent hover:text-accent-foreground' },\n ghost: { classes: 'bg-transparent hover:bg-accent hover:text-accent-foreground' },\n destructive: { classes: 'bg-destructive text-destructive-foreground hover:bg-destructive/90' },\n link: { classes: 'text-primary underline-offset-4 hover:underline bg-transparent' },\n}\n\n/**\n * Default CTA button variant styles\n * Uses semantic Tailwind classes that map to CSS variables.\n */\nexport const DEFAULT_CTA_BUTTON_VARIANTS: ButtonVariantStyles = {\n primary: { classes: 'bg-primary text-primary-foreground hover:bg-primary/90' },\n secondary: { classes: 'bg-secondary text-secondary-foreground hover:bg-secondary/80' },\n outline: { classes: 'border border-input bg-background hover:bg-accent hover:text-accent-foreground' },\n ghost: { classes: 'bg-transparent hover:bg-accent hover:text-accent-foreground' },\n link: { classes: 'text-primary underline-offset-4 hover:underline bg-transparent' },\n}\n\n/**\n * Default CTA background styles\n * Uses semantic Tailwind classes that map to CSS variables.\n */\nexport const DEFAULT_CTA_BACKGROUND_STYLES: BackgroundStyles = {\n default: 'bg-muted',\n dark: 'bg-foreground text-background',\n light: 'bg-background',\n}\n\n/**\n * Default color picker presets\n * Matches DEFAULT_PRESETS from ColorPickerField.tsx\n */\nexport const DEFAULT_COLOR_PRESETS: ColorPreset[] = [\n { hex: '#ffffff', label: 'White' },\n { hex: '#f9fafb', label: 'Gray 50' },\n { hex: '#f3f4f6', label: 'Gray 100' },\n { hex: '#1f2937', label: 'Gray 800' },\n { hex: '#111827', label: 'Gray 900' },\n { hex: '#000000', label: 'Black' },\n { hex: '#3b82f6', label: 'Blue' },\n { hex: '#10b981', label: 'Green' },\n { hex: '#f59e0b', label: 'Amber' },\n { hex: '#ef4444', label: 'Red' },\n]\n\n/**\n * Default focus ring color class\n * Uses semantic ring color from CSS variables\n */\nexport const DEFAULT_FOCUS_RING = 'focus:ring-ring'\n\n/**\n * Complete default theme\n * Used when no ThemeProvider is present or no theme config is provided\n */\nexport const DEFAULT_THEME: ResolvedTheme = {\n buttonVariants: DEFAULT_BUTTON_VARIANTS,\n ctaButtonVariants: DEFAULT_CTA_BUTTON_VARIANTS,\n ctaBackgroundStyles: DEFAULT_CTA_BACKGROUND_STYLES,\n colorPresets: DEFAULT_COLOR_PRESETS,\n focusRingColor: DEFAULT_FOCUS_RING,\n}\n","/**\n * Theme Resolution Utilities\n *\n * Functions for merging user-provided theme config with defaults\n * and safely accessing theme values.\n */\n\nimport type {\n ThemeConfig,\n ResolvedTheme,\n ButtonVariantStyles,\n BackgroundStyles,\n} from './types'\nimport {\n DEFAULT_BUTTON_VARIANTS,\n DEFAULT_CTA_BUTTON_VARIANTS,\n DEFAULT_CTA_BACKGROUND_STYLES,\n DEFAULT_COLOR_PRESETS,\n DEFAULT_FOCUS_RING,\n DEFAULT_THEME,\n} from './defaults'\n\n/**\n * Merges user-provided theme config with defaults to create a fully resolved theme\n */\nexport function resolveTheme(config?: ThemeConfig): ResolvedTheme {\n if (!config) return DEFAULT_THEME\n\n return {\n buttonVariants: mergeVariants(DEFAULT_BUTTON_VARIANTS, config.buttonVariants),\n ctaButtonVariants: mergeVariants(DEFAULT_CTA_BUTTON_VARIANTS, config.ctaButtonVariants),\n ctaBackgroundStyles: mergeBackgroundStyles(\n DEFAULT_CTA_BACKGROUND_STYLES,\n config.ctaBackgroundStyles\n ),\n colorPresets: resolveColorPresets(config),\n focusRingColor: config.focusRingColor ?? DEFAULT_FOCUS_RING,\n }\n}\n\n/**\n * Merges variant overrides with defaults\n */\nfunction mergeVariants(\n defaults: ButtonVariantStyles,\n overrides?: Partial<ButtonVariantStyles>\n): ButtonVariantStyles {\n if (!overrides) return defaults\n\n const result: ButtonVariantStyles = { ...defaults }\n for (const key of Object.keys(overrides)) {\n const override = overrides[key]\n if (override) {\n result[key] = override\n }\n }\n return result\n}\n\n/**\n * Merges background style overrides with defaults\n */\nfunction mergeBackgroundStyles(\n defaults: BackgroundStyles,\n overrides?: Partial<BackgroundStyles>\n): BackgroundStyles {\n if (!overrides) return defaults\n return { ...defaults, ...overrides }\n}\n\n/**\n * Resolves color presets based on config\n */\nfunction resolveColorPresets(config: ThemeConfig) {\n if (!config.colorPresets) {\n return DEFAULT_COLOR_PRESETS\n }\n\n if (config.extendColorPresets) {\n return [...DEFAULT_COLOR_PRESETS, ...config.colorPresets]\n }\n\n return config.colorPresets\n}\n\n/**\n * Safely gets variant classes from a variant styles object\n *\n * @param variants - The button variant styles object\n * @param variant - The variant key to look up\n * @param fallback - Fallback variant key if the requested variant doesn't exist\n * @returns The CSS classes string for the variant\n */\nexport function getVariantClasses(\n variants: ButtonVariantStyles,\n variant: string,\n fallback = 'default'\n): string {\n const config = variants[variant]\n if (config?.classes) {\n return config.classes\n }\n\n const fallbackConfig = variants[fallback]\n return fallbackConfig?.classes ?? ''\n}\n\n/**\n * Safely gets background style classes\n *\n * @param styles - The background styles object\n * @param style - The style key to look up\n * @param fallback - Fallback style key if the requested style doesn't exist\n * @returns The CSS classes string for the background\n */\nexport function getBackgroundClasses(\n styles: BackgroundStyles,\n style: string,\n fallback = 'default'\n): string {\n return styles[style] ?? styles[fallback] ?? ''\n}\n","'use client'\n\n/**\n * Theme Context\n *\n * React context for distributing theme configuration to Puck components.\n * The useTheme() hook returns defaults when no provider is present,\n * ensuring backwards compatibility.\n */\n\nimport { createContext, useContext, useMemo, type ReactNode } from 'react'\nimport type { ThemeConfig, ThemeContextValue, ResolvedTheme } from './types'\nimport { DEFAULT_THEME } from './defaults'\nimport { resolveTheme } from './utils'\n\nconst ThemeContext = createContext<ThemeContextValue | null>(null)\n\nexport interface ThemeProviderProps {\n children: ReactNode\n /** Theme configuration to apply */\n theme?: ThemeConfig\n}\n\n/**\n * Provides theme configuration to descendant Puck components\n *\n * @example\n * ```tsx\n * <ThemeProvider theme={{\n * buttonVariants: {\n * default: { classes: 'bg-primary text-white hover:bg-primary/90' }\n * }\n * }}>\n * <PageRenderer data={data} />\n * </ThemeProvider>\n * ```\n */\nexport function ThemeProvider({ children, theme }: ThemeProviderProps) {\n const resolvedTheme = useMemo(() => resolveTheme(theme), [theme])\n\n const value = useMemo<ThemeContextValue>(\n () => ({\n theme: resolvedTheme,\n }),\n [resolvedTheme]\n )\n\n return <ThemeContext.Provider value={value}>{children}</ThemeContext.Provider>\n}\n\n/**\n * Hook to access the current theme\n *\n * Returns DEFAULT_THEME if no ThemeProvider is present,\n * ensuring components work standalone for backwards compatibility.\n *\n * @example\n * ```tsx\n * function MyComponent() {\n * const theme = useTheme()\n * const buttonClasses = getVariantClasses(theme.buttonVariants, 'primary')\n * return <button className={buttonClasses}>Click me</button>\n * }\n * ```\n */\nexport function useTheme(): ResolvedTheme {\n const context = useContext(ThemeContext)\n // Return defaults if no provider - ensures backwards compatibility\n return context?.theme ?? DEFAULT_THEME\n}\n\n/**\n * Gets the default theme for server components\n *\n * Use this when you need theme values in a server component\n * where hooks cannot be used.\n */\nexport function getDefaultTheme(): ResolvedTheme {\n return DEFAULT_THEME\n}\n\n/**\n * Hook to check if a ThemeProvider is present\n *\n * Useful for conditional logic based on whether theming is configured.\n */\nexport function useHasThemeProvider(): boolean {\n const context = useContext(ThemeContext)\n return context !== null\n}\n","/**\n * Example Theme Configuration\n *\n * Copy this file to your project and customize it to match your design system.\n *\n * Usage:\n * 1. Copy this file to your project (e.g., src/lib/puck-theme.ts)\n * 2. Customize the values to match your CSS variables/design tokens\n * 3. Import and pass to PageRenderer or PuckEditor:\n *\n * ```tsx\n * import { puckTheme } from '@/lib/puck-theme'\n *\n * <PageRenderer data={data} config={config} theme={puckTheme} />\n * ```\n */\n\nimport type { ThemeConfig } from './types'\n\n/**\n * Example theme using shadcn/ui CSS variables\n *\n * This example assumes you have CSS variables like:\n * --primary, --primary-foreground\n * --secondary, --secondary-foreground\n * --accent, --accent-foreground\n * --muted, --muted-foreground\n * --destructive, --destructive-foreground\n * --ring (for focus rings)\n */\nexport const exampleTheme: ThemeConfig = {\n // Button component variants\n buttonVariants: {\n default: {\n classes: 'bg-primary text-primary-foreground hover:bg-primary/90',\n },\n secondary: {\n classes: 'bg-secondary text-secondary-foreground hover:bg-secondary/80',\n },\n outline: {\n classes: 'border border-input bg-background hover:bg-accent hover:text-accent-foreground',\n },\n ghost: {\n classes: 'hover:bg-accent hover:text-accent-foreground',\n },\n destructive: {\n classes: 'bg-destructive text-destructive-foreground hover:bg-destructive/90',\n },\n link: {\n classes: 'text-primary underline-offset-4 hover:underline',\n },\n },\n\n // CTA button variants\n ctaButtonVariants: {\n primary: {\n classes: 'bg-primary text-primary-foreground hover:bg-primary/90',\n },\n secondary: {\n classes: 'bg-secondary text-secondary-foreground hover:bg-secondary/80',\n },\n outline: {\n classes: 'border border-input bg-background hover:bg-accent hover:text-accent-foreground',\n },\n },\n\n // CTA background styles\n ctaBackgroundStyles: {\n default: 'bg-muted',\n dark: 'bg-primary text-primary-foreground',\n light: 'bg-background',\n },\n\n // Focus ring class\n focusRingColor: 'focus:ring-ring',\n\n // Color picker presets - customize with your brand colors\n colorPresets: [\n { hex: '#ffffff', label: 'White' },\n { hex: '#f8fafc', label: 'Slate 50' },\n { hex: '#f1f5f9', label: 'Slate 100' },\n { hex: '#e2e8f0', label: 'Slate 200' },\n { hex: '#64748b', label: 'Slate 500' },\n { hex: '#334155', label: 'Slate 700' },\n { hex: '#1e293b', label: 'Slate 800' },\n { hex: '#0f172a', label: 'Slate 900' },\n { hex: '#000000', label: 'Black' },\n { hex: '#3b82f6', label: 'Blue' },\n { hex: '#10b981', label: 'Green' },\n { hex: '#f59e0b', label: 'Amber' },\n { hex: '#ef4444', label: 'Red' },\n ],\n\n // Set to true to add your presets to defaults instead of replacing\n extendColorPresets: false,\n}\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../src/theme/defaults.ts","../../src/theme/utils.ts","../../src/theme/context.tsx","../../src/theme/example.ts"],"names":[],"mappings":"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","file":"index.mjs","sourcesContent":["/**\n * Default Theme Values\n *\n * These defaults ensure backwards compatibility - components render\n * identically to before theming was introduced when no theme is provided.\n */\n\nimport type {\n ButtonVariantStyles,\n BackgroundStyles,\n ColorPreset,\n ResolvedTheme,\n} from './types'\n\n/**\n * Default button variant styles\n * Uses semantic Tailwind classes that map to CSS variables (--primary, --secondary, etc.)\n * This allows consuming apps to customize colors via their theme CSS variables.\n */\nexport const DEFAULT_BUTTON_VARIANTS: ButtonVariantStyles = {\n default: { classes: 'bg-primary text-primary-foreground hover:bg-primary/90' },\n secondary: { classes: 'bg-secondary text-secondary-foreground hover:bg-secondary/80' },\n outline: { classes: 'border border-input bg-background hover:bg-accent hover:text-accent-foreground' },\n ghost: { classes: 'bg-transparent hover:bg-accent hover:text-accent-foreground' },\n destructive: { classes: 'bg-destructive text-destructive-foreground hover:bg-destructive/90' },\n link: { classes: 'text-primary underline-offset-4 hover:underline bg-transparent' },\n}\n\n/**\n * Default CTA button variant styles\n * Uses semantic Tailwind classes that map to CSS variables.\n */\nexport const DEFAULT_CTA_BUTTON_VARIANTS: ButtonVariantStyles = {\n primary: { classes: 'bg-primary text-primary-foreground hover:bg-primary/90' },\n secondary: { classes: 'bg-secondary text-secondary-foreground hover:bg-secondary/80' },\n outline: { classes: 'border border-input bg-background hover:bg-accent hover:text-accent-foreground' },\n ghost: { classes: 'bg-transparent hover:bg-accent hover:text-accent-foreground' },\n link: { classes: 'text-primary underline-offset-4 hover:underline bg-transparent' },\n}\n\n/**\n * Default CTA background styles\n * Uses semantic Tailwind classes that map to CSS variables.\n */\nexport const DEFAULT_CTA_BACKGROUND_STYLES: BackgroundStyles = {\n default: 'bg-muted',\n dark: 'bg-foreground text-background',\n light: 'bg-background',\n}\n\n/**\n * Default color picker presets\n * Matches DEFAULT_PRESETS from ColorPickerField.tsx\n */\nexport const DEFAULT_COLOR_PRESETS: ColorPreset[] = [\n { hex: '#ffffff', label: 'White' },\n { hex: '#f9fafb', label: 'Gray 50' },\n { hex: '#f3f4f6', label: 'Gray 100' },\n { hex: '#1f2937', label: 'Gray 800' },\n { hex: '#111827', label: 'Gray 900' },\n { hex: '#000000', label: 'Black' },\n { hex: '#3b82f6', label: 'Blue' },\n { hex: '#10b981', label: 'Green' },\n { hex: '#f59e0b', label: 'Amber' },\n { hex: '#ef4444', label: 'Red' },\n]\n\n/**\n * Default focus ring color class\n * Uses semantic ring color from CSS variables\n */\nexport const DEFAULT_FOCUS_RING = 'focus:ring-ring'\n\n/**\n * Complete default theme\n * Used when no ThemeProvider is present or no theme config is provided\n */\nexport const DEFAULT_THEME: ResolvedTheme = {\n buttonVariants: DEFAULT_BUTTON_VARIANTS,\n ctaButtonVariants: DEFAULT_CTA_BUTTON_VARIANTS,\n ctaBackgroundStyles: DEFAULT_CTA_BACKGROUND_STYLES,\n colorPresets: DEFAULT_COLOR_PRESETS,\n focusRingColor: DEFAULT_FOCUS_RING,\n}\n","/**\n * Theme Resolution Utilities\n *\n * Functions for merging user-provided theme config with defaults\n * and safely accessing theme values.\n */\n\nimport type {\n ThemeConfig,\n ResolvedTheme,\n ButtonVariantStyles,\n BackgroundStyles,\n} from './types'\nimport {\n DEFAULT_BUTTON_VARIANTS,\n DEFAULT_CTA_BUTTON_VARIANTS,\n DEFAULT_CTA_BACKGROUND_STYLES,\n DEFAULT_COLOR_PRESETS,\n DEFAULT_FOCUS_RING,\n DEFAULT_THEME,\n} from './defaults'\n\n/**\n * Merges user-provided theme config with defaults to create a fully resolved theme\n */\nexport function resolveTheme(config?: ThemeConfig): ResolvedTheme {\n if (!config) return DEFAULT_THEME\n\n return {\n buttonVariants: mergeVariants(DEFAULT_BUTTON_VARIANTS, config.buttonVariants),\n ctaButtonVariants: mergeVariants(DEFAULT_CTA_BUTTON_VARIANTS, config.ctaButtonVariants),\n ctaBackgroundStyles: mergeBackgroundStyles(\n DEFAULT_CTA_BACKGROUND_STYLES,\n config.ctaBackgroundStyles\n ),\n colorPresets: resolveColorPresets(config),\n focusRingColor: config.focusRingColor ?? DEFAULT_FOCUS_RING,\n }\n}\n\n/**\n * Merges variant overrides with defaults\n */\nfunction mergeVariants(\n defaults: ButtonVariantStyles,\n overrides?: Partial<ButtonVariantStyles>\n): ButtonVariantStyles {\n if (!overrides) return defaults\n\n const result: ButtonVariantStyles = { ...defaults }\n for (const key of Object.keys(overrides)) {\n const override = overrides[key]\n if (override) {\n result[key] = override\n }\n }\n return result\n}\n\n/**\n * Merges background style overrides with defaults\n */\nfunction mergeBackgroundStyles(\n defaults: BackgroundStyles,\n overrides?: Partial<BackgroundStyles>\n): BackgroundStyles {\n if (!overrides) return defaults\n return { ...defaults, ...overrides }\n}\n\n/**\n * Resolves color presets based on config\n */\nfunction resolveColorPresets(config: ThemeConfig) {\n if (!config.colorPresets) {\n return DEFAULT_COLOR_PRESETS\n }\n\n if (config.extendColorPresets) {\n return [...DEFAULT_COLOR_PRESETS, ...config.colorPresets]\n }\n\n return config.colorPresets\n}\n\n/**\n * Safely gets variant classes from a variant styles object\n *\n * @param variants - The button variant styles object\n * @param variant - The variant key to look up\n * @param fallback - Fallback variant key if the requested variant doesn't exist\n * @returns The CSS classes string for the variant\n */\nexport function getVariantClasses(\n variants: ButtonVariantStyles,\n variant: string,\n fallback = 'default'\n): string {\n const config = variants[variant]\n if (config?.classes) {\n return config.classes\n }\n\n const fallbackConfig = variants[fallback]\n return fallbackConfig?.classes ?? ''\n}\n\n/**\n * Safely gets background style classes\n *\n * @param styles - The background styles object\n * @param style - The style key to look up\n * @param fallback - Fallback style key if the requested style doesn't exist\n * @returns The CSS classes string for the background\n */\nexport function getBackgroundClasses(\n styles: BackgroundStyles,\n style: string,\n fallback = 'default'\n): string {\n return styles[style] ?? styles[fallback] ?? ''\n}\n","'use client'\n\n/**\n * Theme Context\n *\n * React context for distributing theme configuration to Puck components.\n * The useTheme() hook returns defaults when no provider is present,\n * ensuring backwards compatibility.\n */\n\nimport { createContext, useContext, useMemo, type ReactNode } from 'react'\nimport type { ThemeConfig, ThemeContextValue, ResolvedTheme } from './types'\nimport { DEFAULT_THEME } from './defaults'\nimport { resolveTheme } from './utils'\n\nconst ThemeContext = createContext<ThemeContextValue | null>(null)\n\nexport interface ThemeProviderProps {\n children: ReactNode\n /** Theme configuration to apply */\n theme?: ThemeConfig\n}\n\n/**\n * Provides theme configuration to descendant Puck components\n *\n * @example\n * ```tsx\n * <ThemeProvider theme={{\n * buttonVariants: {\n * default: { classes: 'bg-primary text-white hover:bg-primary/90' }\n * }\n * }}>\n * <PageRenderer data={data} />\n * </ThemeProvider>\n * ```\n */\nexport function ThemeProvider({ children, theme }: ThemeProviderProps) {\n const resolvedTheme = useMemo(() => resolveTheme(theme), [theme])\n\n const value = useMemo<ThemeContextValue>(\n () => ({\n theme: resolvedTheme,\n }),\n [resolvedTheme]\n )\n\n return <ThemeContext.Provider value={value}>{children}</ThemeContext.Provider>\n}\n\n/**\n * Hook to access the current theme\n *\n * Returns DEFAULT_THEME if no ThemeProvider is present,\n * ensuring components work standalone for backwards compatibility.\n *\n * @example\n * ```tsx\n * function MyComponent() {\n * const theme = useTheme()\n * const buttonClasses = getVariantClasses(theme.buttonVariants, 'primary')\n * return <button className={buttonClasses}>Click me</button>\n * }\n * ```\n */\nexport function useTheme(): ResolvedTheme {\n const context = useContext(ThemeContext)\n // Return defaults if no provider - ensures backwards compatibility\n return context?.theme ?? DEFAULT_THEME\n}\n\n/**\n * Gets the default theme for server components\n *\n * Use this when you need theme values in a server component\n * where hooks cannot be used.\n */\nexport function getDefaultTheme(): ResolvedTheme {\n return DEFAULT_THEME\n}\n\n/**\n * Hook to check if a ThemeProvider is present\n *\n * Useful for conditional logic based on whether theming is configured.\n */\nexport function useHasThemeProvider(): boolean {\n const context = useContext(ThemeContext)\n return context !== null\n}\n","/**\n * Example Theme Configuration\n *\n * Copy this file to your project and customize it to match your design system.\n *\n * Usage:\n * 1. Copy this file to your project (e.g., src/lib/puck-theme.ts)\n * 2. Customize the values to match your CSS variables/design tokens\n * 3. Import and pass to PageRenderer or PuckEditor:\n *\n * ```tsx\n * import { puckTheme } from '@/lib/puck-theme'\n *\n * <PageRenderer data={data} config={config} theme={puckTheme} />\n * ```\n */\n\nimport type { ThemeConfig } from './types'\n\n/**\n * Example theme using shadcn/ui CSS variables\n *\n * This example assumes you have CSS variables like:\n * --primary, --primary-foreground\n * --secondary, --secondary-foreground\n * --accent, --accent-foreground\n * --muted, --muted-foreground\n * --destructive, --destructive-foreground\n * --ring (for focus rings)\n */\nexport const exampleTheme: ThemeConfig = {\n // Button component variants\n buttonVariants: {\n default: {\n classes: 'bg-primary text-primary-foreground hover:bg-primary/90',\n },\n secondary: {\n classes: 'bg-secondary text-secondary-foreground hover:bg-secondary/80',\n },\n outline: {\n classes: 'border border-input bg-background hover:bg-accent hover:text-accent-foreground',\n },\n ghost: {\n classes: 'hover:bg-accent hover:text-accent-foreground',\n },\n destructive: {\n classes: 'bg-destructive text-destructive-foreground hover:bg-destructive/90',\n },\n link: {\n classes: 'text-primary underline-offset-4 hover:underline',\n },\n },\n\n // CTA button variants\n ctaButtonVariants: {\n primary: {\n classes: 'bg-primary text-primary-foreground hover:bg-primary/90',\n },\n secondary: {\n classes: 'bg-secondary text-secondary-foreground hover:bg-secondary/80',\n },\n outline: {\n classes: 'border border-input bg-background hover:bg-accent hover:text-accent-foreground',\n },\n },\n\n // CTA background styles\n ctaBackgroundStyles: {\n default: 'bg-muted',\n dark: 'bg-primary text-primary-foreground',\n light: 'bg-background',\n },\n\n // Focus ring class\n focusRingColor: 'focus:ring-ring',\n\n // Color picker presets - customize with your brand colors\n colorPresets: [\n { hex: '#ffffff', label: 'White' },\n { hex: '#f8fafc', label: 'Slate 50' },\n { hex: '#f1f5f9', label: 'Slate 100' },\n { hex: '#e2e8f0', label: 'Slate 200' },\n { hex: '#64748b', label: 'Slate 500' },\n { hex: '#334155', label: 'Slate 700' },\n { hex: '#1e293b', label: 'Slate 800' },\n { hex: '#0f172a', label: 'Slate 900' },\n { hex: '#000000', label: 'Black' },\n { hex: '#3b82f6', label: 'Blue' },\n { hex: '#10b981', label: 'Green' },\n { hex: '#f59e0b', label: 'Amber' },\n { hex: '#ef4444', label: 'Red' },\n ],\n\n // Set to true to add your presets to defaults instead of replacing\n extendColorPresets: false,\n}\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../src/utils/migration.ts","../../src/utils/validation.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Migration Utility for Converting Legacy Payload CMS Pages to Puck Format\n *\n * This utility converts legacy Payload CMS page block structures to the\n * Puck visual editor format, enabling seamless migration of existing content.\n */\n\nimport type { PuckPageData, PuckRootProps, MediaObject } from '../types'\n\n// =============================================================================\n// Type Definitions\n// =============================================================================\n\n/**\n * Legacy block from Payload CMS pages.\n * Each block has a blockType discriminator and various props.\n */\nexport interface LegacyBlock {\n blockType: string\n id?: string | null\n blockName?: string | null\n [key: string]: unknown\n}\n\n/**\n * Subset of Page type used for migration.\n * Only includes fields relevant to content migration.\n */\nexport interface LegacyPage {\n title: string\n slug: string\n pageLayout?: string\n layout?: LegacyBlock[] | null\n [key: string]: unknown\n}\n\n/**\n * Media reference in Puck format\n */\nexport interface MediaReference {\n id: string | number\n url?: string\n alt?: string\n width?: number\n height?: number\n}\n\n/**\n * Puck content item structure\n */\nexport interface PuckContentItem {\n type: string\n props: { id: string; [key: string]: unknown }\n}\n\n// =============================================================================\n// Block Type Mapping\n// =============================================================================\n\n/**\n * Maps legacy Payload block types (camelCase) to Puck component types (PascalCase).\n * Extend this map to support additional custom block types.\n */\nexport const blockTypeMap: Record<string, string> = {\n heroBlock: 'Hero',\n richTextBlock: 'RichText',\n containerBlock: 'Container',\n flexBlock: 'Flex',\n gridBlock: 'Grid',\n sectionBlock: 'Section',\n spacerBlock: 'Spacer',\n headingBlock: 'Heading',\n textBlock: 'Text',\n imageBlock: 'Image',\n buttonBlock: 'Button',\n cardBlock: 'Card',\n dividerBlock: 'Divider',\n accordionBlock: 'Accordion',\n}\n\n// =============================================================================\n// ID Generation\n// =============================================================================\n\n/**\n * Generates a unique ID for Puck content items.\n * Uses a format compatible with Puck's internal ID scheme.\n */\nexport function generatePuckId(legacyId?: string | null): string {\n if (legacyId) {\n return legacyId\n }\n // Generate a random ID similar to Puck's format\n return `puck-${Date.now()}-${Math.random().toString(36).substring(2, 9)}`\n}\n\n// =============================================================================\n// Prop Transformation Utilities\n// =============================================================================\n\n/**\n * Transforms a Payload media reference (ID or Media object) to Puck MediaReference format.\n * Handles both ID-only references and full Media objects.\n */\nexport function transformMediaReference(\n media:\n | string\n | number\n | { id: string | number; url?: string; alt?: string; width?: number; height?: number }\n | MediaObject\n | null\n | undefined\n): MediaReference | null {\n if (media === null || media === undefined) {\n return null\n }\n\n if (typeof media === 'number' || typeof media === 'string') {\n // Just an ID reference - Puck will need to fetch the full media\n return { id: media }\n }\n\n // Full media object\n return {\n id: media.id,\n url: media.url,\n alt: media.alt,\n width: media.width,\n height: media.height,\n }\n}\n\n/**\n * Transforms Lexical rich text content to a serialized string format.\n * Puck stores rich text as JSON strings for the custom editors.\n */\nexport function transformRichText(richText: unknown): string | undefined {\n if (!richText) {\n return undefined\n }\n\n // If it's already a string, return as-is\n if (typeof richText === 'string') {\n return richText\n }\n\n // If it's an object (Lexical format), serialize it\n if (typeof richText === 'object') {\n try {\n return JSON.stringify(richText)\n } catch {\n console.warn('[payload-puck] Failed to serialize rich text content')\n return undefined\n }\n }\n\n return undefined\n}\n\n/**\n * Transforms an array of relationships to Puck format.\n */\nexport function transformRelationshipArray<\n T extends { id: string | number; title?: string; slug?: string },\n>(\n relations: (string | number | T)[] | null | undefined\n): Array<{ id: string | number; title: string; slug?: string }> | undefined {\n if (!relations || !Array.isArray(relations)) {\n return undefined\n }\n\n return relations.map((rel) => {\n if (typeof rel === 'number' || typeof rel === 'string') {\n return { id: rel, title: '' } // Title will need to be fetched\n }\n return {\n id: rel.id,\n title: rel.title || '',\n slug: rel.slug,\n }\n })\n}\n\n// =============================================================================\n// Block Prop Transformation\n// =============================================================================\n\n/**\n * Known rich text field names in legacy blocks\n */\nconst RICH_TEXT_FIELDS = [\n 'headingRich',\n 'subheadingRich',\n 'textRich',\n 'content',\n 'leftContent',\n 'rightContent',\n 'bodyContent',\n 'description',\n]\n\n/**\n * Known media field names in legacy blocks\n */\nconst MEDIA_FIELDS = [\n 'backgroundImage',\n 'image',\n 'rightImage',\n 'leftImage',\n 'profileImage',\n 'media',\n 'thumbnail',\n 'icon',\n]\n\n/**\n * Transform props for a specific block type.\n * Handles any block-specific transformations needed.\n */\nexport function transformBlockProps(\n block: LegacyBlock,\n options?: {\n richTextFields?: string[]\n mediaFields?: string[]\n customTransformers?: Record<string, (value: unknown) => unknown>\n }\n): Record<string, unknown> {\n const { blockType, id, blockName, ...restProps } = block\n const richTextFields = options?.richTextFields || RICH_TEXT_FIELDS\n const mediaFields = options?.mediaFields || MEDIA_FIELDS\n const customTransformers = options?.customTransformers || {}\n\n const props: Record<string, unknown> = {\n id: generatePuckId(id),\n }\n\n // Process each prop based on known patterns\n for (const [key, value] of Object.entries(restProps)) {\n // Check for custom transformer first\n if (customTransformers[key]) {\n props[key] = customTransformers[key](value)\n continue\n }\n\n // Rich text fields - serialize Lexical content\n if (richTextFields.includes(key)) {\n props[key] = transformRichText(value)\n continue\n }\n\n // Media fields - transform to MediaReference\n if (mediaFields.includes(key)) {\n props[key] = transformMediaReference(\n value as\n | string\n | number\n | { id: string | number; url?: string; alt?: string }\n | null\n )\n continue\n }\n\n // Array fields that need ID generation for items\n if (Array.isArray(value)) {\n props[key] = value.map((item) => {\n if (typeof item === 'object' && item !== null) {\n const { id: itemId, ...itemRest } = item as {\n id?: string\n [k: string]: unknown\n }\n return {\n ...itemRest,\n id: itemId || generatePuckId(),\n }\n }\n return item\n })\n continue\n }\n\n // Default: pass through as-is\n props[key] = value\n }\n\n return props\n}\n\n// =============================================================================\n// Main Migration Function\n// =============================================================================\n\n/**\n * Options for the migration function\n */\nexport interface MigrateLegacyOptions {\n /**\n * Custom block type mapping to extend or override defaults\n */\n blockTypeMap?: Record<string, string>\n\n /**\n * Additional rich text field names to transform\n */\n richTextFields?: string[]\n\n /**\n * Additional media field names to transform\n */\n mediaFields?: string[]\n\n /**\n * Custom prop transformers for specific field names\n */\n customTransformers?: Record<string, (value: unknown) => unknown>\n\n /**\n * Whether to skip unknown block types (default: true)\n * If false, unknown blocks will throw an error\n */\n skipUnknownBlocks?: boolean\n\n /**\n * Callback for handling unknown block types\n */\n onUnknownBlock?: (block: LegacyBlock) => PuckContentItem | null\n}\n\n/**\n * Migrates a legacy Payload CMS page to Puck format.\n *\n * This function:\n * 1. Extracts root props (title, pageLayout, etc.)\n * 2. Converts each block in the layout array to a Puck content item\n * 3. Maps block types from camelCase to PascalCase using blockTypeMap\n * 4. Transforms block props appropriately\n *\n * @param page - The legacy Page object from Payload CMS\n * @param options - Migration options\n * @returns PuckPageData ready for use with the Puck editor\n *\n * @example\n * ```ts\n * const legacyPage = await payload.findByID({ collection: 'pages', id: pageId })\n * const puckData = migrateLegacyToPuck(legacyPage)\n * await payload.update({\n * collection: 'pages',\n * id: pageId,\n * data: { puckData },\n * })\n * ```\n */\nexport function migrateLegacyToPuck(\n page: LegacyPage,\n options: MigrateLegacyOptions = {}\n): PuckPageData {\n const {\n blockTypeMap: customBlockTypeMap,\n richTextFields,\n mediaFields,\n customTransformers,\n skipUnknownBlocks = true,\n onUnknownBlock,\n } = options\n\n // Merge custom block type map with defaults\n const effectiveBlockTypeMap = {\n ...blockTypeMap,\n ...customBlockTypeMap,\n }\n\n // Build root props\n const rootProps: PuckRootProps = {\n title: page.title,\n pageLayout: page.pageLayout || 'default',\n }\n\n // Convert layout blocks to Puck content items\n const content: PuckContentItem[] = []\n\n if (page.layout && Array.isArray(page.layout)) {\n for (const block of page.layout) {\n const legacyBlock = block as LegacyBlock\n\n // Get the Puck component type from the legacy block type\n const puckType = effectiveBlockTypeMap[legacyBlock.blockType]\n\n if (!puckType) {\n // Handle unknown block type\n if (onUnknownBlock) {\n const customItem = onUnknownBlock(legacyBlock)\n if (customItem) {\n content.push(customItem)\n }\n continue\n }\n\n if (skipUnknownBlocks) {\n console.warn(\n `[payload-puck] Unknown block type \"${legacyBlock.blockType}\" - skipping during migration`\n )\n continue\n }\n\n throw new Error(\n `Unknown block type \"${legacyBlock.blockType}\" encountered during migration`\n )\n }\n\n // Transform the block props\n const transformedProps = transformBlockProps(legacyBlock, {\n richTextFields,\n mediaFields,\n customTransformers,\n })\n\n // Create the Puck content item\n const contentItem: PuckContentItem = {\n type: puckType,\n props: transformedProps as { id: string; [key: string]: unknown },\n }\n\n content.push(contentItem)\n }\n }\n\n // Build the complete Puck data structure\n const puckData: PuckPageData = {\n root: {\n props: rootProps,\n },\n content,\n zones: {},\n }\n\n return puckData\n}\n\n// =============================================================================\n// Migration Preview\n// =============================================================================\n\n/**\n * Migration preview result\n */\nexport interface MigrationPreview {\n title: string\n slug: string\n blockCount: number\n blockTypes: string[]\n warnings: string[]\n unmappedBlockTypes: string[]\n}\n\n/**\n * Gets a summary of a legacy page for migration preview.\n * Useful for showing users what will be migrated before committing.\n *\n * @param page - The legacy page to preview\n * @param customBlockTypeMap - Optional custom block type mapping\n * @returns Preview information about the migration\n */\nexport function getMigrationPreview(\n page: LegacyPage,\n customBlockTypeMap?: Record<string, string>\n): MigrationPreview {\n const warnings: string[] = []\n const blockTypes: string[] = []\n const unmappedBlockTypes: string[] = []\n\n const effectiveBlockTypeMap = {\n ...blockTypeMap,\n ...customBlockTypeMap,\n }\n\n if (page.layout && Array.isArray(page.layout)) {\n for (const block of page.layout) {\n const legacyBlock = block as LegacyBlock\n const puckType = effectiveBlockTypeMap[legacyBlock.blockType]\n\n if (puckType) {\n blockTypes.push(puckType)\n } else {\n warnings.push(`Unknown block type: ${legacyBlock.blockType}`)\n if (!unmappedBlockTypes.includes(legacyBlock.blockType)) {\n unmappedBlockTypes.push(legacyBlock.blockType)\n }\n }\n }\n }\n\n return {\n title: page.title,\n slug: page.slug,\n blockCount: page.layout?.length || 0,\n blockTypes,\n warnings,\n unmappedBlockTypes,\n }\n}\n","/**\n * Puck Data Validation Utilities\n *\n * Provides validation functions for ensuring Puck data structures are well-formed.\n */\n\nimport type { PuckPageData, PuckRootProps } from '../types'\n\n// =============================================================================\n// Validation Result Types\n// =============================================================================\n\n/**\n * Result of a validation operation\n */\nexport interface ValidationResult {\n valid: boolean\n errors: string[]\n warnings: string[]\n}\n\n/**\n * Options for validation\n */\nexport interface ValidationOptions {\n /**\n * Whether to validate that all content items have IDs\n * @default true\n */\n requireContentIds?: boolean\n\n /**\n * Whether to validate root props\n * @default true\n */\n validateRoot?: boolean\n\n /**\n * Required root prop fields\n * @default ['title']\n */\n requiredRootProps?: string[]\n\n /**\n * Allowed component types (if specified, unknown types will be flagged)\n */\n allowedComponentTypes?: string[]\n\n /**\n * Whether to treat unknown component types as errors (vs warnings)\n * @default false\n */\n strictComponentTypes?: boolean\n}\n\n// =============================================================================\n// Type Guards\n// =============================================================================\n\n/**\n * Type guard to check if a value is a valid PuckPageData structure.\n * Performs basic structural validation.\n */\nexport function isPuckData(data: unknown): data is PuckPageData {\n if (!data || typeof data !== 'object') {\n return false\n }\n\n const obj = data as Record<string, unknown>\n\n // Check root structure\n if (!obj.root || typeof obj.root !== 'object') {\n return false\n }\n\n const root = obj.root as Record<string, unknown>\n if (!root.props || typeof root.props !== 'object') {\n return false\n }\n\n // Check content array\n if (!Array.isArray(obj.content)) {\n return false\n }\n\n // Validate each content item has required fields\n for (const item of obj.content) {\n if (!item || typeof item !== 'object') {\n return false\n }\n const contentItem = item as Record<string, unknown>\n if (typeof contentItem.type !== 'string') {\n return false\n }\n if (!contentItem.props || typeof contentItem.props !== 'object') {\n return false\n }\n }\n\n // Check zones (optional but must be object if present)\n if (obj.zones !== undefined && typeof obj.zones !== 'object') {\n return false\n }\n\n return true\n}\n\n/**\n * Type guard for PuckRootProps\n */\nexport function isPuckRootProps(props: unknown): props is PuckRootProps {\n if (!props || typeof props !== 'object') {\n return false\n }\n return true\n}\n\n// =============================================================================\n// Validation Functions\n// =============================================================================\n\n/**\n * Validates that a PuckPageData structure is well-formed.\n * Useful for testing and debugging migration issues.\n *\n * @param data - The data to validate\n * @param options - Validation options\n * @returns Validation result with errors and warnings\n *\n * @example\n * ```ts\n * const result = validatePuckData(puckData)\n * if (!result.valid) {\n * console.error('Validation errors:', result.errors)\n * }\n * ```\n */\nexport function validatePuckData(\n data: unknown,\n options: ValidationOptions = {}\n): ValidationResult {\n const {\n requireContentIds = true,\n validateRoot = true,\n requiredRootProps = ['title'],\n allowedComponentTypes,\n strictComponentTypes = false,\n } = options\n\n const errors: string[] = []\n const warnings: string[] = []\n\n // Basic type check\n if (!data || typeof data !== 'object') {\n errors.push('Data must be a non-null object')\n return { valid: false, errors, warnings }\n }\n\n const obj = data as Record<string, unknown>\n\n // ==========================================================================\n // Validate root structure\n // ==========================================================================\n\n if (!obj.root || typeof obj.root !== 'object') {\n errors.push('Missing or invalid root object')\n } else if (validateRoot) {\n const root = obj.root as Record<string, unknown>\n\n if (!root.props || typeof root.props !== 'object') {\n errors.push('Missing root.props object')\n } else {\n const rootProps = root.props as Record<string, unknown>\n\n // Check required root props\n for (const prop of requiredRootProps) {\n if (rootProps[prop] === undefined || rootProps[prop] === null) {\n errors.push(`Missing required root prop: ${prop}`)\n }\n }\n\n // Validate pageLayout if present\n if (rootProps.pageLayout !== undefined) {\n if (typeof rootProps.pageLayout !== 'string') {\n errors.push('root.props.pageLayout must be a string')\n }\n }\n }\n }\n\n // ==========================================================================\n // Validate content array\n // ==========================================================================\n\n if (!Array.isArray(obj.content)) {\n errors.push('content must be an array')\n } else {\n const seenIds = new Set<string>()\n\n obj.content.forEach((item, index) => {\n if (!item || typeof item !== 'object') {\n errors.push(`Content item at index ${index} is not an object`)\n return\n }\n\n const contentItem = item as Record<string, unknown>\n\n // Validate type\n if (!contentItem.type || typeof contentItem.type !== 'string') {\n errors.push(`Content item at index ${index} missing or invalid type`)\n } else if (allowedComponentTypes) {\n if (!allowedComponentTypes.includes(contentItem.type)) {\n const message = `Unknown component type \"${contentItem.type}\" at index ${index}`\n if (strictComponentTypes) {\n errors.push(message)\n } else {\n warnings.push(message)\n }\n }\n }\n\n // Validate props\n if (!contentItem.props || typeof contentItem.props !== 'object') {\n errors.push(`Content item at index ${index} missing props object`)\n } else if (requireContentIds) {\n const props = contentItem.props as Record<string, unknown>\n\n if (!props.id || typeof props.id !== 'string') {\n errors.push(`Content item at index ${index} missing or invalid props.id`)\n } else {\n // Check for duplicate IDs\n if (seenIds.has(props.id)) {\n warnings.push(\n `Duplicate content item ID \"${props.id}\" at index ${index}`\n )\n }\n seenIds.add(props.id)\n }\n }\n })\n }\n\n // ==========================================================================\n // Validate zones\n // ==========================================================================\n\n if (obj.zones !== undefined) {\n if (typeof obj.zones !== 'object' || obj.zones === null) {\n errors.push('zones must be an object')\n } else {\n const zones = obj.zones as Record<string, unknown>\n\n for (const [zoneName, zoneContent] of Object.entries(zones)) {\n if (!Array.isArray(zoneContent)) {\n errors.push(`Zone \"${zoneName}\" content must be an array`)\n continue\n }\n\n zoneContent.forEach((item, index) => {\n if (!item || typeof item !== 'object') {\n errors.push(`Zone \"${zoneName}\" item at index ${index} is not an object`)\n return\n }\n\n const contentItem = item as Record<string, unknown>\n\n if (!contentItem.type || typeof contentItem.type !== 'string') {\n errors.push(\n `Zone \"${zoneName}\" item at index ${index} missing or invalid type`\n )\n }\n\n if (!contentItem.props || typeof contentItem.props !== 'object') {\n errors.push(\n `Zone \"${zoneName}\" item at index ${index} missing props object`\n )\n } else if (requireContentIds) {\n const props = contentItem.props as Record<string, unknown>\n if (!props.id || typeof props.id !== 'string') {\n errors.push(\n `Zone \"${zoneName}\" item at index ${index} missing or invalid props.id`\n )\n }\n }\n })\n }\n }\n }\n\n return {\n valid: errors.length === 0,\n errors,\n warnings,\n }\n}\n\n/**\n * Validates and returns typed PuckPageData, throwing if invalid.\n *\n * @param data - The data to validate\n * @param options - Validation options\n * @returns The validated PuckPageData\n * @throws Error if validation fails\n */\nexport function assertPuckData(\n data: unknown,\n options?: ValidationOptions\n): PuckPageData {\n const result = validatePuckData(data, options)\n\n if (!result.valid) {\n throw new Error(\n `Invalid Puck data: ${result.errors.join('; ')}`\n )\n }\n\n return data as PuckPageData\n}\n\n/**\n * Safely parses JSON and validates as PuckPageData.\n *\n * @param json - JSON string to parse\n * @param options - Validation options\n * @returns Validation result with parsed data if valid\n */\nexport function parsePuckDataJson(\n json: string,\n options?: ValidationOptions\n): ValidationResult & { data?: PuckPageData } {\n let parsed: unknown\n\n try {\n parsed = JSON.parse(json)\n } catch (e) {\n return {\n valid: false,\n errors: [`Invalid JSON: ${e instanceof Error ? e.message : 'Parse error'}`],\n warnings: [],\n }\n }\n\n const result = validatePuckData(parsed, options)\n\n if (result.valid) {\n return {\n ...result,\n data: parsed as PuckPageData,\n }\n }\n\n return result\n}\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../src/utils/migration.ts","../../src/utils/validation.ts"],"names":[],"mappings":"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","file":"index.mjs","sourcesContent":["/**\n * Migration Utility for Converting Legacy Payload CMS Pages to Puck Format\n *\n * This utility converts legacy Payload CMS page block structures to the\n * Puck visual editor format, enabling seamless migration of existing content.\n */\n\nimport type { PuckPageData, PuckRootProps, MediaObject } from '../types'\n\n// =============================================================================\n// Type Definitions\n// =============================================================================\n\n/**\n * Legacy block from Payload CMS pages.\n * Each block has a blockType discriminator and various props.\n */\nexport interface LegacyBlock {\n blockType: string\n id?: string | null\n blockName?: string | null\n [key: string]: unknown\n}\n\n/**\n * Subset of Page type used for migration.\n * Only includes fields relevant to content migration.\n */\nexport interface LegacyPage {\n title: string\n slug: string\n pageLayout?: string\n layout?: LegacyBlock[] | null\n [key: string]: unknown\n}\n\n/**\n * Media reference in Puck format\n */\nexport interface MediaReference {\n id: string | number\n url?: string\n alt?: string\n width?: number\n height?: number\n}\n\n/**\n * Puck content item structure\n */\nexport interface PuckContentItem {\n type: string\n props: { id: string; [key: string]: unknown }\n}\n\n// =============================================================================\n// Block Type Mapping\n// =============================================================================\n\n/**\n * Maps legacy Payload block types (camelCase) to Puck component types (PascalCase).\n * Extend this map to support additional custom block types.\n */\nexport const blockTypeMap: Record<string, string> = {\n heroBlock: 'Hero',\n richTextBlock: 'RichText',\n containerBlock: 'Container',\n flexBlock: 'Flex',\n gridBlock: 'Grid',\n sectionBlock: 'Section',\n spacerBlock: 'Spacer',\n headingBlock: 'Heading',\n textBlock: 'Text',\n imageBlock: 'Image',\n buttonBlock: 'Button',\n cardBlock: 'Card',\n dividerBlock: 'Divider',\n accordionBlock: 'Accordion',\n}\n\n// =============================================================================\n// ID Generation\n// =============================================================================\n\n/**\n * Generates a unique ID for Puck content items.\n * Uses a format compatible with Puck's internal ID scheme.\n */\nexport function generatePuckId(legacyId?: string | null): string {\n if (legacyId) {\n return legacyId\n }\n // Generate a random ID similar to Puck's format\n return `puck-${Date.now()}-${Math.random().toString(36).substring(2, 9)}`\n}\n\n// =============================================================================\n// Prop Transformation Utilities\n// =============================================================================\n\n/**\n * Transforms a Payload media reference (ID or Media object) to Puck MediaReference format.\n * Handles both ID-only references and full Media objects.\n */\nexport function transformMediaReference(\n media:\n | string\n | number\n | { id: string | number; url?: string; alt?: string; width?: number; height?: number }\n | MediaObject\n | null\n | undefined\n): MediaReference | null {\n if (media === null || media === undefined) {\n return null\n }\n\n if (typeof media === 'number' || typeof media === 'string') {\n // Just an ID reference - Puck will need to fetch the full media\n return { id: media }\n }\n\n // Full media object\n return {\n id: media.id,\n url: media.url,\n alt: media.alt,\n width: media.width,\n height: media.height,\n }\n}\n\n/**\n * Transforms Lexical rich text content to a serialized string format.\n * Puck stores rich text as JSON strings for the custom editors.\n */\nexport function transformRichText(richText: unknown): string | undefined {\n if (!richText) {\n return undefined\n }\n\n // If it's already a string, return as-is\n if (typeof richText === 'string') {\n return richText\n }\n\n // If it's an object (Lexical format), serialize it\n if (typeof richText === 'object') {\n try {\n return JSON.stringify(richText)\n } catch {\n console.warn('[payload-puck] Failed to serialize rich text content')\n return undefined\n }\n }\n\n return undefined\n}\n\n/**\n * Transforms an array of relationships to Puck format.\n */\nexport function transformRelationshipArray<\n T extends { id: string | number; title?: string; slug?: string },\n>(\n relations: (string | number | T)[] | null | undefined\n): Array<{ id: string | number; title: string; slug?: string }> | undefined {\n if (!relations || !Array.isArray(relations)) {\n return undefined\n }\n\n return relations.map((rel) => {\n if (typeof rel === 'number' || typeof rel === 'string') {\n return { id: rel, title: '' } // Title will need to be fetched\n }\n return {\n id: rel.id,\n title: rel.title || '',\n slug: rel.slug,\n }\n })\n}\n\n// =============================================================================\n// Block Prop Transformation\n// =============================================================================\n\n/**\n * Known rich text field names in legacy blocks\n */\nconst RICH_TEXT_FIELDS = [\n 'headingRich',\n 'subheadingRich',\n 'textRich',\n 'content',\n 'leftContent',\n 'rightContent',\n 'bodyContent',\n 'description',\n]\n\n/**\n * Known media field names in legacy blocks\n */\nconst MEDIA_FIELDS = [\n 'backgroundImage',\n 'image',\n 'rightImage',\n 'leftImage',\n 'profileImage',\n 'media',\n 'thumbnail',\n 'icon',\n]\n\n/**\n * Transform props for a specific block type.\n * Handles any block-specific transformations needed.\n */\nexport function transformBlockProps(\n block: LegacyBlock,\n options?: {\n richTextFields?: string[]\n mediaFields?: string[]\n customTransformers?: Record<string, (value: unknown) => unknown>\n }\n): Record<string, unknown> {\n const { blockType, id, blockName, ...restProps } = block\n const richTextFields = options?.richTextFields || RICH_TEXT_FIELDS\n const mediaFields = options?.mediaFields || MEDIA_FIELDS\n const customTransformers = options?.customTransformers || {}\n\n const props: Record<string, unknown> = {\n id: generatePuckId(id),\n }\n\n // Process each prop based on known patterns\n for (const [key, value] of Object.entries(restProps)) {\n // Check for custom transformer first\n if (customTransformers[key]) {\n props[key] = customTransformers[key](value)\n continue\n }\n\n // Rich text fields - serialize Lexical content\n if (richTextFields.includes(key)) {\n props[key] = transformRichText(value)\n continue\n }\n\n // Media fields - transform to MediaReference\n if (mediaFields.includes(key)) {\n props[key] = transformMediaReference(\n value as\n | string\n | number\n | { id: string | number; url?: string; alt?: string }\n | null\n )\n continue\n }\n\n // Array fields that need ID generation for items\n if (Array.isArray(value)) {\n props[key] = value.map((item) => {\n if (typeof item === 'object' && item !== null) {\n const { id: itemId, ...itemRest } = item as {\n id?: string\n [k: string]: unknown\n }\n return {\n ...itemRest,\n id: itemId || generatePuckId(),\n }\n }\n return item\n })\n continue\n }\n\n // Default: pass through as-is\n props[key] = value\n }\n\n return props\n}\n\n// =============================================================================\n// Main Migration Function\n// =============================================================================\n\n/**\n * Options for the migration function\n */\nexport interface MigrateLegacyOptions {\n /**\n * Custom block type mapping to extend or override defaults\n */\n blockTypeMap?: Record<string, string>\n\n /**\n * Additional rich text field names to transform\n */\n richTextFields?: string[]\n\n /**\n * Additional media field names to transform\n */\n mediaFields?: string[]\n\n /**\n * Custom prop transformers for specific field names\n */\n customTransformers?: Record<string, (value: unknown) => unknown>\n\n /**\n * Whether to skip unknown block types (default: true)\n * If false, unknown blocks will throw an error\n */\n skipUnknownBlocks?: boolean\n\n /**\n * Callback for handling unknown block types\n */\n onUnknownBlock?: (block: LegacyBlock) => PuckContentItem | null\n}\n\n/**\n * Migrates a legacy Payload CMS page to Puck format.\n *\n * This function:\n * 1. Extracts root props (title, pageLayout, etc.)\n * 2. Converts each block in the layout array to a Puck content item\n * 3. Maps block types from camelCase to PascalCase using blockTypeMap\n * 4. Transforms block props appropriately\n *\n * @param page - The legacy Page object from Payload CMS\n * @param options - Migration options\n * @returns PuckPageData ready for use with the Puck editor\n *\n * @example\n * ```ts\n * const legacyPage = await payload.findByID({ collection: 'pages', id: pageId })\n * const puckData = migrateLegacyToPuck(legacyPage)\n * await payload.update({\n * collection: 'pages',\n * id: pageId,\n * data: { puckData },\n * })\n * ```\n */\nexport function migrateLegacyToPuck(\n page: LegacyPage,\n options: MigrateLegacyOptions = {}\n): PuckPageData {\n const {\n blockTypeMap: customBlockTypeMap,\n richTextFields,\n mediaFields,\n customTransformers,\n skipUnknownBlocks = true,\n onUnknownBlock,\n } = options\n\n // Merge custom block type map with defaults\n const effectiveBlockTypeMap = {\n ...blockTypeMap,\n ...customBlockTypeMap,\n }\n\n // Build root props\n const rootProps: PuckRootProps = {\n title: page.title,\n pageLayout: page.pageLayout || 'default',\n }\n\n // Convert layout blocks to Puck content items\n const content: PuckContentItem[] = []\n\n if (page.layout && Array.isArray(page.layout)) {\n for (const block of page.layout) {\n const legacyBlock = block as LegacyBlock\n\n // Get the Puck component type from the legacy block type\n const puckType = effectiveBlockTypeMap[legacyBlock.blockType]\n\n if (!puckType) {\n // Handle unknown block type\n if (onUnknownBlock) {\n const customItem = onUnknownBlock(legacyBlock)\n if (customItem) {\n content.push(customItem)\n }\n continue\n }\n\n if (skipUnknownBlocks) {\n console.warn(\n `[payload-puck] Unknown block type \"${legacyBlock.blockType}\" - skipping during migration`\n )\n continue\n }\n\n throw new Error(\n `Unknown block type \"${legacyBlock.blockType}\" encountered during migration`\n )\n }\n\n // Transform the block props\n const transformedProps = transformBlockProps(legacyBlock, {\n richTextFields,\n mediaFields,\n customTransformers,\n })\n\n // Create the Puck content item\n const contentItem: PuckContentItem = {\n type: puckType,\n props: transformedProps as { id: string; [key: string]: unknown },\n }\n\n content.push(contentItem)\n }\n }\n\n // Build the complete Puck data structure\n const puckData: PuckPageData = {\n root: {\n props: rootProps,\n },\n content,\n zones: {},\n }\n\n return puckData\n}\n\n// =============================================================================\n// Migration Preview\n// =============================================================================\n\n/**\n * Migration preview result\n */\nexport interface MigrationPreview {\n title: string\n slug: string\n blockCount: number\n blockTypes: string[]\n warnings: string[]\n unmappedBlockTypes: string[]\n}\n\n/**\n * Gets a summary of a legacy page for migration preview.\n * Useful for showing users what will be migrated before committing.\n *\n * @param page - The legacy page to preview\n * @param customBlockTypeMap - Optional custom block type mapping\n * @returns Preview information about the migration\n */\nexport function getMigrationPreview(\n page: LegacyPage,\n customBlockTypeMap?: Record<string, string>\n): MigrationPreview {\n const warnings: string[] = []\n const blockTypes: string[] = []\n const unmappedBlockTypes: string[] = []\n\n const effectiveBlockTypeMap = {\n ...blockTypeMap,\n ...customBlockTypeMap,\n }\n\n if (page.layout && Array.isArray(page.layout)) {\n for (const block of page.layout) {\n const legacyBlock = block as LegacyBlock\n const puckType = effectiveBlockTypeMap[legacyBlock.blockType]\n\n if (puckType) {\n blockTypes.push(puckType)\n } else {\n warnings.push(`Unknown block type: ${legacyBlock.blockType}`)\n if (!unmappedBlockTypes.includes(legacyBlock.blockType)) {\n unmappedBlockTypes.push(legacyBlock.blockType)\n }\n }\n }\n }\n\n return {\n title: page.title,\n slug: page.slug,\n blockCount: page.layout?.length || 0,\n blockTypes,\n warnings,\n unmappedBlockTypes,\n }\n}\n","/**\n * Puck Data Validation Utilities\n *\n * Provides validation functions for ensuring Puck data structures are well-formed.\n */\n\nimport type { PuckPageData, PuckRootProps } from '../types'\n\n// =============================================================================\n// Validation Result Types\n// =============================================================================\n\n/**\n * Result of a validation operation\n */\nexport interface ValidationResult {\n valid: boolean\n errors: string[]\n warnings: string[]\n}\n\n/**\n * Options for validation\n */\nexport interface ValidationOptions {\n /**\n * Whether to validate that all content items have IDs\n * @default true\n */\n requireContentIds?: boolean\n\n /**\n * Whether to validate root props\n * @default true\n */\n validateRoot?: boolean\n\n /**\n * Required root prop fields\n * @default ['title']\n */\n requiredRootProps?: string[]\n\n /**\n * Allowed component types (if specified, unknown types will be flagged)\n */\n allowedComponentTypes?: string[]\n\n /**\n * Whether to treat unknown component types as errors (vs warnings)\n * @default false\n */\n strictComponentTypes?: boolean\n}\n\n// =============================================================================\n// Type Guards\n// =============================================================================\n\n/**\n * Type guard to check if a value is a valid PuckPageData structure.\n * Performs basic structural validation.\n */\nexport function isPuckData(data: unknown): data is PuckPageData {\n if (!data || typeof data !== 'object') {\n return false\n }\n\n const obj = data as Record<string, unknown>\n\n // Check root structure\n if (!obj.root || typeof obj.root !== 'object') {\n return false\n }\n\n const root = obj.root as Record<string, unknown>\n if (!root.props || typeof root.props !== 'object') {\n return false\n }\n\n // Check content array\n if (!Array.isArray(obj.content)) {\n return false\n }\n\n // Validate each content item has required fields\n for (const item of obj.content) {\n if (!item || typeof item !== 'object') {\n return false\n }\n const contentItem = item as Record<string, unknown>\n if (typeof contentItem.type !== 'string') {\n return false\n }\n if (!contentItem.props || typeof contentItem.props !== 'object') {\n return false\n }\n }\n\n // Check zones (optional but must be object if present)\n if (obj.zones !== undefined && typeof obj.zones !== 'object') {\n return false\n }\n\n return true\n}\n\n/**\n * Type guard for PuckRootProps\n */\nexport function isPuckRootProps(props: unknown): props is PuckRootProps {\n if (!props || typeof props !== 'object') {\n return false\n }\n return true\n}\n\n// =============================================================================\n// Validation Functions\n// =============================================================================\n\n/**\n * Validates that a PuckPageData structure is well-formed.\n * Useful for testing and debugging migration issues.\n *\n * @param data - The data to validate\n * @param options - Validation options\n * @returns Validation result with errors and warnings\n *\n * @example\n * ```ts\n * const result = validatePuckData(puckData)\n * if (!result.valid) {\n * console.error('Validation errors:', result.errors)\n * }\n * ```\n */\nexport function validatePuckData(\n data: unknown,\n options: ValidationOptions = {}\n): ValidationResult {\n const {\n requireContentIds = true,\n validateRoot = true,\n requiredRootProps = ['title'],\n allowedComponentTypes,\n strictComponentTypes = false,\n } = options\n\n const errors: string[] = []\n const warnings: string[] = []\n\n // Basic type check\n if (!data || typeof data !== 'object') {\n errors.push('Data must be a non-null object')\n return { valid: false, errors, warnings }\n }\n\n const obj = data as Record<string, unknown>\n\n // ==========================================================================\n // Validate root structure\n // ==========================================================================\n\n if (!obj.root || typeof obj.root !== 'object') {\n errors.push('Missing or invalid root object')\n } else if (validateRoot) {\n const root = obj.root as Record<string, unknown>\n\n if (!root.props || typeof root.props !== 'object') {\n errors.push('Missing root.props object')\n } else {\n const rootProps = root.props as Record<string, unknown>\n\n // Check required root props\n for (const prop of requiredRootProps) {\n if (rootProps[prop] === undefined || rootProps[prop] === null) {\n errors.push(`Missing required root prop: ${prop}`)\n }\n }\n\n // Validate pageLayout if present\n if (rootProps.pageLayout !== undefined) {\n if (typeof rootProps.pageLayout !== 'string') {\n errors.push('root.props.pageLayout must be a string')\n }\n }\n }\n }\n\n // ==========================================================================\n // Validate content array\n // ==========================================================================\n\n if (!Array.isArray(obj.content)) {\n errors.push('content must be an array')\n } else {\n const seenIds = new Set<string>()\n\n obj.content.forEach((item, index) => {\n if (!item || typeof item !== 'object') {\n errors.push(`Content item at index ${index} is not an object`)\n return\n }\n\n const contentItem = item as Record<string, unknown>\n\n // Validate type\n if (!contentItem.type || typeof contentItem.type !== 'string') {\n errors.push(`Content item at index ${index} missing or invalid type`)\n } else if (allowedComponentTypes) {\n if (!allowedComponentTypes.includes(contentItem.type)) {\n const message = `Unknown component type \"${contentItem.type}\" at index ${index}`\n if (strictComponentTypes) {\n errors.push(message)\n } else {\n warnings.push(message)\n }\n }\n }\n\n // Validate props\n if (!contentItem.props || typeof contentItem.props !== 'object') {\n errors.push(`Content item at index ${index} missing props object`)\n } else if (requireContentIds) {\n const props = contentItem.props as Record<string, unknown>\n\n if (!props.id || typeof props.id !== 'string') {\n errors.push(`Content item at index ${index} missing or invalid props.id`)\n } else {\n // Check for duplicate IDs\n if (seenIds.has(props.id)) {\n warnings.push(\n `Duplicate content item ID \"${props.id}\" at index ${index}`\n )\n }\n seenIds.add(props.id)\n }\n }\n })\n }\n\n // ==========================================================================\n // Validate zones\n // ==========================================================================\n\n if (obj.zones !== undefined) {\n if (typeof obj.zones !== 'object' || obj.zones === null) {\n errors.push('zones must be an object')\n } else {\n const zones = obj.zones as Record<string, unknown>\n\n for (const [zoneName, zoneContent] of Object.entries(zones)) {\n if (!Array.isArray(zoneContent)) {\n errors.push(`Zone \"${zoneName}\" content must be an array`)\n continue\n }\n\n zoneContent.forEach((item, index) => {\n if (!item || typeof item !== 'object') {\n errors.push(`Zone \"${zoneName}\" item at index ${index} is not an object`)\n return\n }\n\n const contentItem = item as Record<string, unknown>\n\n if (!contentItem.type || typeof contentItem.type !== 'string') {\n errors.push(\n `Zone \"${zoneName}\" item at index ${index} missing or invalid type`\n )\n }\n\n if (!contentItem.props || typeof contentItem.props !== 'object') {\n errors.push(\n `Zone \"${zoneName}\" item at index ${index} missing props object`\n )\n } else if (requireContentIds) {\n const props = contentItem.props as Record<string, unknown>\n if (!props.id || typeof props.id !== 'string') {\n errors.push(\n `Zone \"${zoneName}\" item at index ${index} missing or invalid props.id`\n )\n }\n }\n })\n }\n }\n }\n\n return {\n valid: errors.length === 0,\n errors,\n warnings,\n }\n}\n\n/**\n * Validates and returns typed PuckPageData, throwing if invalid.\n *\n * @param data - The data to validate\n * @param options - Validation options\n * @returns The validated PuckPageData\n * @throws Error if validation fails\n */\nexport function assertPuckData(\n data: unknown,\n options?: ValidationOptions\n): PuckPageData {\n const result = validatePuckData(data, options)\n\n if (!result.valid) {\n throw new Error(\n `Invalid Puck data: ${result.errors.join('; ')}`\n )\n }\n\n return data as PuckPageData\n}\n\n/**\n * Safely parses JSON and validates as PuckPageData.\n *\n * @param json - JSON string to parse\n * @param options - Validation options\n * @returns Validation result with parsed data if valid\n */\nexport function parsePuckDataJson(\n json: string,\n options?: ValidationOptions\n): ValidationResult & { data?: PuckPageData } {\n let parsed: unknown\n\n try {\n parsed = JSON.parse(json)\n } catch (e) {\n return {\n valid: false,\n errors: [`Invalid JSON: ${e instanceof Error ? e.message : 'Parse error'}`],\n warnings: [],\n }\n }\n\n const result = validatePuckData(parsed, options)\n\n if (result.valid) {\n return {\n ...result,\n data: parsed as PuckPageData,\n }\n }\n\n return result\n}\n"]}