@01.software/sdk 0.2.9-dev.260311.926a6d4 → 0.2.9-dev.260312.8c43a16

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 (64) hide show
  1. package/README.md +95 -62
  2. package/dist/auth.cjs +3 -1
  3. package/dist/auth.cjs.map +1 -1
  4. package/dist/auth.d.cts +1 -1
  5. package/dist/auth.d.ts +1 -1
  6. package/dist/auth.js +3 -1
  7. package/dist/auth.js.map +1 -1
  8. package/dist/index.cjs +172 -91
  9. package/dist/index.cjs.map +1 -1
  10. package/dist/index.d.cts +17 -35
  11. package/dist/index.d.ts +17 -35
  12. package/dist/index.js +177 -92
  13. package/dist/index.js.map +1 -1
  14. package/dist/{payload-types-BjvBwB8Z.d.cts → payload-types-BUwpb306.d.cts} +295 -1384
  15. package/dist/{payload-types-BjvBwB8Z.d.ts → payload-types-BUwpb306.d.ts} +295 -1384
  16. package/dist/{components → ui}/code-block.cjs +11 -8
  17. package/dist/ui/code-block.cjs.map +1 -0
  18. package/dist/{components → ui}/code-block.js +11 -8
  19. package/dist/ui/code-block.js.map +1 -0
  20. package/dist/{components → ui}/flow.cjs +117 -69
  21. package/dist/ui/flow.cjs.map +1 -0
  22. package/dist/{components → ui}/flow.js +114 -66
  23. package/dist/ui/flow.js.map +1 -0
  24. package/dist/{components → ui}/form.cjs +6 -6
  25. package/dist/ui/form.cjs.map +1 -0
  26. package/dist/{components → ui}/form.d.cts +1 -1
  27. package/dist/{components → ui}/form.d.ts +1 -1
  28. package/dist/{components → ui}/form.js +3 -3
  29. package/dist/ui/form.js.map +1 -0
  30. package/dist/{components → ui}/image.cjs +2 -2
  31. package/dist/ui/image.cjs.map +1 -0
  32. package/dist/{components → ui}/image.js +2 -2
  33. package/dist/ui/image.js.map +1 -0
  34. package/dist/{components → ui}/rich-text.cjs +6 -6
  35. package/dist/ui/rich-text.cjs.map +1 -0
  36. package/dist/{components → ui}/rich-text.js +3 -3
  37. package/dist/ui/rich-text.js.map +1 -0
  38. package/dist/{webhook-_LdLdjGa.d.ts → webhook-BUcDo2Ny.d.cts} +2 -2
  39. package/dist/{webhook-CszIpUKn.d.cts → webhook-D8Bp97bF.d.ts} +2 -2
  40. package/dist/webhook.cjs +7 -5
  41. package/dist/webhook.cjs.map +1 -1
  42. package/dist/webhook.d.cts +2 -2
  43. package/dist/webhook.d.ts +2 -2
  44. package/dist/webhook.js +7 -5
  45. package/dist/webhook.js.map +1 -1
  46. package/package.json +29 -28
  47. package/dist/components/code-block.cjs.map +0 -1
  48. package/dist/components/code-block.js.map +0 -1
  49. package/dist/components/flow.cjs.map +0 -1
  50. package/dist/components/flow.js.map +0 -1
  51. package/dist/components/form.cjs.map +0 -1
  52. package/dist/components/form.js.map +0 -1
  53. package/dist/components/image.cjs.map +0 -1
  54. package/dist/components/image.js.map +0 -1
  55. package/dist/components/rich-text.cjs.map +0 -1
  56. package/dist/components/rich-text.js.map +0 -1
  57. /package/dist/{components → ui}/code-block.d.cts +0 -0
  58. /package/dist/{components → ui}/code-block.d.ts +0 -0
  59. /package/dist/{components → ui}/flow.d.cts +0 -0
  60. /package/dist/{components → ui}/flow.d.ts +0 -0
  61. /package/dist/{components → ui}/image.d.cts +0 -0
  62. /package/dist/{components → ui}/image.d.ts +0 -0
  63. /package/dist/{components → ui}/rich-text.d.cts +0 -0
  64. /package/dist/{components → ui}/rich-text.d.ts +0 -0
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/ui/Image/index.tsx","../../src/utils/image.ts"],"sourcesContent":["'use client'\n\nimport React, { useCallback, useRef, useState } from 'react'\nimport type { CSSProperties } from 'react'\nimport type { ImageData } from '../../utils/image'\nimport { getImageSrcSet, getImagePlaceholderStyle } from '../../utils/image'\n\nexport interface ImageProps {\n /** Payload image document */\n image: ImageData\n /** Display width in CSS pixels (for selecting optimal srcset size) */\n width?: number\n /** Device pixel ratio (default: 1) */\n dpr?: number\n /** Placeholder strategy (default: 'blur'; defaults to 'none' when imageRendering is 'pixelated' or 'crisp-edges') */\n placeholder?: 'blur' | 'color' | 'none'\n /** Container className */\n className?: string\n /** Container style */\n style?: CSSProperties\n /** Inner `<img>` className */\n imgClassName?: string\n /** Inner `<img>` style */\n imgStyle?: CSSProperties\n /** HTML sizes attribute */\n sizes?: string\n /** Loading strategy (default: 'lazy'; automatically 'eager' when priority is true) */\n loading?: 'lazy' | 'eager'\n /** Callback when image finishes loading */\n onLoad?: () => void\n /** Object-fit for the image (default: 'cover') */\n objectFit?: 'cover' | 'contain' | 'fill' | 'none' | 'scale-down'\n /** When true, loads eagerly with high fetch priority (for LCP images) */\n priority?: boolean\n /** When true, fills parent container (width/height: 100%, no aspect ratio) */\n fill?: boolean\n /** CSS image-rendering mode (e.g. 'pixelated' for pixel art) */\n imageRendering?: 'auto' | 'pixelated' | 'crisp-edges'\n}\n\n/**\n * Image component with blur-up / color placeholder support.\n *\n * Uses LQIP (Low Quality Image Placeholder) for a smooth blur-up effect,\n * falling back to palette color or no placeholder.\n */\nexport function Image({\n image,\n width,\n dpr = 1,\n placeholder: placeholderProp,\n className,\n style,\n imgClassName,\n imgStyle,\n sizes,\n loading: loadingProp,\n onLoad,\n objectFit = 'cover',\n priority = false,\n fill = false,\n imageRendering,\n}: ImageProps) {\n const [loaded, setLoaded] = useState(false)\n const firedRef = useRef(false)\n\n // Resolve defaults based on other props\n const isPixelRendering =\n imageRendering === 'pixelated' || imageRendering === 'crisp-edges'\n const placeholder = placeholderProp ?? (isPixelRendering ? 'none' : 'blur')\n const loading = priority ? 'eager' : (loadingProp ?? 'lazy')\n\n const aspectRatio =\n !fill && image.width && image.height\n ? `${image.width} / ${image.height}`\n : undefined\n\n const srcSet = getImageSrcSet(image)\n const src = image.url ?? undefined\n\n // Placeholder: LQIP overlay or color overlay (mutually exclusive)\n const hasLqip = placeholder === 'blur' && !!image.lqip\n const placeholderStyle = getImagePlaceholderStyle(image, {\n type: placeholder,\n })\n const placeholderColor =\n !hasLqip && 'backgroundColor' in placeholderStyle\n ? placeholderStyle.backgroundColor\n : undefined\n\n const fireLoad = useCallback(() => {\n if (firedRef.current) return\n firedRef.current = true\n setLoaded(true)\n onLoad?.()\n }, [onLoad])\n\n // Callback ref: detect SSR-cached images that are already loaded\n const imgRef = useCallback(\n (node: HTMLImageElement | null) => {\n if (node && node.complete && node.naturalWidth > 0) {\n fireLoad()\n }\n },\n [fireLoad],\n )\n\n // Container styles\n const containerStyle: CSSProperties = {\n position: 'relative',\n overflow: 'hidden',\n ...(fill ? { width: '100%', height: '100%' } : {}),\n ...(aspectRatio ? { aspectRatio } : {}),\n ...style,\n }\n\n // Shared overlay styles (LQIP and color)\n const overlayBase: CSSProperties = {\n position: 'absolute',\n top: 0,\n left: 0,\n width: '100%',\n height: '100%',\n opacity: loaded ? 0 : 1,\n transition: 'opacity 0.3s ease',\n pointerEvents: 'none',\n }\n\n // Main image styles\n const mainImgStyle: CSSProperties = {\n display: 'block',\n width: '100%',\n height: '100%',\n objectFit,\n ...(imageRendering ? { imageRendering } : {}),\n opacity: loaded ? 1 : 0,\n transition: 'opacity 0.3s ease',\n ...imgStyle,\n }\n\n return (\n <div className={className} style={containerStyle}>\n {hasLqip && (\n <img\n aria-hidden\n alt=\"\"\n src={image.lqip!}\n style={{\n ...overlayBase,\n display: 'block',\n objectFit,\n filter: 'blur(20px)',\n transform: 'scale(1.1)',\n }}\n />\n )}\n {placeholderColor && (\n <div\n aria-hidden\n style={{\n ...overlayBase,\n backgroundColor: placeholderColor,\n }}\n />\n )}\n <img\n ref={imgRef}\n alt={image.alt ?? ''}\n src={src}\n srcSet={srcSet || undefined}\n sizes={sizes}\n width={width ? width * dpr : undefined}\n loading={loading}\n decoding=\"async\"\n fetchPriority={priority ? 'high' : undefined}\n onLoad={fireLoad}\n className={imgClassName}\n style={mainImgStyle}\n />\n </div>\n )\n}\n","/** Palette colors extracted from an image */\nexport interface ImagePalette {\n vibrant?: string | null\n muted?: string | null\n darkVibrant?: string | null\n darkMuted?: string | null\n lightVibrant?: string | null\n lightMuted?: string | null\n}\n\n/** Common image data shape from Payload CMS upload collections */\nexport interface ImageData {\n url?: string | null\n width?: number | null\n height?: number | null\n alt?: string | null\n lqip?: string | null\n palette?: ImagePalette | null\n sizes?: Record<\n string,\n | {\n url?: string | null\n width?: number | null\n height?: number | null\n }\n | undefined\n >\n}\n\n/** Pre-generated image size breakpoints (px) */\nexport const IMAGE_SIZES = [384, 768, 1536] as const\n\n/**\n * Returns the optimal image URL for a given display width.\n *\n * Picks the smallest pre-generated size whose width >= displayWidth × dpr.\n * Falls back to the original URL when no matching size exists.\n *\n * @param image - Payload image document\n * @param displayWidth - CSS pixel width the image will be displayed at\n * @param dpr - Device pixel ratio (default: 1)\n * @returns URL string, or empty string if no URL is available\n */\nexport function getImageUrl(\n image: ImageData,\n displayWidth: number,\n dpr: number = 1,\n): string {\n const target = displayWidth * dpr\n const sizes = image.sizes\n\n if (sizes) {\n for (const size of IMAGE_SIZES) {\n if (size >= target) {\n const entry = sizes[String(size)]\n if (entry?.url) return entry.url\n }\n }\n }\n\n return image.url ?? ''\n}\n\n/**\n * Generates an HTML `srcset` attribute string from pre-generated sizes.\n *\n * Includes all available sizes plus the original image.\n * Example output: `\"url-384 384w, url-768 768w, url-1536 1536w, url-original 2000w\"`\n *\n * @param image - Payload image document\n * @returns srcset string, or empty string if no URLs are available\n */\nexport function getImageSrcSet(image: ImageData): string {\n const parts: string[] = []\n const sizes = image.sizes\n\n if (sizes) {\n for (const size of IMAGE_SIZES) {\n const entry = sizes[String(size)]\n if (entry?.url && entry.width) {\n parts.push(`${entry.url} ${entry.width}w`)\n }\n }\n }\n\n if (image.url && image.width) {\n parts.push(`${image.url} ${image.width}w`)\n }\n\n return parts.join(', ')\n}\n\n/**\n * Returns the LQIP (Low Quality Image Placeholder) data URL for an image.\n *\n * @param image - Payload image document\n * @returns LQIP data URL string, or undefined if not available\n */\nexport function getImageLqip(image: ImageData): string | undefined {\n return image.lqip ?? undefined\n}\n\n/**\n * Returns the extracted color palette for an image.\n *\n * @param image - Payload image document\n * @returns ImagePalette object, or undefined if not available\n */\nexport function getImagePalette(image: ImageData): ImagePalette | undefined {\n return image.palette ?? undefined\n}\n\n/** Options for `getImagePlaceholderStyle` */\nexport interface ImagePlaceholderOptions {\n /** Placeholder strategy (default: 'blur') */\n type?: 'blur' | 'color' | 'none'\n /** Which palette color to use for 'color' strategy (default: 'muted') */\n paletteColor?: keyof ImagePalette\n}\n\n/**\n * Returns inline CSS styles for an image placeholder.\n *\n * - `blur`: uses LQIP as background, falls back to palette color, then empty\n * - `color`: uses palette color as background, falls back to empty\n * - `none`: always returns empty\n *\n * @param image - Payload image document\n * @param options - Placeholder options\n * @returns CSS style object compatible with React CSSProperties\n */\nexport function getImagePlaceholderStyle(\n image: ImageData,\n options?: ImagePlaceholderOptions,\n): Record<string, string> {\n const type = options?.type ?? 'blur'\n const paletteColor = options?.paletteColor ?? 'muted'\n\n if (type === 'none') return {}\n\n const color = image.palette?.[paletteColor]\n\n if (type === 'blur') {\n const lqip = image.lqip\n if (lqip) {\n return {\n backgroundImage: `url(${lqip})`,\n backgroundSize: 'cover',\n backgroundPosition: 'center',\n }\n }\n // Cascade: fall back to color\n if (color) {\n return { backgroundColor: color }\n }\n return {}\n }\n\n // type === 'color'\n if (color) {\n return { backgroundColor: color }\n }\n return {}\n}\n"],"mappings":"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","names":["React"]}
@@ -19,7 +19,7 @@ var __spreadValues = (a, b) => {
19
19
  };
20
20
  var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
21
21
 
22
- // src/components/Image/index.tsx
22
+ // src/ui/Image/index.tsx
23
23
  import React, { useCallback, useRef, useState } from "react";
24
24
 
25
25
  // src/utils/image.ts
@@ -66,7 +66,7 @@ function getImagePlaceholderStyle(image, options) {
66
66
  return {};
67
67
  }
68
68
 
69
- // src/components/Image/index.tsx
69
+ // src/ui/Image/index.tsx
70
70
  function Image({
71
71
  image,
72
72
  width,
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/ui/Image/index.tsx","../../src/utils/image.ts"],"sourcesContent":["'use client'\n\nimport React, { useCallback, useRef, useState } from 'react'\nimport type { CSSProperties } from 'react'\nimport type { ImageData } from '../../utils/image'\nimport { getImageSrcSet, getImagePlaceholderStyle } from '../../utils/image'\n\nexport interface ImageProps {\n /** Payload image document */\n image: ImageData\n /** Display width in CSS pixels (for selecting optimal srcset size) */\n width?: number\n /** Device pixel ratio (default: 1) */\n dpr?: number\n /** Placeholder strategy (default: 'blur'; defaults to 'none' when imageRendering is 'pixelated' or 'crisp-edges') */\n placeholder?: 'blur' | 'color' | 'none'\n /** Container className */\n className?: string\n /** Container style */\n style?: CSSProperties\n /** Inner `<img>` className */\n imgClassName?: string\n /** Inner `<img>` style */\n imgStyle?: CSSProperties\n /** HTML sizes attribute */\n sizes?: string\n /** Loading strategy (default: 'lazy'; automatically 'eager' when priority is true) */\n loading?: 'lazy' | 'eager'\n /** Callback when image finishes loading */\n onLoad?: () => void\n /** Object-fit for the image (default: 'cover') */\n objectFit?: 'cover' | 'contain' | 'fill' | 'none' | 'scale-down'\n /** When true, loads eagerly with high fetch priority (for LCP images) */\n priority?: boolean\n /** When true, fills parent container (width/height: 100%, no aspect ratio) */\n fill?: boolean\n /** CSS image-rendering mode (e.g. 'pixelated' for pixel art) */\n imageRendering?: 'auto' | 'pixelated' | 'crisp-edges'\n}\n\n/**\n * Image component with blur-up / color placeholder support.\n *\n * Uses LQIP (Low Quality Image Placeholder) for a smooth blur-up effect,\n * falling back to palette color or no placeholder.\n */\nexport function Image({\n image,\n width,\n dpr = 1,\n placeholder: placeholderProp,\n className,\n style,\n imgClassName,\n imgStyle,\n sizes,\n loading: loadingProp,\n onLoad,\n objectFit = 'cover',\n priority = false,\n fill = false,\n imageRendering,\n}: ImageProps) {\n const [loaded, setLoaded] = useState(false)\n const firedRef = useRef(false)\n\n // Resolve defaults based on other props\n const isPixelRendering =\n imageRendering === 'pixelated' || imageRendering === 'crisp-edges'\n const placeholder = placeholderProp ?? (isPixelRendering ? 'none' : 'blur')\n const loading = priority ? 'eager' : (loadingProp ?? 'lazy')\n\n const aspectRatio =\n !fill && image.width && image.height\n ? `${image.width} / ${image.height}`\n : undefined\n\n const srcSet = getImageSrcSet(image)\n const src = image.url ?? undefined\n\n // Placeholder: LQIP overlay or color overlay (mutually exclusive)\n const hasLqip = placeholder === 'blur' && !!image.lqip\n const placeholderStyle = getImagePlaceholderStyle(image, {\n type: placeholder,\n })\n const placeholderColor =\n !hasLqip && 'backgroundColor' in placeholderStyle\n ? placeholderStyle.backgroundColor\n : undefined\n\n const fireLoad = useCallback(() => {\n if (firedRef.current) return\n firedRef.current = true\n setLoaded(true)\n onLoad?.()\n }, [onLoad])\n\n // Callback ref: detect SSR-cached images that are already loaded\n const imgRef = useCallback(\n (node: HTMLImageElement | null) => {\n if (node && node.complete && node.naturalWidth > 0) {\n fireLoad()\n }\n },\n [fireLoad],\n )\n\n // Container styles\n const containerStyle: CSSProperties = {\n position: 'relative',\n overflow: 'hidden',\n ...(fill ? { width: '100%', height: '100%' } : {}),\n ...(aspectRatio ? { aspectRatio } : {}),\n ...style,\n }\n\n // Shared overlay styles (LQIP and color)\n const overlayBase: CSSProperties = {\n position: 'absolute',\n top: 0,\n left: 0,\n width: '100%',\n height: '100%',\n opacity: loaded ? 0 : 1,\n transition: 'opacity 0.3s ease',\n pointerEvents: 'none',\n }\n\n // Main image styles\n const mainImgStyle: CSSProperties = {\n display: 'block',\n width: '100%',\n height: '100%',\n objectFit,\n ...(imageRendering ? { imageRendering } : {}),\n opacity: loaded ? 1 : 0,\n transition: 'opacity 0.3s ease',\n ...imgStyle,\n }\n\n return (\n <div className={className} style={containerStyle}>\n {hasLqip && (\n <img\n aria-hidden\n alt=\"\"\n src={image.lqip!}\n style={{\n ...overlayBase,\n display: 'block',\n objectFit,\n filter: 'blur(20px)',\n transform: 'scale(1.1)',\n }}\n />\n )}\n {placeholderColor && (\n <div\n aria-hidden\n style={{\n ...overlayBase,\n backgroundColor: placeholderColor,\n }}\n />\n )}\n <img\n ref={imgRef}\n alt={image.alt ?? ''}\n src={src}\n srcSet={srcSet || undefined}\n sizes={sizes}\n width={width ? width * dpr : undefined}\n loading={loading}\n decoding=\"async\"\n fetchPriority={priority ? 'high' : undefined}\n onLoad={fireLoad}\n className={imgClassName}\n style={mainImgStyle}\n />\n </div>\n )\n}\n","/** Palette colors extracted from an image */\nexport interface ImagePalette {\n vibrant?: string | null\n muted?: string | null\n darkVibrant?: string | null\n darkMuted?: string | null\n lightVibrant?: string | null\n lightMuted?: string | null\n}\n\n/** Common image data shape from Payload CMS upload collections */\nexport interface ImageData {\n url?: string | null\n width?: number | null\n height?: number | null\n alt?: string | null\n lqip?: string | null\n palette?: ImagePalette | null\n sizes?: Record<\n string,\n | {\n url?: string | null\n width?: number | null\n height?: number | null\n }\n | undefined\n >\n}\n\n/** Pre-generated image size breakpoints (px) */\nexport const IMAGE_SIZES = [384, 768, 1536] as const\n\n/**\n * Returns the optimal image URL for a given display width.\n *\n * Picks the smallest pre-generated size whose width >= displayWidth × dpr.\n * Falls back to the original URL when no matching size exists.\n *\n * @param image - Payload image document\n * @param displayWidth - CSS pixel width the image will be displayed at\n * @param dpr - Device pixel ratio (default: 1)\n * @returns URL string, or empty string if no URL is available\n */\nexport function getImageUrl(\n image: ImageData,\n displayWidth: number,\n dpr: number = 1,\n): string {\n const target = displayWidth * dpr\n const sizes = image.sizes\n\n if (sizes) {\n for (const size of IMAGE_SIZES) {\n if (size >= target) {\n const entry = sizes[String(size)]\n if (entry?.url) return entry.url\n }\n }\n }\n\n return image.url ?? ''\n}\n\n/**\n * Generates an HTML `srcset` attribute string from pre-generated sizes.\n *\n * Includes all available sizes plus the original image.\n * Example output: `\"url-384 384w, url-768 768w, url-1536 1536w, url-original 2000w\"`\n *\n * @param image - Payload image document\n * @returns srcset string, or empty string if no URLs are available\n */\nexport function getImageSrcSet(image: ImageData): string {\n const parts: string[] = []\n const sizes = image.sizes\n\n if (sizes) {\n for (const size of IMAGE_SIZES) {\n const entry = sizes[String(size)]\n if (entry?.url && entry.width) {\n parts.push(`${entry.url} ${entry.width}w`)\n }\n }\n }\n\n if (image.url && image.width) {\n parts.push(`${image.url} ${image.width}w`)\n }\n\n return parts.join(', ')\n}\n\n/**\n * Returns the LQIP (Low Quality Image Placeholder) data URL for an image.\n *\n * @param image - Payload image document\n * @returns LQIP data URL string, or undefined if not available\n */\nexport function getImageLqip(image: ImageData): string | undefined {\n return image.lqip ?? undefined\n}\n\n/**\n * Returns the extracted color palette for an image.\n *\n * @param image - Payload image document\n * @returns ImagePalette object, or undefined if not available\n */\nexport function getImagePalette(image: ImageData): ImagePalette | undefined {\n return image.palette ?? undefined\n}\n\n/** Options for `getImagePlaceholderStyle` */\nexport interface ImagePlaceholderOptions {\n /** Placeholder strategy (default: 'blur') */\n type?: 'blur' | 'color' | 'none'\n /** Which palette color to use for 'color' strategy (default: 'muted') */\n paletteColor?: keyof ImagePalette\n}\n\n/**\n * Returns inline CSS styles for an image placeholder.\n *\n * - `blur`: uses LQIP as background, falls back to palette color, then empty\n * - `color`: uses palette color as background, falls back to empty\n * - `none`: always returns empty\n *\n * @param image - Payload image document\n * @param options - Placeholder options\n * @returns CSS style object compatible with React CSSProperties\n */\nexport function getImagePlaceholderStyle(\n image: ImageData,\n options?: ImagePlaceholderOptions,\n): Record<string, string> {\n const type = options?.type ?? 'blur'\n const paletteColor = options?.paletteColor ?? 'muted'\n\n if (type === 'none') return {}\n\n const color = image.palette?.[paletteColor]\n\n if (type === 'blur') {\n const lqip = image.lqip\n if (lqip) {\n return {\n backgroundImage: `url(${lqip})`,\n backgroundSize: 'cover',\n backgroundPosition: 'center',\n }\n }\n // Cascade: fall back to color\n if (color) {\n return { backgroundColor: color }\n }\n return {}\n }\n\n // type === 'color'\n if (color) {\n return { backgroundColor: color }\n }\n return {}\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;AAEA,OAAO,SAAS,aAAa,QAAQ,gBAAgB;;;AC4B9C,IAAM,cAAc,CAAC,KAAK,KAAK,IAAI;AA0CnC,SAAS,eAAe,OAA0B;AACvD,QAAM,QAAkB,CAAC;AACzB,QAAM,QAAQ,MAAM;AAEpB,MAAI,OAAO;AACT,eAAW,QAAQ,aAAa;AAC9B,YAAM,QAAQ,MAAM,OAAO,IAAI,CAAC;AAChC,WAAI,+BAAO,QAAO,MAAM,OAAO;AAC7B,cAAM,KAAK,GAAG,MAAM,GAAG,IAAI,MAAM,KAAK,GAAG;AAAA,MAC3C;AAAA,IACF;AAAA,EACF;AAEA,MAAI,MAAM,OAAO,MAAM,OAAO;AAC5B,UAAM,KAAK,GAAG,MAAM,GAAG,IAAI,MAAM,KAAK,GAAG;AAAA,EAC3C;AAEA,SAAO,MAAM,KAAK,IAAI;AACxB;AAyCO,SAAS,yBACd,OACA,SACwB;AAtI1B;AAuIE,QAAM,QAAO,wCAAS,SAAT,YAAiB;AAC9B,QAAM,gBAAe,wCAAS,iBAAT,YAAyB;AAE9C,MAAI,SAAS,OAAQ,QAAO,CAAC;AAE7B,QAAM,SAAQ,WAAM,YAAN,mBAAgB;AAE9B,MAAI,SAAS,QAAQ;AACnB,UAAM,OAAO,MAAM;AACnB,QAAI,MAAM;AACR,aAAO;AAAA,QACL,iBAAiB,OAAO,IAAI;AAAA,QAC5B,gBAAgB;AAAA,QAChB,oBAAoB;AAAA,MACtB;AAAA,IACF;AAEA,QAAI,OAAO;AACT,aAAO,EAAE,iBAAiB,MAAM;AAAA,IAClC;AACA,WAAO,CAAC;AAAA,EACV;AAGA,MAAI,OAAO;AACT,WAAO,EAAE,iBAAiB,MAAM;AAAA,EAClC;AACA,SAAO,CAAC;AACV;;;ADrHO,SAAS,MAAM;AAAA,EACpB;AAAA,EACA;AAAA,EACA,MAAM;AAAA,EACN,aAAa;AAAA,EACb;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,SAAS;AAAA,EACT;AAAA,EACA,YAAY;AAAA,EACZ,WAAW;AAAA,EACX,OAAO;AAAA,EACP;AACF,GAAe;AA9Df;AA+DE,QAAM,CAAC,QAAQ,SAAS,IAAI,SAAS,KAAK;AAC1C,QAAM,WAAW,OAAO,KAAK;AAG7B,QAAM,mBACJ,mBAAmB,eAAe,mBAAmB;AACvD,QAAM,cAAc,4CAAoB,mBAAmB,SAAS;AACpE,QAAM,UAAU,WAAW,UAAW,oCAAe;AAErD,QAAM,cACJ,CAAC,QAAQ,MAAM,SAAS,MAAM,SAC1B,GAAG,MAAM,KAAK,MAAM,MAAM,MAAM,KAChC;AAEN,QAAM,SAAS,eAAe,KAAK;AACnC,QAAM,OAAM,WAAM,QAAN,YAAa;AAGzB,QAAM,UAAU,gBAAgB,UAAU,CAAC,CAAC,MAAM;AAClD,QAAM,mBAAmB,yBAAyB,OAAO;AAAA,IACvD,MAAM;AAAA,EACR,CAAC;AACD,QAAM,mBACJ,CAAC,WAAW,qBAAqB,mBAC7B,iBAAiB,kBACjB;AAEN,QAAM,WAAW,YAAY,MAAM;AACjC,QAAI,SAAS,QAAS;AACtB,aAAS,UAAU;AACnB,cAAU,IAAI;AACd;AAAA,EACF,GAAG,CAAC,MAAM,CAAC;AAGX,QAAM,SAAS;AAAA,IACb,CAAC,SAAkC;AACjC,UAAI,QAAQ,KAAK,YAAY,KAAK,eAAe,GAAG;AAClD,iBAAS;AAAA,MACX;AAAA,IACF;AAAA,IACA,CAAC,QAAQ;AAAA,EACX;AAGA,QAAM,iBAAgC;AAAA,IACpC,UAAU;AAAA,IACV,UAAU;AAAA,KACN,OAAO,EAAE,OAAO,QAAQ,QAAQ,OAAO,IAAI,CAAC,IAC5C,cAAc,EAAE,YAAY,IAAI,CAAC,IAClC;AAIL,QAAM,cAA6B;AAAA,IACjC,UAAU;AAAA,IACV,KAAK;AAAA,IACL,MAAM;AAAA,IACN,OAAO;AAAA,IACP,QAAQ;AAAA,IACR,SAAS,SAAS,IAAI;AAAA,IACtB,YAAY;AAAA,IACZ,eAAe;AAAA,EACjB;AAGA,QAAM,eAA8B;AAAA,IAClC,SAAS;AAAA,IACT,OAAO;AAAA,IACP,QAAQ;AAAA,IACR;AAAA,KACI,iBAAiB,EAAE,eAAe,IAAI,CAAC,IALT;AAAA,IAMlC,SAAS,SAAS,IAAI;AAAA,IACtB,YAAY;AAAA,MACT;AAGL,SACE,oCAAC,SAAI,WAAsB,OAAO,kBAC/B,WACC;AAAA,IAAC;AAAA;AAAA,MACC,eAAW;AAAA,MACX,KAAI;AAAA,MACJ,KAAK,MAAM;AAAA,MACX,OAAO,iCACF,cADE;AAAA,QAEL,SAAS;AAAA,QACT;AAAA,QACA,QAAQ;AAAA,QACR,WAAW;AAAA,MACb;AAAA;AAAA,EACF,GAED,oBACC;AAAA,IAAC;AAAA;AAAA,MACC,eAAW;AAAA,MACX,OAAO,iCACF,cADE;AAAA,QAEL,iBAAiB;AAAA,MACnB;AAAA;AAAA,EACF,GAEF;AAAA,IAAC;AAAA;AAAA,MACC,KAAK;AAAA,MACL,MAAK,WAAM,QAAN,YAAa;AAAA,MAClB;AAAA,MACA,QAAQ,UAAU;AAAA,MAClB;AAAA,MACA,OAAO,QAAQ,QAAQ,MAAM;AAAA,MAC7B;AAAA,MACA,UAAS;AAAA,MACT,eAAe,WAAW,SAAS;AAAA,MACnC,QAAQ;AAAA,MACR,WAAW;AAAA,MACX,OAAO;AAAA;AAAA,EACT,CACF;AAEJ;","names":[]}
@@ -57,17 +57,17 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
57
57
  ));
58
58
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
59
59
 
60
- // src/components/RichTextContent/index.tsx
61
- var RichTextContent_exports = {};
62
- __export(RichTextContent_exports, {
60
+ // src/ui/RichText/index.tsx
61
+ var RichText_exports = {};
62
+ __export(RichText_exports, {
63
63
  RichTextContent: () => RichTextContent,
64
64
  StyledRichTextContent: () => StyledRichTextContent
65
65
  });
66
- module.exports = __toCommonJS(RichTextContent_exports);
66
+ module.exports = __toCommonJS(RichText_exports);
67
67
  var import_react2 = __toESM(require("react"), 1);
68
68
  var import_react3 = require("@payloadcms/richtext-lexical/react");
69
69
 
70
- // src/components/RichTextContent/styled.tsx
70
+ // src/ui/RichText/styled.tsx
71
71
  var import_react = __toESM(require("react"), 1);
72
72
  function createComponentConverters(components, internalDocToHref) {
73
73
  const converters = {};
@@ -215,7 +215,7 @@ function StyledRichTextContent(_a) {
215
215
  );
216
216
  }
217
217
 
218
- // src/components/RichTextContent/index.tsx
218
+ // src/ui/RichText/index.tsx
219
219
  function hyphenToCamel(str) {
220
220
  return str.replace(/-([a-z])/g, (_, c) => c.toUpperCase());
221
221
  }
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/ui/RichText/index.tsx","../../src/ui/RichText/styled.tsx"],"sourcesContent":["'use client'\n\nimport React from 'react'\nimport {\n SerializedBlockNode,\n SerializedLinkNode,\n} from '@payloadcms/richtext-lexical'\nimport {\n SerializedEditorState,\n SerializedLexicalNode,\n} from '@payloadcms/richtext-lexical/lexical'\nimport {\n defaultJSXConverters,\n JSXConverter,\n JSXConverters,\n LinkJSXConverter,\n RichText,\n TextJSXConverter,\n} from '@payloadcms/richtext-lexical/react'\n\nexport type RichTextData = SerializedEditorState<SerializedLexicalNode>\n\nexport type TextStateConfig = {\n [stateKey: string]: {\n [stateValue: string]: {\n css: Record<string, string>\n label: string\n }\n }\n}\n\nexport interface RichTextContentProps {\n data: RichTextData\n className?: string\n internalDocToHref?: (args: { linkNode: SerializedLinkNode }) => string\n converters?: Partial<JSXConverters>\n blocks?: Record<string, JSXConverter<SerializedBlockNode>>\n disableDefaultConverters?: boolean\n textState?: TextStateConfig\n}\n\nexport { StyledRichTextContent } from './styled'\nexport type {\n RichTextComponents,\n StyledRichTextContentProps,\n HeadingSlotProps,\n ParagraphSlotProps,\n BlockquoteSlotProps,\n ListSlotProps,\n ListItemSlotProps,\n LinkSlotProps,\n HorizontalRuleSlotProps,\n UploadSlotProps,\n TableSlotProps,\n TableRowSlotProps,\n TableCellSlotProps,\n} from './styled'\n\nfunction hyphenToCamel(str: string): string {\n return str.replace(/-([a-z])/g, (_, c) => c.toUpperCase())\n}\n\nfunction createTextStateConverter(\n state: TextStateConfig,\n): JSXConverters['text'] {\n const defaultTextConverter = TextJSXConverter.text\n // eslint-disable-next-line react/display-name\n return ({ node, ...rest }) => {\n const base = (\n defaultTextConverter as (...args: unknown[]) => React.ReactNode\n )({ node, ...rest })\n const nodeState = (node as Record<string, unknown>).$ as\n | Record<string, string>\n | undefined\n if (!nodeState || typeof nodeState !== 'object') return base\n\n const style: Record<string, string> = {}\n for (const stateKey in nodeState) {\n const stateValue = nodeState[stateKey]\n if (!stateValue) continue\n const css = state[stateKey]?.[stateValue]?.css\n if (css) {\n for (const prop in css) {\n const val = css[prop]\n if (val) style[hyphenToCamel(prop)] = val\n }\n }\n }\n\n if (Object.keys(style).length === 0) return base\n return <span style={style}>{base}</span>\n }\n}\n\nexport function RichTextContent({\n data,\n className,\n internalDocToHref,\n converters,\n blocks,\n disableDefaultConverters,\n textState,\n}: RichTextContentProps) {\n const baseConverters: JSXConverters = {\n ...(disableDefaultConverters ? {} : defaultJSXConverters),\n ...LinkJSXConverter({ internalDocToHref }),\n ...(textState ? { text: createTextStateConverter(textState) } : {}),\n ...converters,\n ...(blocks ? { blocks } : {}),\n }\n\n return (\n <RichText data={data} className={className} converters={baseConverters} />\n )\n}\n","'use client'\n\n/* eslint-disable @typescript-eslint/no-explicit-any */\nimport React from 'react'\nimport { SerializedLinkNode } from '@payloadcms/richtext-lexical'\nimport { JSXConverters } from '@payloadcms/richtext-lexical/react'\nimport { RichTextContent, RichTextContentProps } from './index'\n\n// --- Slot prop types (each slot gets structured data + raw node) ---\n\nexport interface HeadingSlotProps {\n tag: 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6'\n children: React.ReactNode\n node: any\n}\n\nexport interface ParagraphSlotProps {\n children: React.ReactNode\n isEmpty: boolean\n node: any\n}\n\nexport interface BlockquoteSlotProps {\n children: React.ReactNode\n node: any\n}\n\nexport interface ListSlotProps {\n tag: 'ul' | 'ol'\n listType: string\n children: React.ReactNode\n node: any\n}\n\nexport interface ListItemSlotProps {\n children: React.ReactNode\n hasSubLists: boolean\n checked?: boolean\n value?: number\n node: any\n}\n\nexport interface LinkSlotProps {\n href: string\n target?: string\n rel?: string\n children: React.ReactNode\n node: any\n}\n\nexport interface HorizontalRuleSlotProps {\n node?: any\n}\n\nexport interface UploadSlotProps {\n src: string\n alt: string\n width?: number\n height?: number\n mimeType: string\n filename: string\n sizes?: Record<string, any>\n node: any\n}\n\nexport interface TableSlotProps {\n children: React.ReactNode\n node: any\n}\n\nexport interface TableRowSlotProps {\n children: React.ReactNode\n node: any\n}\n\nexport interface TableCellSlotProps {\n tag: 'th' | 'td'\n children: React.ReactNode\n colSpan?: number\n rowSpan?: number\n backgroundColor?: string\n node: any\n}\n\n// --- Components map ---\n\nexport interface RichTextComponents {\n Heading?: React.ComponentType<HeadingSlotProps>\n Paragraph?: React.ComponentType<ParagraphSlotProps>\n Blockquote?: React.ComponentType<BlockquoteSlotProps>\n List?: React.ComponentType<ListSlotProps>\n ListItem?: React.ComponentType<ListItemSlotProps>\n Link?: React.ComponentType<LinkSlotProps>\n HorizontalRule?: React.ComponentType<HorizontalRuleSlotProps>\n Upload?: React.ComponentType<UploadSlotProps>\n Table?: React.ComponentType<TableSlotProps>\n TableRow?: React.ComponentType<TableRowSlotProps>\n TableCell?: React.ComponentType<TableCellSlotProps>\n}\n\nexport interface StyledRichTextContentProps extends Omit<\n RichTextContentProps,\n 'converters' | 'disableDefaultConverters'\n> {\n components?: RichTextComponents\n}\n\nfunction createComponentConverters(\n components: RichTextComponents,\n internalDocToHref?: (args: { linkNode: SerializedLinkNode }) => string,\n): Partial<JSXConverters> {\n const converters: Partial<JSXConverters> = {}\n\n if (components.Heading) {\n const Heading = components.Heading\n converters.heading = ({ node, nodesToJSX }) => (\n <Heading tag={node.tag} node={node}>\n {nodesToJSX({ nodes: node.children })}\n </Heading>\n )\n }\n\n if (components.Paragraph) {\n const Paragraph = components.Paragraph\n converters.paragraph = ({ node, nodesToJSX }) => {\n const children = nodesToJSX({ nodes: node.children })\n return (\n <Paragraph isEmpty={!children?.length} node={node}>\n {children?.length ? children : <br />}\n </Paragraph>\n )\n }\n }\n\n if (components.Blockquote) {\n const Blockquote = components.Blockquote\n converters.quote = ({ node, nodesToJSX }) => (\n <Blockquote node={node}>\n {nodesToJSX({ nodes: node.children })}\n </Blockquote>\n )\n }\n\n if (components.List) {\n const List = components.List\n converters.list = ({ node, nodesToJSX }) => (\n <List tag={node.tag} listType={node.listType} node={node}>\n {nodesToJSX({ nodes: node.children })}\n </List>\n )\n }\n\n if (components.ListItem) {\n const ListItem = components.ListItem\n converters.listitem = ({ node, nodesToJSX }) => {\n const hasSubLists = node.children.some(\n (child: { type: string }) => child.type === 'list',\n )\n return (\n <ListItem\n hasSubLists={hasSubLists}\n checked={node.checked}\n value={node.value}\n node={node}\n >\n {nodesToJSX({ nodes: node.children })}\n </ListItem>\n )\n }\n }\n\n if (components.Link) {\n const Link = components.Link\n\n const resolveHref = (node: any): string => {\n if (node.fields.linkType === 'internal') {\n return internalDocToHref ? internalDocToHref({ linkNode: node }) : '#'\n }\n return node.fields.url ?? ''\n }\n\n converters.link = ({ node, nodesToJSX }) => (\n <Link\n href={resolveHref(node)}\n rel={node.fields.newTab ? 'noopener noreferrer' : undefined}\n target={node.fields.newTab ? '_blank' : undefined}\n node={node}\n >\n {nodesToJSX({ nodes: node.children })}\n </Link>\n )\n\n converters.autolink = ({ node, nodesToJSX }) => (\n <Link\n href={node.fields.url ?? ''}\n rel={node.fields.newTab ? 'noopener noreferrer' : undefined}\n target={node.fields.newTab ? '_blank' : undefined}\n node={node}\n >\n {nodesToJSX({ nodes: node.children })}\n </Link>\n )\n }\n\n if (components.HorizontalRule) {\n const HorizontalRule = components.HorizontalRule\n converters.horizontalrule = <HorizontalRule />\n }\n\n if (components.Upload) {\n const Upload = components.Upload\n converters.upload = ({ node }) => {\n const uploadNode = node as any\n if (typeof uploadNode.value !== 'object') return null\n const doc = uploadNode.value\n return (\n <Upload\n src={doc.url}\n alt={uploadNode.fields?.alt || doc?.alt || ''}\n width={doc.width}\n height={doc.height}\n mimeType={doc.mimeType}\n filename={doc.filename}\n sizes={doc.sizes}\n node={node}\n />\n )\n }\n }\n\n if (components.Table) {\n const Table = components.Table\n converters.table = ({ node, nodesToJSX }) => (\n <Table node={node}>{nodesToJSX({ nodes: node.children })}</Table>\n )\n }\n\n if (components.TableRow) {\n const TableRow = components.TableRow\n converters.tablerow = ({ node, nodesToJSX }) => (\n <TableRow node={node}>{nodesToJSX({ nodes: node.children })}</TableRow>\n )\n }\n\n if (components.TableCell) {\n const TableCell = components.TableCell\n converters.tablecell = ({ node, nodesToJSX }) => (\n <TableCell\n tag={node.headerState > 0 ? 'th' : 'td'}\n colSpan={node.colSpan > 1 ? node.colSpan : undefined}\n rowSpan={node.rowSpan > 1 ? node.rowSpan : undefined}\n backgroundColor={node.backgroundColor || undefined}\n node={node}\n >\n {nodesToJSX({ nodes: node.children })}\n </TableCell>\n )\n }\n\n return converters\n}\n\nexport function StyledRichTextContent({\n components = {},\n internalDocToHref,\n blocks,\n textState,\n ...props\n}: StyledRichTextContentProps) {\n const converters = createComponentConverters(components, internalDocToHref)\n\n return (\n <RichTextContent\n {...props}\n internalDocToHref={internalDocToHref}\n converters={converters}\n blocks={blocks}\n textState={textState}\n />\n )\n}\n"],"mappings":"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","names":["import_react","React","_a","_b","React"]}
@@ -31,7 +31,7 @@ var __objRest = (source, exclude) => {
31
31
  return target;
32
32
  };
33
33
 
34
- // src/components/RichTextContent/index.tsx
34
+ // src/ui/RichText/index.tsx
35
35
  import React2 from "react";
36
36
  import {
37
37
  defaultJSXConverters,
@@ -40,7 +40,7 @@ import {
40
40
  TextJSXConverter
41
41
  } from "@payloadcms/richtext-lexical/react";
42
42
 
43
- // src/components/RichTextContent/styled.tsx
43
+ // src/ui/RichText/styled.tsx
44
44
  import React from "react";
45
45
  function createComponentConverters(components, internalDocToHref) {
46
46
  const converters = {};
@@ -188,7 +188,7 @@ function StyledRichTextContent(_a) {
188
188
  );
189
189
  }
190
190
 
191
- // src/components/RichTextContent/index.tsx
191
+ // src/ui/RichText/index.tsx
192
192
  function hyphenToCamel(str) {
193
193
  return str.replace(/-([a-z])/g, (_, c) => c.toUpperCase());
194
194
  }
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/ui/RichText/index.tsx","../../src/ui/RichText/styled.tsx"],"sourcesContent":["'use client'\n\nimport React from 'react'\nimport {\n SerializedBlockNode,\n SerializedLinkNode,\n} from '@payloadcms/richtext-lexical'\nimport {\n SerializedEditorState,\n SerializedLexicalNode,\n} from '@payloadcms/richtext-lexical/lexical'\nimport {\n defaultJSXConverters,\n JSXConverter,\n JSXConverters,\n LinkJSXConverter,\n RichText,\n TextJSXConverter,\n} from '@payloadcms/richtext-lexical/react'\n\nexport type RichTextData = SerializedEditorState<SerializedLexicalNode>\n\nexport type TextStateConfig = {\n [stateKey: string]: {\n [stateValue: string]: {\n css: Record<string, string>\n label: string\n }\n }\n}\n\nexport interface RichTextContentProps {\n data: RichTextData\n className?: string\n internalDocToHref?: (args: { linkNode: SerializedLinkNode }) => string\n converters?: Partial<JSXConverters>\n blocks?: Record<string, JSXConverter<SerializedBlockNode>>\n disableDefaultConverters?: boolean\n textState?: TextStateConfig\n}\n\nexport { StyledRichTextContent } from './styled'\nexport type {\n RichTextComponents,\n StyledRichTextContentProps,\n HeadingSlotProps,\n ParagraphSlotProps,\n BlockquoteSlotProps,\n ListSlotProps,\n ListItemSlotProps,\n LinkSlotProps,\n HorizontalRuleSlotProps,\n UploadSlotProps,\n TableSlotProps,\n TableRowSlotProps,\n TableCellSlotProps,\n} from './styled'\n\nfunction hyphenToCamel(str: string): string {\n return str.replace(/-([a-z])/g, (_, c) => c.toUpperCase())\n}\n\nfunction createTextStateConverter(\n state: TextStateConfig,\n): JSXConverters['text'] {\n const defaultTextConverter = TextJSXConverter.text\n // eslint-disable-next-line react/display-name\n return ({ node, ...rest }) => {\n const base = (\n defaultTextConverter as (...args: unknown[]) => React.ReactNode\n )({ node, ...rest })\n const nodeState = (node as Record<string, unknown>).$ as\n | Record<string, string>\n | undefined\n if (!nodeState || typeof nodeState !== 'object') return base\n\n const style: Record<string, string> = {}\n for (const stateKey in nodeState) {\n const stateValue = nodeState[stateKey]\n if (!stateValue) continue\n const css = state[stateKey]?.[stateValue]?.css\n if (css) {\n for (const prop in css) {\n const val = css[prop]\n if (val) style[hyphenToCamel(prop)] = val\n }\n }\n }\n\n if (Object.keys(style).length === 0) return base\n return <span style={style}>{base}</span>\n }\n}\n\nexport function RichTextContent({\n data,\n className,\n internalDocToHref,\n converters,\n blocks,\n disableDefaultConverters,\n textState,\n}: RichTextContentProps) {\n const baseConverters: JSXConverters = {\n ...(disableDefaultConverters ? {} : defaultJSXConverters),\n ...LinkJSXConverter({ internalDocToHref }),\n ...(textState ? { text: createTextStateConverter(textState) } : {}),\n ...converters,\n ...(blocks ? { blocks } : {}),\n }\n\n return (\n <RichText data={data} className={className} converters={baseConverters} />\n )\n}\n","'use client'\n\n/* eslint-disable @typescript-eslint/no-explicit-any */\nimport React from 'react'\nimport { SerializedLinkNode } from '@payloadcms/richtext-lexical'\nimport { JSXConverters } from '@payloadcms/richtext-lexical/react'\nimport { RichTextContent, RichTextContentProps } from './index'\n\n// --- Slot prop types (each slot gets structured data + raw node) ---\n\nexport interface HeadingSlotProps {\n tag: 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6'\n children: React.ReactNode\n node: any\n}\n\nexport interface ParagraphSlotProps {\n children: React.ReactNode\n isEmpty: boolean\n node: any\n}\n\nexport interface BlockquoteSlotProps {\n children: React.ReactNode\n node: any\n}\n\nexport interface ListSlotProps {\n tag: 'ul' | 'ol'\n listType: string\n children: React.ReactNode\n node: any\n}\n\nexport interface ListItemSlotProps {\n children: React.ReactNode\n hasSubLists: boolean\n checked?: boolean\n value?: number\n node: any\n}\n\nexport interface LinkSlotProps {\n href: string\n target?: string\n rel?: string\n children: React.ReactNode\n node: any\n}\n\nexport interface HorizontalRuleSlotProps {\n node?: any\n}\n\nexport interface UploadSlotProps {\n src: string\n alt: string\n width?: number\n height?: number\n mimeType: string\n filename: string\n sizes?: Record<string, any>\n node: any\n}\n\nexport interface TableSlotProps {\n children: React.ReactNode\n node: any\n}\n\nexport interface TableRowSlotProps {\n children: React.ReactNode\n node: any\n}\n\nexport interface TableCellSlotProps {\n tag: 'th' | 'td'\n children: React.ReactNode\n colSpan?: number\n rowSpan?: number\n backgroundColor?: string\n node: any\n}\n\n// --- Components map ---\n\nexport interface RichTextComponents {\n Heading?: React.ComponentType<HeadingSlotProps>\n Paragraph?: React.ComponentType<ParagraphSlotProps>\n Blockquote?: React.ComponentType<BlockquoteSlotProps>\n List?: React.ComponentType<ListSlotProps>\n ListItem?: React.ComponentType<ListItemSlotProps>\n Link?: React.ComponentType<LinkSlotProps>\n HorizontalRule?: React.ComponentType<HorizontalRuleSlotProps>\n Upload?: React.ComponentType<UploadSlotProps>\n Table?: React.ComponentType<TableSlotProps>\n TableRow?: React.ComponentType<TableRowSlotProps>\n TableCell?: React.ComponentType<TableCellSlotProps>\n}\n\nexport interface StyledRichTextContentProps extends Omit<\n RichTextContentProps,\n 'converters' | 'disableDefaultConverters'\n> {\n components?: RichTextComponents\n}\n\nfunction createComponentConverters(\n components: RichTextComponents,\n internalDocToHref?: (args: { linkNode: SerializedLinkNode }) => string,\n): Partial<JSXConverters> {\n const converters: Partial<JSXConverters> = {}\n\n if (components.Heading) {\n const Heading = components.Heading\n converters.heading = ({ node, nodesToJSX }) => (\n <Heading tag={node.tag} node={node}>\n {nodesToJSX({ nodes: node.children })}\n </Heading>\n )\n }\n\n if (components.Paragraph) {\n const Paragraph = components.Paragraph\n converters.paragraph = ({ node, nodesToJSX }) => {\n const children = nodesToJSX({ nodes: node.children })\n return (\n <Paragraph isEmpty={!children?.length} node={node}>\n {children?.length ? children : <br />}\n </Paragraph>\n )\n }\n }\n\n if (components.Blockquote) {\n const Blockquote = components.Blockquote\n converters.quote = ({ node, nodesToJSX }) => (\n <Blockquote node={node}>\n {nodesToJSX({ nodes: node.children })}\n </Blockquote>\n )\n }\n\n if (components.List) {\n const List = components.List\n converters.list = ({ node, nodesToJSX }) => (\n <List tag={node.tag} listType={node.listType} node={node}>\n {nodesToJSX({ nodes: node.children })}\n </List>\n )\n }\n\n if (components.ListItem) {\n const ListItem = components.ListItem\n converters.listitem = ({ node, nodesToJSX }) => {\n const hasSubLists = node.children.some(\n (child: { type: string }) => child.type === 'list',\n )\n return (\n <ListItem\n hasSubLists={hasSubLists}\n checked={node.checked}\n value={node.value}\n node={node}\n >\n {nodesToJSX({ nodes: node.children })}\n </ListItem>\n )\n }\n }\n\n if (components.Link) {\n const Link = components.Link\n\n const resolveHref = (node: any): string => {\n if (node.fields.linkType === 'internal') {\n return internalDocToHref ? internalDocToHref({ linkNode: node }) : '#'\n }\n return node.fields.url ?? ''\n }\n\n converters.link = ({ node, nodesToJSX }) => (\n <Link\n href={resolveHref(node)}\n rel={node.fields.newTab ? 'noopener noreferrer' : undefined}\n target={node.fields.newTab ? '_blank' : undefined}\n node={node}\n >\n {nodesToJSX({ nodes: node.children })}\n </Link>\n )\n\n converters.autolink = ({ node, nodesToJSX }) => (\n <Link\n href={node.fields.url ?? ''}\n rel={node.fields.newTab ? 'noopener noreferrer' : undefined}\n target={node.fields.newTab ? '_blank' : undefined}\n node={node}\n >\n {nodesToJSX({ nodes: node.children })}\n </Link>\n )\n }\n\n if (components.HorizontalRule) {\n const HorizontalRule = components.HorizontalRule\n converters.horizontalrule = <HorizontalRule />\n }\n\n if (components.Upload) {\n const Upload = components.Upload\n converters.upload = ({ node }) => {\n const uploadNode = node as any\n if (typeof uploadNode.value !== 'object') return null\n const doc = uploadNode.value\n return (\n <Upload\n src={doc.url}\n alt={uploadNode.fields?.alt || doc?.alt || ''}\n width={doc.width}\n height={doc.height}\n mimeType={doc.mimeType}\n filename={doc.filename}\n sizes={doc.sizes}\n node={node}\n />\n )\n }\n }\n\n if (components.Table) {\n const Table = components.Table\n converters.table = ({ node, nodesToJSX }) => (\n <Table node={node}>{nodesToJSX({ nodes: node.children })}</Table>\n )\n }\n\n if (components.TableRow) {\n const TableRow = components.TableRow\n converters.tablerow = ({ node, nodesToJSX }) => (\n <TableRow node={node}>{nodesToJSX({ nodes: node.children })}</TableRow>\n )\n }\n\n if (components.TableCell) {\n const TableCell = components.TableCell\n converters.tablecell = ({ node, nodesToJSX }) => (\n <TableCell\n tag={node.headerState > 0 ? 'th' : 'td'}\n colSpan={node.colSpan > 1 ? node.colSpan : undefined}\n rowSpan={node.rowSpan > 1 ? node.rowSpan : undefined}\n backgroundColor={node.backgroundColor || undefined}\n node={node}\n >\n {nodesToJSX({ nodes: node.children })}\n </TableCell>\n )\n }\n\n return converters\n}\n\nexport function StyledRichTextContent({\n components = {},\n internalDocToHref,\n blocks,\n textState,\n ...props\n}: StyledRichTextContentProps) {\n const converters = createComponentConverters(components, internalDocToHref)\n\n return (\n <RichTextContent\n {...props}\n internalDocToHref={internalDocToHref}\n converters={converters}\n blocks={blocks}\n textState={textState}\n />\n )\n}\n"],"mappings":"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","names":["React","_a","_b","React"]}
@@ -1,4 +1,4 @@
1
- import { d as Config } from './payload-types-BjvBwB8Z.js';
1
+ import { d as Config } from './payload-types-BUwpb306.cjs';
2
2
 
3
3
  /**
4
4
  * Collection type derived from Payload Config.
@@ -9,7 +9,7 @@ type Collection = keyof Config['collections'];
9
9
  * Array of all public collection names for runtime use (e.g., Zod enum validation).
10
10
  * This is the single source of truth for which collections are publicly accessible via SDK.
11
11
  */
12
- declare const COLLECTIONS: readonly ["tenants", "tenant-metadata", "tenant-logos", "tenant-og-images", "products", "product-variants", "product-options", "product-categories", "product-tags", "product-images", "product-collections", "brands", "brand-logos", "orders", "order-products", "returns", "return-products", "exchanges", "exchange-products", "fulfillments", "fulfillment-items", "transactions", "customers", "customer-addresses", "customer-groups", "customer-group-images", "carts", "cart-items", "discounts", "shipping-policies", "documents", "document-categories", "document-types", "document-images", "posts", "post-categories", "post-tags", "post-images", "playlists", "playlist-images", "playlist-categories", "playlist-tags", "musics", "galleries", "gallery-images", "gallery-categories", "gallery-tags", "flows", "flow-images", "flow-node-types", "flow-edge-types", "flow-categories", "flow-tags", "videos", "video-images", "video-categories", "video-tags", "live-streams", "live-stream-images", "forms", "form-submissions", "media"];
12
+ declare const COLLECTIONS: readonly ["tenants", "tenant-metadata", "tenant-logos", "products", "product-variants", "product-options", "product-categories", "product-tags", "product-collections", "brands", "brand-logos", "orders", "order-products", "returns", "return-products", "exchanges", "exchange-products", "fulfillments", "fulfillment-items", "transactions", "customers", "customer-addresses", "customer-groups", "carts", "cart-items", "discounts", "shipping-policies", "documents", "document-categories", "document-types", "posts", "post-categories", "post-tags", "playlists", "playlist-categories", "playlist-tags", "musics", "galleries", "gallery-categories", "gallery-tags", "gallery-items", "flows", "flow-node-types", "flow-edge-types", "flow-categories", "flow-tags", "videos", "video-categories", "video-tags", "live-streams", "images", "forms", "form-submissions"];
13
13
  /**
14
14
  * Public collections available for SDK access.
15
15
  * Derived from the COLLECTIONS array (single source of truth).
@@ -1,4 +1,4 @@
1
- import { d as Config } from './payload-types-BjvBwB8Z.cjs';
1
+ import { d as Config } from './payload-types-BUwpb306.js';
2
2
 
3
3
  /**
4
4
  * Collection type derived from Payload Config.
@@ -9,7 +9,7 @@ type Collection = keyof Config['collections'];
9
9
  * Array of all public collection names for runtime use (e.g., Zod enum validation).
10
10
  * This is the single source of truth for which collections are publicly accessible via SDK.
11
11
  */
12
- declare const COLLECTIONS: readonly ["tenants", "tenant-metadata", "tenant-logos", "tenant-og-images", "products", "product-variants", "product-options", "product-categories", "product-tags", "product-images", "product-collections", "brands", "brand-logos", "orders", "order-products", "returns", "return-products", "exchanges", "exchange-products", "fulfillments", "fulfillment-items", "transactions", "customers", "customer-addresses", "customer-groups", "customer-group-images", "carts", "cart-items", "discounts", "shipping-policies", "documents", "document-categories", "document-types", "document-images", "posts", "post-categories", "post-tags", "post-images", "playlists", "playlist-images", "playlist-categories", "playlist-tags", "musics", "galleries", "gallery-images", "gallery-categories", "gallery-tags", "flows", "flow-images", "flow-node-types", "flow-edge-types", "flow-categories", "flow-tags", "videos", "video-images", "video-categories", "video-tags", "live-streams", "live-stream-images", "forms", "form-submissions", "media"];
12
+ declare const COLLECTIONS: readonly ["tenants", "tenant-metadata", "tenant-logos", "products", "product-variants", "product-options", "product-categories", "product-tags", "product-collections", "brands", "brand-logos", "orders", "order-products", "returns", "return-products", "exchanges", "exchange-products", "fulfillments", "fulfillment-items", "transactions", "customers", "customer-addresses", "customer-groups", "carts", "cart-items", "discounts", "shipping-policies", "documents", "document-categories", "document-types", "posts", "post-categories", "post-tags", "playlists", "playlist-categories", "playlist-tags", "musics", "galleries", "gallery-categories", "gallery-tags", "gallery-items", "flows", "flow-node-types", "flow-edge-types", "flow-categories", "flow-tags", "videos", "video-categories", "video-tags", "live-streams", "images", "forms", "form-submissions"];
13
13
  /**
14
14
  * Public collections available for SDK access.
15
15
  * Derived from the COLLECTIONS array (single source of truth).
package/dist/webhook.cjs CHANGED
@@ -104,17 +104,19 @@ function handleWebhook(request, handler, options) {
104
104
  );
105
105
  } catch (error) {
106
106
  console.error("Webhook processing error:", error);
107
- return new Response(
108
- JSON.stringify({ error: "Internal server error" }),
109
- { status: 500, headers: { "Content-Type": "application/json" } }
110
- );
107
+ return new Response(JSON.stringify({ error: "Internal server error" }), {
108
+ status: 500,
109
+ headers: { "Content-Type": "application/json" }
110
+ });
111
111
  }
112
112
  });
113
113
  }
114
114
  function createTypedWebhookHandler(collection, handler) {
115
115
  return (event) => __async(null, null, function* () {
116
116
  if (event.collection !== collection) {
117
- throw new Error(`Expected collection "${collection}", got "${event.collection}"`);
117
+ throw new Error(
118
+ `Expected collection "${collection}", got "${event.collection}"`
119
+ );
118
120
  }
119
121
  return handler(event);
120
122
  });
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/webhook.ts","../src/core/webhook/index.ts"],"sourcesContent":["export {\n handleWebhook,\n createTypedWebhookHandler,\n isValidWebhookEvent,\n} from './core/webhook'\nexport type {\n WebhookEvent,\n WebhookHandler,\n WebhookOperation,\n WebhookOptions,\n} from './core/webhook'\n","import type { Collection } from '../client/types'\nimport type { CollectionType } from '../collection/types'\n\nexport type WebhookOperation = 'create' | 'update'\n\nexport interface WebhookEvent<T extends Collection = Collection> {\n collection: T\n operation: WebhookOperation\n data: CollectionType<T>\n}\n\nexport type WebhookHandler<T extends Collection = Collection> = (\n event: WebhookEvent<T>,\n) => Promise<void> | void\n\nexport interface WebhookOptions {\n secret?: string\n}\n\nexport function isValidWebhookEvent(data: unknown): data is WebhookEvent {\n if (typeof data !== 'object' || data === null) return false\n const obj = data as Record<string, unknown>\n return (\n typeof obj.collection === 'string' &&\n (obj.operation === 'create' || obj.operation === 'update') &&\n typeof obj.data === 'object' &&\n obj.data !== null\n )\n}\n\nasync function verifySignature(\n payload: string,\n secret: string,\n signature: string,\n): Promise<boolean> {\n const encoder = new TextEncoder()\n const key = await crypto.subtle.importKey(\n 'raw',\n encoder.encode(secret),\n { name: 'HMAC', hash: 'SHA-256' },\n false,\n ['sign'],\n )\n const sig = await crypto.subtle.sign('HMAC', key, encoder.encode(payload))\n const expected = Array.from(new Uint8Array(sig))\n .map((b) => b.toString(16).padStart(2, '0'))\n .join('')\n // Constant-time comparison to prevent timing attacks\n let result = expected.length !== signature.length ? 1 : 0\n const len = Math.max(expected.length, signature.length)\n for (let i = 0; i < len; i++) {\n result |= (expected.charCodeAt(i) || 0) ^ (signature.charCodeAt(i) || 0)\n }\n return result === 0\n}\n\nexport async function handleWebhook<T extends Collection = Collection>(\n request: Request,\n handler: WebhookHandler<T>,\n options?: WebhookOptions,\n): Promise<Response> {\n try {\n const rawBody = await request.text()\n\n if (options?.secret) {\n const signature = request.headers.get('x-webhook-signature') || ''\n const valid = await verifySignature(rawBody, options.secret, signature)\n if (!valid) {\n return new Response(\n JSON.stringify({ error: 'Invalid webhook signature' }),\n { status: 401, headers: { 'Content-Type': 'application/json' } },\n )\n }\n } else {\n console.warn(\n '[@01.software/sdk] Webhook signature verification is disabled. ' +\n 'Set { secret } in handleWebhook() options to enable HMAC-SHA256 verification.',\n )\n }\n\n const body = JSON.parse(rawBody)\n\n if (!isValidWebhookEvent(body)) {\n return new Response(\n JSON.stringify({ error: 'Invalid webhook event format' }),\n { status: 400, headers: { 'Content-Type': 'application/json' } },\n )\n }\n\n await handler(body as WebhookEvent<T>)\n\n return new Response(\n JSON.stringify({ success: true, message: 'Webhook processed' }),\n { status: 200, headers: { 'Content-Type': 'application/json' } },\n )\n } catch (error) {\n console.error('Webhook processing error:', error)\n\n return new Response(\n JSON.stringify({ error: 'Internal server error' }),\n { status: 500, headers: { 'Content-Type': 'application/json' } },\n )\n }\n}\n\nexport function createTypedWebhookHandler<T extends Collection>(\n collection: T,\n handler: (event: WebhookEvent<T>) => Promise<void> | void,\n): WebhookHandler<T> {\n return async (event: WebhookEvent<T>) => {\n if (event.collection !== collection) {\n throw new Error(`Expected collection \"${collection}\", got \"${event.collection}\"`)\n }\n return handler(event)\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACmBO,SAAS,oBAAoB,MAAqC;AACvE,MAAI,OAAO,SAAS,YAAY,SAAS,KAAM,QAAO;AACtD,QAAM,MAAM;AACZ,SACE,OAAO,IAAI,eAAe,aACzB,IAAI,cAAc,YAAY,IAAI,cAAc,aACjD,OAAO,IAAI,SAAS,YACpB,IAAI,SAAS;AAEjB;AAEA,SAAe,gBACb,SACA,QACA,WACkB;AAAA;AAClB,UAAM,UAAU,IAAI,YAAY;AAChC,UAAM,MAAM,MAAM,OAAO,OAAO;AAAA,MAC9B;AAAA,MACA,QAAQ,OAAO,MAAM;AAAA,MACrB,EAAE,MAAM,QAAQ,MAAM,UAAU;AAAA,MAChC;AAAA,MACA,CAAC,MAAM;AAAA,IACT;AACA,UAAM,MAAM,MAAM,OAAO,OAAO,KAAK,QAAQ,KAAK,QAAQ,OAAO,OAAO,CAAC;AACzE,UAAM,WAAW,MAAM,KAAK,IAAI,WAAW,GAAG,CAAC,EAC5C,IAAI,CAAC,MAAM,EAAE,SAAS,EAAE,EAAE,SAAS,GAAG,GAAG,CAAC,EAC1C,KAAK,EAAE;AAEV,QAAI,SAAS,SAAS,WAAW,UAAU,SAAS,IAAI;AACxD,UAAM,MAAM,KAAK,IAAI,SAAS,QAAQ,UAAU,MAAM;AACtD,aAAS,IAAI,GAAG,IAAI,KAAK,KAAK;AAC5B,iBAAW,SAAS,WAAW,CAAC,KAAK,MAAM,UAAU,WAAW,CAAC,KAAK;AAAA,IACxE;AACA,WAAO,WAAW;AAAA,EACpB;AAAA;AAEA,SAAsB,cACpB,SACA,SACA,SACmB;AAAA;AACnB,QAAI;AACF,YAAM,UAAU,MAAM,QAAQ,KAAK;AAEnC,UAAI,mCAAS,QAAQ;AACnB,cAAM,YAAY,QAAQ,QAAQ,IAAI,qBAAqB,KAAK;AAChE,cAAM,QAAQ,MAAM,gBAAgB,SAAS,QAAQ,QAAQ,SAAS;AACtE,YAAI,CAAC,OAAO;AACV,iBAAO,IAAI;AAAA,YACT,KAAK,UAAU,EAAE,OAAO,4BAA4B,CAAC;AAAA,YACrD,EAAE,QAAQ,KAAK,SAAS,EAAE,gBAAgB,mBAAmB,EAAE;AAAA,UACjE;AAAA,QACF;AAAA,MACF,OAAO;AACL,gBAAQ;AAAA,UACN;AAAA,QAEF;AAAA,MACF;AAEA,YAAM,OAAO,KAAK,MAAM,OAAO;AAE/B,UAAI,CAAC,oBAAoB,IAAI,GAAG;AAC9B,eAAO,IAAI;AAAA,UACT,KAAK,UAAU,EAAE,OAAO,+BAA+B,CAAC;AAAA,UACxD,EAAE,QAAQ,KAAK,SAAS,EAAE,gBAAgB,mBAAmB,EAAE;AAAA,QACjE;AAAA,MACF;AAEA,YAAM,QAAQ,IAAuB;AAErC,aAAO,IAAI;AAAA,QACT,KAAK,UAAU,EAAE,SAAS,MAAM,SAAS,oBAAoB,CAAC;AAAA,QAC9D,EAAE,QAAQ,KAAK,SAAS,EAAE,gBAAgB,mBAAmB,EAAE;AAAA,MACjE;AAAA,IACF,SAAS,OAAO;AACd,cAAQ,MAAM,6BAA6B,KAAK;AAEhD,aAAO,IAAI;AAAA,QACT,KAAK,UAAU,EAAE,OAAO,wBAAwB,CAAC;AAAA,QACjD,EAAE,QAAQ,KAAK,SAAS,EAAE,gBAAgB,mBAAmB,EAAE;AAAA,MACjE;AAAA,IACF;AAAA,EACF;AAAA;AAEO,SAAS,0BACd,YACA,SACmB;AACnB,SAAO,CAAO,UAA2B;AACvC,QAAI,MAAM,eAAe,YAAY;AACnC,YAAM,IAAI,MAAM,wBAAwB,UAAU,WAAW,MAAM,UAAU,GAAG;AAAA,IAClF;AACA,WAAO,QAAQ,KAAK;AAAA,EACtB;AACF;","names":[]}
1
+ {"version":3,"sources":["../src/webhook.ts","../src/core/webhook/index.ts"],"sourcesContent":["export {\n handleWebhook,\n createTypedWebhookHandler,\n isValidWebhookEvent,\n} from './core/webhook'\nexport type {\n WebhookEvent,\n WebhookHandler,\n WebhookOperation,\n WebhookOptions,\n} from './core/webhook'\n","import type { Collection } from '../client/types'\nimport type { CollectionType } from '../collection/types'\n\nexport type WebhookOperation = 'create' | 'update'\n\nexport interface WebhookEvent<T extends Collection = Collection> {\n collection: T\n operation: WebhookOperation\n data: CollectionType<T>\n}\n\nexport type WebhookHandler<T extends Collection = Collection> = (\n event: WebhookEvent<T>,\n) => Promise<void> | void\n\nexport interface WebhookOptions {\n secret?: string\n}\n\nexport function isValidWebhookEvent(data: unknown): data is WebhookEvent {\n if (typeof data !== 'object' || data === null) return false\n const obj = data as Record<string, unknown>\n return (\n typeof obj.collection === 'string' &&\n (obj.operation === 'create' || obj.operation === 'update') &&\n typeof obj.data === 'object' &&\n obj.data !== null\n )\n}\n\nasync function verifySignature(\n payload: string,\n secret: string,\n signature: string,\n): Promise<boolean> {\n const encoder = new TextEncoder()\n const key = await crypto.subtle.importKey(\n 'raw',\n encoder.encode(secret),\n { name: 'HMAC', hash: 'SHA-256' },\n false,\n ['sign'],\n )\n const sig = await crypto.subtle.sign('HMAC', key, encoder.encode(payload))\n const expected = Array.from(new Uint8Array(sig))\n .map((b) => b.toString(16).padStart(2, '0'))\n .join('')\n // Constant-time comparison to prevent timing attacks\n let result = expected.length !== signature.length ? 1 : 0\n const len = Math.max(expected.length, signature.length)\n for (let i = 0; i < len; i++) {\n result |= (expected.charCodeAt(i) || 0) ^ (signature.charCodeAt(i) || 0)\n }\n return result === 0\n}\n\nexport async function handleWebhook<T extends Collection = Collection>(\n request: Request,\n handler: WebhookHandler<T>,\n options?: WebhookOptions,\n): Promise<Response> {\n try {\n const rawBody = await request.text()\n\n if (options?.secret) {\n const signature = request.headers.get('x-webhook-signature') || ''\n const valid = await verifySignature(rawBody, options.secret, signature)\n if (!valid) {\n return new Response(\n JSON.stringify({ error: 'Invalid webhook signature' }),\n { status: 401, headers: { 'Content-Type': 'application/json' } },\n )\n }\n } else {\n console.warn(\n '[@01.software/sdk] Webhook signature verification is disabled. ' +\n 'Set { secret } in handleWebhook() options to enable HMAC-SHA256 verification.',\n )\n }\n\n const body = JSON.parse(rawBody)\n\n if (!isValidWebhookEvent(body)) {\n return new Response(\n JSON.stringify({ error: 'Invalid webhook event format' }),\n { status: 400, headers: { 'Content-Type': 'application/json' } },\n )\n }\n\n await handler(body as WebhookEvent<T>)\n\n return new Response(\n JSON.stringify({ success: true, message: 'Webhook processed' }),\n { status: 200, headers: { 'Content-Type': 'application/json' } },\n )\n } catch (error) {\n console.error('Webhook processing error:', error)\n\n return new Response(JSON.stringify({ error: 'Internal server error' }), {\n status: 500,\n headers: { 'Content-Type': 'application/json' },\n })\n }\n}\n\nexport function createTypedWebhookHandler<T extends Collection>(\n collection: T,\n handler: (event: WebhookEvent<T>) => Promise<void> | void,\n): WebhookHandler<T> {\n return async (event: WebhookEvent<T>) => {\n if (event.collection !== collection) {\n throw new Error(\n `Expected collection \"${collection}\", got \"${event.collection}\"`,\n )\n }\n return handler(event)\n }\n}\n"],"mappings":"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","names":[]}
@@ -1,2 +1,2 @@
1
- export { c as WebhookEvent, d as WebhookHandler, W as WebhookOperation, e as WebhookOptions, f as createTypedWebhookHandler, h as handleWebhook, i as isValidWebhookEvent } from './webhook-CszIpUKn.cjs';
2
- import './payload-types-BjvBwB8Z.cjs';
1
+ export { c as WebhookEvent, d as WebhookHandler, W as WebhookOperation, e as WebhookOptions, f as createTypedWebhookHandler, h as handleWebhook, i as isValidWebhookEvent } from './webhook-BUcDo2Ny.cjs';
2
+ import './payload-types-BUwpb306.cjs';
package/dist/webhook.d.ts CHANGED
@@ -1,2 +1,2 @@
1
- export { c as WebhookEvent, d as WebhookHandler, W as WebhookOperation, e as WebhookOptions, f as createTypedWebhookHandler, h as handleWebhook, i as isValidWebhookEvent } from './webhook-_LdLdjGa.js';
2
- import './payload-types-BjvBwB8Z.js';
1
+ export { c as WebhookEvent, d as WebhookHandler, W as WebhookOperation, e as WebhookOptions, f as createTypedWebhookHandler, h as handleWebhook, i as isValidWebhookEvent } from './webhook-D8Bp97bF.js';
2
+ import './payload-types-BUwpb306.js';
package/dist/webhook.js CHANGED
@@ -77,17 +77,19 @@ function handleWebhook(request, handler, options) {
77
77
  );
78
78
  } catch (error) {
79
79
  console.error("Webhook processing error:", error);
80
- return new Response(
81
- JSON.stringify({ error: "Internal server error" }),
82
- { status: 500, headers: { "Content-Type": "application/json" } }
83
- );
80
+ return new Response(JSON.stringify({ error: "Internal server error" }), {
81
+ status: 500,
82
+ headers: { "Content-Type": "application/json" }
83
+ });
84
84
  }
85
85
  });
86
86
  }
87
87
  function createTypedWebhookHandler(collection, handler) {
88
88
  return (event) => __async(null, null, function* () {
89
89
  if (event.collection !== collection) {
90
- throw new Error(`Expected collection "${collection}", got "${event.collection}"`);
90
+ throw new Error(
91
+ `Expected collection "${collection}", got "${event.collection}"`
92
+ );
91
93
  }
92
94
  return handler(event);
93
95
  });
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/core/webhook/index.ts"],"sourcesContent":["import type { Collection } from '../client/types'\nimport type { CollectionType } from '../collection/types'\n\nexport type WebhookOperation = 'create' | 'update'\n\nexport interface WebhookEvent<T extends Collection = Collection> {\n collection: T\n operation: WebhookOperation\n data: CollectionType<T>\n}\n\nexport type WebhookHandler<T extends Collection = Collection> = (\n event: WebhookEvent<T>,\n) => Promise<void> | void\n\nexport interface WebhookOptions {\n secret?: string\n}\n\nexport function isValidWebhookEvent(data: unknown): data is WebhookEvent {\n if (typeof data !== 'object' || data === null) return false\n const obj = data as Record<string, unknown>\n return (\n typeof obj.collection === 'string' &&\n (obj.operation === 'create' || obj.operation === 'update') &&\n typeof obj.data === 'object' &&\n obj.data !== null\n )\n}\n\nasync function verifySignature(\n payload: string,\n secret: string,\n signature: string,\n): Promise<boolean> {\n const encoder = new TextEncoder()\n const key = await crypto.subtle.importKey(\n 'raw',\n encoder.encode(secret),\n { name: 'HMAC', hash: 'SHA-256' },\n false,\n ['sign'],\n )\n const sig = await crypto.subtle.sign('HMAC', key, encoder.encode(payload))\n const expected = Array.from(new Uint8Array(sig))\n .map((b) => b.toString(16).padStart(2, '0'))\n .join('')\n // Constant-time comparison to prevent timing attacks\n let result = expected.length !== signature.length ? 1 : 0\n const len = Math.max(expected.length, signature.length)\n for (let i = 0; i < len; i++) {\n result |= (expected.charCodeAt(i) || 0) ^ (signature.charCodeAt(i) || 0)\n }\n return result === 0\n}\n\nexport async function handleWebhook<T extends Collection = Collection>(\n request: Request,\n handler: WebhookHandler<T>,\n options?: WebhookOptions,\n): Promise<Response> {\n try {\n const rawBody = await request.text()\n\n if (options?.secret) {\n const signature = request.headers.get('x-webhook-signature') || ''\n const valid = await verifySignature(rawBody, options.secret, signature)\n if (!valid) {\n return new Response(\n JSON.stringify({ error: 'Invalid webhook signature' }),\n { status: 401, headers: { 'Content-Type': 'application/json' } },\n )\n }\n } else {\n console.warn(\n '[@01.software/sdk] Webhook signature verification is disabled. ' +\n 'Set { secret } in handleWebhook() options to enable HMAC-SHA256 verification.',\n )\n }\n\n const body = JSON.parse(rawBody)\n\n if (!isValidWebhookEvent(body)) {\n return new Response(\n JSON.stringify({ error: 'Invalid webhook event format' }),\n { status: 400, headers: { 'Content-Type': 'application/json' } },\n )\n }\n\n await handler(body as WebhookEvent<T>)\n\n return new Response(\n JSON.stringify({ success: true, message: 'Webhook processed' }),\n { status: 200, headers: { 'Content-Type': 'application/json' } },\n )\n } catch (error) {\n console.error('Webhook processing error:', error)\n\n return new Response(\n JSON.stringify({ error: 'Internal server error' }),\n { status: 500, headers: { 'Content-Type': 'application/json' } },\n )\n }\n}\n\nexport function createTypedWebhookHandler<T extends Collection>(\n collection: T,\n handler: (event: WebhookEvent<T>) => Promise<void> | void,\n): WebhookHandler<T> {\n return async (event: WebhookEvent<T>) => {\n if (event.collection !== collection) {\n throw new Error(`Expected collection \"${collection}\", got \"${event.collection}\"`)\n }\n return handler(event)\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;AAmBO,SAAS,oBAAoB,MAAqC;AACvE,MAAI,OAAO,SAAS,YAAY,SAAS,KAAM,QAAO;AACtD,QAAM,MAAM;AACZ,SACE,OAAO,IAAI,eAAe,aACzB,IAAI,cAAc,YAAY,IAAI,cAAc,aACjD,OAAO,IAAI,SAAS,YACpB,IAAI,SAAS;AAEjB;AAEA,SAAe,gBACb,SACA,QACA,WACkB;AAAA;AAClB,UAAM,UAAU,IAAI,YAAY;AAChC,UAAM,MAAM,MAAM,OAAO,OAAO;AAAA,MAC9B;AAAA,MACA,QAAQ,OAAO,MAAM;AAAA,MACrB,EAAE,MAAM,QAAQ,MAAM,UAAU;AAAA,MAChC;AAAA,MACA,CAAC,MAAM;AAAA,IACT;AACA,UAAM,MAAM,MAAM,OAAO,OAAO,KAAK,QAAQ,KAAK,QAAQ,OAAO,OAAO,CAAC;AACzE,UAAM,WAAW,MAAM,KAAK,IAAI,WAAW,GAAG,CAAC,EAC5C,IAAI,CAAC,MAAM,EAAE,SAAS,EAAE,EAAE,SAAS,GAAG,GAAG,CAAC,EAC1C,KAAK,EAAE;AAEV,QAAI,SAAS,SAAS,WAAW,UAAU,SAAS,IAAI;AACxD,UAAM,MAAM,KAAK,IAAI,SAAS,QAAQ,UAAU,MAAM;AACtD,aAAS,IAAI,GAAG,IAAI,KAAK,KAAK;AAC5B,iBAAW,SAAS,WAAW,CAAC,KAAK,MAAM,UAAU,WAAW,CAAC,KAAK;AAAA,IACxE;AACA,WAAO,WAAW;AAAA,EACpB;AAAA;AAEA,SAAsB,cACpB,SACA,SACA,SACmB;AAAA;AACnB,QAAI;AACF,YAAM,UAAU,MAAM,QAAQ,KAAK;AAEnC,UAAI,mCAAS,QAAQ;AACnB,cAAM,YAAY,QAAQ,QAAQ,IAAI,qBAAqB,KAAK;AAChE,cAAM,QAAQ,MAAM,gBAAgB,SAAS,QAAQ,QAAQ,SAAS;AACtE,YAAI,CAAC,OAAO;AACV,iBAAO,IAAI;AAAA,YACT,KAAK,UAAU,EAAE,OAAO,4BAA4B,CAAC;AAAA,YACrD,EAAE,QAAQ,KAAK,SAAS,EAAE,gBAAgB,mBAAmB,EAAE;AAAA,UACjE;AAAA,QACF;AAAA,MACF,OAAO;AACL,gBAAQ;AAAA,UACN;AAAA,QAEF;AAAA,MACF;AAEA,YAAM,OAAO,KAAK,MAAM,OAAO;AAE/B,UAAI,CAAC,oBAAoB,IAAI,GAAG;AAC9B,eAAO,IAAI;AAAA,UACT,KAAK,UAAU,EAAE,OAAO,+BAA+B,CAAC;AAAA,UACxD,EAAE,QAAQ,KAAK,SAAS,EAAE,gBAAgB,mBAAmB,EAAE;AAAA,QACjE;AAAA,MACF;AAEA,YAAM,QAAQ,IAAuB;AAErC,aAAO,IAAI;AAAA,QACT,KAAK,UAAU,EAAE,SAAS,MAAM,SAAS,oBAAoB,CAAC;AAAA,QAC9D,EAAE,QAAQ,KAAK,SAAS,EAAE,gBAAgB,mBAAmB,EAAE;AAAA,MACjE;AAAA,IACF,SAAS,OAAO;AACd,cAAQ,MAAM,6BAA6B,KAAK;AAEhD,aAAO,IAAI;AAAA,QACT,KAAK,UAAU,EAAE,OAAO,wBAAwB,CAAC;AAAA,QACjD,EAAE,QAAQ,KAAK,SAAS,EAAE,gBAAgB,mBAAmB,EAAE;AAAA,MACjE;AAAA,IACF;AAAA,EACF;AAAA;AAEO,SAAS,0BACd,YACA,SACmB;AACnB,SAAO,CAAO,UAA2B;AACvC,QAAI,MAAM,eAAe,YAAY;AACnC,YAAM,IAAI,MAAM,wBAAwB,UAAU,WAAW,MAAM,UAAU,GAAG;AAAA,IAClF;AACA,WAAO,QAAQ,KAAK;AAAA,EACtB;AACF;","names":[]}
1
+ {"version":3,"sources":["../src/core/webhook/index.ts"],"sourcesContent":["import type { Collection } from '../client/types'\nimport type { CollectionType } from '../collection/types'\n\nexport type WebhookOperation = 'create' | 'update'\n\nexport interface WebhookEvent<T extends Collection = Collection> {\n collection: T\n operation: WebhookOperation\n data: CollectionType<T>\n}\n\nexport type WebhookHandler<T extends Collection = Collection> = (\n event: WebhookEvent<T>,\n) => Promise<void> | void\n\nexport interface WebhookOptions {\n secret?: string\n}\n\nexport function isValidWebhookEvent(data: unknown): data is WebhookEvent {\n if (typeof data !== 'object' || data === null) return false\n const obj = data as Record<string, unknown>\n return (\n typeof obj.collection === 'string' &&\n (obj.operation === 'create' || obj.operation === 'update') &&\n typeof obj.data === 'object' &&\n obj.data !== null\n )\n}\n\nasync function verifySignature(\n payload: string,\n secret: string,\n signature: string,\n): Promise<boolean> {\n const encoder = new TextEncoder()\n const key = await crypto.subtle.importKey(\n 'raw',\n encoder.encode(secret),\n { name: 'HMAC', hash: 'SHA-256' },\n false,\n ['sign'],\n )\n const sig = await crypto.subtle.sign('HMAC', key, encoder.encode(payload))\n const expected = Array.from(new Uint8Array(sig))\n .map((b) => b.toString(16).padStart(2, '0'))\n .join('')\n // Constant-time comparison to prevent timing attacks\n let result = expected.length !== signature.length ? 1 : 0\n const len = Math.max(expected.length, signature.length)\n for (let i = 0; i < len; i++) {\n result |= (expected.charCodeAt(i) || 0) ^ (signature.charCodeAt(i) || 0)\n }\n return result === 0\n}\n\nexport async function handleWebhook<T extends Collection = Collection>(\n request: Request,\n handler: WebhookHandler<T>,\n options?: WebhookOptions,\n): Promise<Response> {\n try {\n const rawBody = await request.text()\n\n if (options?.secret) {\n const signature = request.headers.get('x-webhook-signature') || ''\n const valid = await verifySignature(rawBody, options.secret, signature)\n if (!valid) {\n return new Response(\n JSON.stringify({ error: 'Invalid webhook signature' }),\n { status: 401, headers: { 'Content-Type': 'application/json' } },\n )\n }\n } else {\n console.warn(\n '[@01.software/sdk] Webhook signature verification is disabled. ' +\n 'Set { secret } in handleWebhook() options to enable HMAC-SHA256 verification.',\n )\n }\n\n const body = JSON.parse(rawBody)\n\n if (!isValidWebhookEvent(body)) {\n return new Response(\n JSON.stringify({ error: 'Invalid webhook event format' }),\n { status: 400, headers: { 'Content-Type': 'application/json' } },\n )\n }\n\n await handler(body as WebhookEvent<T>)\n\n return new Response(\n JSON.stringify({ success: true, message: 'Webhook processed' }),\n { status: 200, headers: { 'Content-Type': 'application/json' } },\n )\n } catch (error) {\n console.error('Webhook processing error:', error)\n\n return new Response(JSON.stringify({ error: 'Internal server error' }), {\n status: 500,\n headers: { 'Content-Type': 'application/json' },\n })\n }\n}\n\nexport function createTypedWebhookHandler<T extends Collection>(\n collection: T,\n handler: (event: WebhookEvent<T>) => Promise<void> | void,\n): WebhookHandler<T> {\n return async (event: WebhookEvent<T>) => {\n if (event.collection !== collection) {\n throw new Error(\n `Expected collection \"${collection}\", got \"${event.collection}\"`,\n )\n }\n return handler(event)\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;AAmBO,SAAS,oBAAoB,MAAqC;AACvE,MAAI,OAAO,SAAS,YAAY,SAAS,KAAM,QAAO;AACtD,QAAM,MAAM;AACZ,SACE,OAAO,IAAI,eAAe,aACzB,IAAI,cAAc,YAAY,IAAI,cAAc,aACjD,OAAO,IAAI,SAAS,YACpB,IAAI,SAAS;AAEjB;AAEA,SAAe,gBACb,SACA,QACA,WACkB;AAAA;AAClB,UAAM,UAAU,IAAI,YAAY;AAChC,UAAM,MAAM,MAAM,OAAO,OAAO;AAAA,MAC9B;AAAA,MACA,QAAQ,OAAO,MAAM;AAAA,MACrB,EAAE,MAAM,QAAQ,MAAM,UAAU;AAAA,MAChC;AAAA,MACA,CAAC,MAAM;AAAA,IACT;AACA,UAAM,MAAM,MAAM,OAAO,OAAO,KAAK,QAAQ,KAAK,QAAQ,OAAO,OAAO,CAAC;AACzE,UAAM,WAAW,MAAM,KAAK,IAAI,WAAW,GAAG,CAAC,EAC5C,IAAI,CAAC,MAAM,EAAE,SAAS,EAAE,EAAE,SAAS,GAAG,GAAG,CAAC,EAC1C,KAAK,EAAE;AAEV,QAAI,SAAS,SAAS,WAAW,UAAU,SAAS,IAAI;AACxD,UAAM,MAAM,KAAK,IAAI,SAAS,QAAQ,UAAU,MAAM;AACtD,aAAS,IAAI,GAAG,IAAI,KAAK,KAAK;AAC5B,iBAAW,SAAS,WAAW,CAAC,KAAK,MAAM,UAAU,WAAW,CAAC,KAAK;AAAA,IACxE;AACA,WAAO,WAAW;AAAA,EACpB;AAAA;AAEA,SAAsB,cACpB,SACA,SACA,SACmB;AAAA;AACnB,QAAI;AACF,YAAM,UAAU,MAAM,QAAQ,KAAK;AAEnC,UAAI,mCAAS,QAAQ;AACnB,cAAM,YAAY,QAAQ,QAAQ,IAAI,qBAAqB,KAAK;AAChE,cAAM,QAAQ,MAAM,gBAAgB,SAAS,QAAQ,QAAQ,SAAS;AACtE,YAAI,CAAC,OAAO;AACV,iBAAO,IAAI;AAAA,YACT,KAAK,UAAU,EAAE,OAAO,4BAA4B,CAAC;AAAA,YACrD,EAAE,QAAQ,KAAK,SAAS,EAAE,gBAAgB,mBAAmB,EAAE;AAAA,UACjE;AAAA,QACF;AAAA,MACF,OAAO;AACL,gBAAQ;AAAA,UACN;AAAA,QAEF;AAAA,MACF;AAEA,YAAM,OAAO,KAAK,MAAM,OAAO;AAE/B,UAAI,CAAC,oBAAoB,IAAI,GAAG;AAC9B,eAAO,IAAI;AAAA,UACT,KAAK,UAAU,EAAE,OAAO,+BAA+B,CAAC;AAAA,UACxD,EAAE,QAAQ,KAAK,SAAS,EAAE,gBAAgB,mBAAmB,EAAE;AAAA,QACjE;AAAA,MACF;AAEA,YAAM,QAAQ,IAAuB;AAErC,aAAO,IAAI;AAAA,QACT,KAAK,UAAU,EAAE,SAAS,MAAM,SAAS,oBAAoB,CAAC;AAAA,QAC9D,EAAE,QAAQ,KAAK,SAAS,EAAE,gBAAgB,mBAAmB,EAAE;AAAA,MACjE;AAAA,IACF,SAAS,OAAO;AACd,cAAQ,MAAM,6BAA6B,KAAK;AAEhD,aAAO,IAAI,SAAS,KAAK,UAAU,EAAE,OAAO,wBAAwB,CAAC,GAAG;AAAA,QACtE,QAAQ;AAAA,QACR,SAAS,EAAE,gBAAgB,mBAAmB;AAAA,MAChD,CAAC;AAAA,IACH;AAAA,EACF;AAAA;AAEO,SAAS,0BACd,YACA,SACmB;AACnB,SAAO,CAAO,UAA2B;AACvC,QAAI,MAAM,eAAe,YAAY;AACnC,YAAM,IAAI;AAAA,QACR,wBAAwB,UAAU,WAAW,MAAM,UAAU;AAAA,MAC/D;AAAA,IACF;AACA,WAAO,QAAQ,KAAK;AAAA,EACtB;AACF;","names":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@01.software/sdk",
3
- "version": "0.2.9-dev.260311.926a6d4",
3
+ "version": "0.2.9-dev.260312.8c43a16",
4
4
  "description": "01.software SDK",
5
5
  "author": "<office@01.works>",
6
6
  "keywords": [],
@@ -39,54 +39,54 @@
39
39
  "default": "./dist/webhook.cjs"
40
40
  }
41
41
  },
42
- "./components/image": {
42
+ "./ui/image": {
43
43
  "import": {
44
- "types": "./dist/components/image.d.ts",
45
- "default": "./dist/components/image.js"
44
+ "types": "./dist/ui/image.d.ts",
45
+ "default": "./dist/ui/image.js"
46
46
  },
47
47
  "require": {
48
- "types": "./dist/components/image.d.cts",
49
- "default": "./dist/components/image.cjs"
48
+ "types": "./dist/ui/image.d.cts",
49
+ "default": "./dist/ui/image.cjs"
50
50
  }
51
51
  },
52
- "./components/form": {
52
+ "./ui/form": {
53
53
  "import": {
54
- "types": "./dist/components/form.d.ts",
55
- "default": "./dist/components/form.js"
54
+ "types": "./dist/ui/form.d.ts",
55
+ "default": "./dist/ui/form.js"
56
56
  },
57
57
  "require": {
58
- "types": "./dist/components/form.d.cts",
59
- "default": "./dist/components/form.cjs"
58
+ "types": "./dist/ui/form.d.cts",
59
+ "default": "./dist/ui/form.cjs"
60
60
  }
61
61
  },
62
- "./components/rich-text": {
62
+ "./ui/rich-text": {
63
63
  "import": {
64
- "types": "./dist/components/rich-text.d.ts",
65
- "default": "./dist/components/rich-text.js"
64
+ "types": "./dist/ui/rich-text.d.ts",
65
+ "default": "./dist/ui/rich-text.js"
66
66
  },
67
67
  "require": {
68
- "types": "./dist/components/rich-text.d.cts",
69
- "default": "./dist/components/rich-text.cjs"
68
+ "types": "./dist/ui/rich-text.d.cts",
69
+ "default": "./dist/ui/rich-text.cjs"
70
70
  }
71
71
  },
72
- "./components/code-block": {
72
+ "./ui/code-block": {
73
73
  "import": {
74
- "types": "./dist/components/code-block.d.ts",
75
- "default": "./dist/components/code-block.js"
74
+ "types": "./dist/ui/code-block.d.ts",
75
+ "default": "./dist/ui/code-block.js"
76
76
  },
77
77
  "require": {
78
- "types": "./dist/components/code-block.d.cts",
79
- "default": "./dist/components/code-block.cjs"
78
+ "types": "./dist/ui/code-block.d.cts",
79
+ "default": "./dist/ui/code-block.cjs"
80
80
  }
81
81
  },
82
- "./components/flow": {
82
+ "./ui/flow": {
83
83
  "import": {
84
- "types": "./dist/components/flow.d.ts",
85
- "default": "./dist/components/flow.js"
84
+ "types": "./dist/ui/flow.d.ts",
85
+ "default": "./dist/ui/flow.js"
86
86
  },
87
87
  "require": {
88
- "types": "./dist/components/flow.d.cts",
89
- "default": "./dist/components/flow.cjs"
88
+ "types": "./dist/ui/flow.d.cts",
89
+ "default": "./dist/ui/flow.cjs"
90
90
  }
91
91
  },
92
92
  "./package.json": "./package.json"
@@ -116,8 +116,8 @@
116
116
  "shadcn": "^3.6.3",
117
117
  "tsup": "^8.3.7",
118
118
  "vitest": "^3.2.3",
119
- "@repo/eslint-config": "0.0.0",
120
- "@repo/typescript-config": "0.0.0"
119
+ "@repo/typescript-config": "0.0.0",
120
+ "@repo/eslint-config": "0.0.0"
121
121
  },
122
122
  "dependencies": {
123
123
  "@payloadcms/richtext-lexical": "3.78.0",
@@ -155,6 +155,7 @@
155
155
  "build": "tsup",
156
156
  "version:dev": "node ../../scripts/update-version.js",
157
157
  "publish:dev": "pnpm run version:dev && pnpm publish --no-git-checks --access public --tag dev",
158
+ "publish:local": "pnpm run version:dev && DEFAULT_API_URL=http://localhost:3000 pnpm publish --no-git-checks --access public --tag local",
158
159
  "version:patch": "pnpm version patch --no-git-tag-version",
159
160
  "version:minor": "pnpm version minor --no-git-tag-version",
160
161
  "version:major": "pnpm version major --no-git-tag-version",
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../src/components/CodeBlock/index.tsx","../../src/components/CodeBlock/highlight.ts"],"sourcesContent":["'use client'\n\nimport React, { useEffect, useState, type JSX } from 'react'\nimport { highlight, type BundledTheme } from './highlight'\n\nexport type { BundledTheme }\nexport { highlight }\n\nexport interface CodeBlockProps {\n /** Code string to highlight */\n code: string\n /** Language identifier (e.g. 'typescript', 'js', 'python') */\n language?: string\n /** Shiki theme name. Default: 'github-dark' */\n theme?: BundledTheme\n /** CSS class for the wrapper */\n className?: string\n /** Pre-rendered JSX from server component via `highlight()` */\n initial?: JSX.Element\n /** Show line numbers. Default: false */\n showLineNumbers?: boolean\n /** Show copy button. Default: true */\n showCopyButton?: boolean\n}\n\n/**\n * Syntax-highlighted code block using shiki.\n *\n * @example Basic usage\n * ```tsx\n * <CodeBlock code=\"const x = 1\" language=\"typescript\" />\n * ```\n *\n * @example With server pre-rendering (Next.js)\n * ```tsx\n * // Server Component\n * const initial = await highlight(code, 'typescript')\n * return <CodeBlock code={code} language=\"typescript\" initial={initial} />\n * ```\n *\n * @example As RichTextContent block renderer\n * ```tsx\n * <RichTextContent\n * data={data}\n * blocks={{\n * Code: ({ node }) => (\n * <CodeBlock code={node.fields.code} language={node.fields.language} />\n * ),\n * }}\n * />\n * ```\n */\nexport function CodeBlock({\n code,\n language = 'typescript',\n theme = 'github-dark',\n className,\n initial,\n showLineNumbers = false,\n showCopyButton = true,\n}: CodeBlockProps) {\n const [nodes, setNodes] = useState<JSX.Element | undefined>(initial)\n const [copied, setCopied] = useState(false)\n\n useEffect(() => {\n let cancelled = false\n void highlight(code, language, theme).then((el) => {\n if (!cancelled) setNodes(el)\n })\n return () => {\n cancelled = true\n }\n }, [code, language, theme])\n\n const handleCopy = () => {\n void navigator.clipboard.writeText(code).then(() => {\n setCopied(true)\n setTimeout(() => setCopied(false), 2000)\n }, () => {})\n }\n\n return (\n <div className={className} style={{ position: 'relative' }}>\n {showCopyButton && (\n <button\n type=\"button\"\n onClick={handleCopy}\n aria-label=\"Copy code\"\n style={{\n position: 'absolute',\n top: 8,\n right: 8,\n zIndex: 1,\n padding: '4px 8px',\n fontSize: 12,\n lineHeight: 1,\n border: '1px solid rgba(255,255,255,0.2)',\n borderRadius: 4,\n background: 'rgba(0,0,0,0.3)',\n color: '#ccc',\n cursor: 'pointer',\n opacity: 0.7,\n transition: 'opacity 0.15s',\n }}\n onMouseEnter={(e) => {\n e.currentTarget.style.opacity = '1'\n }}\n onMouseLeave={(e) => {\n e.currentTarget.style.opacity = '0.7'\n }}\n >\n {copied ? 'Copied!' : 'Copy'}\n </button>\n )}\n {showLineNumbers && nodes ? (\n <div style={{ display: 'flex' }}>\n <div\n aria-hidden\n style={{\n padding: '1em 0.5em 1em 1em',\n textAlign: 'right',\n userSelect: 'none',\n color: 'rgba(255,255,255,0.3)',\n fontFamily: 'monospace',\n fontSize: 13,\n lineHeight: 1.5,\n }}\n >\n {code.split('\\n').map((_, i) => (\n <div key={i}>{i + 1}</div>\n ))}\n </div>\n <div style={{ flex: 1, overflow: 'auto' }}>{nodes}</div>\n </div>\n ) : (\n nodes ?? (\n <pre\n style={{\n margin: 0,\n padding: '1em',\n overflow: 'auto',\n fontFamily: 'monospace',\n fontSize: 13,\n lineHeight: 1.5,\n }}\n >\n <code>{code}</code>\n </pre>\n )\n )}\n </div>\n )\n}\n","import type { JSX } from 'react'\nimport { Fragment } from 'react'\nimport { jsx, jsxs } from 'react/jsx-runtime'\nimport { toJsxRuntime } from 'hast-util-to-jsx-runtime'\nimport { codeToHast, type BundledLanguage, type BundledTheme } from 'shiki'\n\nexport type { BundledLanguage, BundledTheme }\n\n/** Normalize language aliases to shiki-compatible language IDs */\nconst LANGUAGE_ALIASES: Record<string, string> = {\n js: 'javascript',\n ts: 'typescript',\n sh: 'bash',\n shell: 'bash',\n yml: 'yaml',\n py: 'python',\n rb: 'ruby',\n plaintext: 'text',\n}\n\nfunction normalizeLanguage(lang: string): string {\n return LANGUAGE_ALIASES[lang] || lang\n}\n\n/**\n * Highlight code to JSX using shiki.\n * Works in both Server and Client components.\n *\n * @example Server Component\n * ```tsx\n * const highlighted = await highlight('const x = 1', 'typescript')\n * return <div>{highlighted}</div>\n * ```\n */\nexport async function highlight(\n code: string,\n lang: string,\n theme: BundledTheme = 'github-dark',\n): Promise<JSX.Element> {\n const normalized = normalizeLanguage(lang)\n try {\n const hast = await codeToHast(code, {\n lang: normalized as BundledLanguage,\n theme,\n })\n return toJsxRuntime(hast, { Fragment, jsx, jsxs }) as JSX.Element\n } catch {\n // Fallback to plain text if language is not supported\n const hast = await codeToHast(code, { lang: 'text', theme })\n return toJsxRuntime(hast, { Fragment, jsx, jsxs }) as JSX.Element\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA,IAAAA,gBAAqD;;;ACDrD,mBAAyB;AACzB,yBAA0B;AAC1B,sCAA6B;AAC7B,mBAAoE;AAKpE,IAAM,mBAA2C;AAAA,EAC/C,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,OAAO;AAAA,EACP,KAAK;AAAA,EACL,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,WAAW;AACb;AAEA,SAAS,kBAAkB,MAAsB;AAC/C,SAAO,iBAAiB,IAAI,KAAK;AACnC;AAYA,SAAsB,UACpB,MACA,MACA,QAAsB,eACA;AAAA;AACtB,UAAM,aAAa,kBAAkB,IAAI;AACzC,QAAI;AACF,YAAM,OAAO,UAAM,yBAAW,MAAM;AAAA,QAClC,MAAM;AAAA,QACN;AAAA,MACF,CAAC;AACD,iBAAO,8CAAa,MAAM,EAAE,iCAAU,6BAAK,8BAAK,CAAC;AAAA,IACnD,SAAQ;AAEN,YAAM,OAAO,UAAM,yBAAW,MAAM,EAAE,MAAM,QAAQ,MAAM,CAAC;AAC3D,iBAAO,8CAAa,MAAM,EAAE,iCAAU,6BAAK,8BAAK,CAAC;AAAA,IACnD;AAAA,EACF;AAAA;;;ADCO,SAAS,UAAU;AAAA,EACxB;AAAA,EACA,WAAW;AAAA,EACX,QAAQ;AAAA,EACR;AAAA,EACA;AAAA,EACA,kBAAkB;AAAA,EAClB,iBAAiB;AACnB,GAAmB;AACjB,QAAM,CAAC,OAAO,QAAQ,QAAI,wBAAkC,OAAO;AACnE,QAAM,CAAC,QAAQ,SAAS,QAAI,wBAAS,KAAK;AAE1C,+BAAU,MAAM;AACd,QAAI,YAAY;AAChB,SAAK,UAAU,MAAM,UAAU,KAAK,EAAE,KAAK,CAAC,OAAO;AACjD,UAAI,CAAC,UAAW,UAAS,EAAE;AAAA,IAC7B,CAAC;AACD,WAAO,MAAM;AACX,kBAAY;AAAA,IACd;AAAA,EACF,GAAG,CAAC,MAAM,UAAU,KAAK,CAAC;AAE1B,QAAM,aAAa,MAAM;AACvB,SAAK,UAAU,UAAU,UAAU,IAAI,EAAE,KAAK,MAAM;AAClD,gBAAU,IAAI;AACd,iBAAW,MAAM,UAAU,KAAK,GAAG,GAAI;AAAA,IACzC,GAAG,MAAM;AAAA,IAAC,CAAC;AAAA,EACb;AAEA,SACE,8BAAAC,QAAA,cAAC,SAAI,WAAsB,OAAO,EAAE,UAAU,WAAW,KACtD,kBACC,8BAAAA,QAAA;AAAA,IAAC;AAAA;AAAA,MACC,MAAK;AAAA,MACL,SAAS;AAAA,MACT,cAAW;AAAA,MACX,OAAO;AAAA,QACL,UAAU;AAAA,QACV,KAAK;AAAA,QACL,OAAO;AAAA,QACP,QAAQ;AAAA,QACR,SAAS;AAAA,QACT,UAAU;AAAA,QACV,YAAY;AAAA,QACZ,QAAQ;AAAA,QACR,cAAc;AAAA,QACd,YAAY;AAAA,QACZ,OAAO;AAAA,QACP,QAAQ;AAAA,QACR,SAAS;AAAA,QACT,YAAY;AAAA,MACd;AAAA,MACA,cAAc,CAAC,MAAM;AACnB,UAAE,cAAc,MAAM,UAAU;AAAA,MAClC;AAAA,MACA,cAAc,CAAC,MAAM;AACnB,UAAE,cAAc,MAAM,UAAU;AAAA,MAClC;AAAA;AAAA,IAEC,SAAS,YAAY;AAAA,EACxB,GAED,mBAAmB,QAClB,8BAAAA,QAAA,cAAC,SAAI,OAAO,EAAE,SAAS,OAAO,KAC5B,8BAAAA,QAAA;AAAA,IAAC;AAAA;AAAA,MACC,eAAW;AAAA,MACX,OAAO;AAAA,QACL,SAAS;AAAA,QACT,WAAW;AAAA,QACX,YAAY;AAAA,QACZ,OAAO;AAAA,QACP,YAAY;AAAA,QACZ,UAAU;AAAA,QACV,YAAY;AAAA,MACd;AAAA;AAAA,IAEC,KAAK,MAAM,IAAI,EAAE,IAAI,CAAC,GAAG,MACxB,8BAAAA,QAAA,cAAC,SAAI,KAAK,KAAI,IAAI,CAAE,CACrB;AAAA,EACH,GACA,8BAAAA,QAAA,cAAC,SAAI,OAAO,EAAE,MAAM,GAAG,UAAU,OAAO,KAAI,KAAM,CACpD,IAEA,wBACE,8BAAAA,QAAA;AAAA,IAAC;AAAA;AAAA,MACC,OAAO;AAAA,QACL,QAAQ;AAAA,QACR,SAAS;AAAA,QACT,UAAU;AAAA,QACV,YAAY;AAAA,QACZ,UAAU;AAAA,QACV,YAAY;AAAA,MACd;AAAA;AAAA,IAEA,8BAAAA,QAAA,cAAC,cAAM,IAAK;AAAA,EACd,CAGN;AAEJ;","names":["import_react","React"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../src/components/CodeBlock/index.tsx","../../src/components/CodeBlock/highlight.ts"],"sourcesContent":["'use client'\n\nimport React, { useEffect, useState, type JSX } from 'react'\nimport { highlight, type BundledTheme } from './highlight'\n\nexport type { BundledTheme }\nexport { highlight }\n\nexport interface CodeBlockProps {\n /** Code string to highlight */\n code: string\n /** Language identifier (e.g. 'typescript', 'js', 'python') */\n language?: string\n /** Shiki theme name. Default: 'github-dark' */\n theme?: BundledTheme\n /** CSS class for the wrapper */\n className?: string\n /** Pre-rendered JSX from server component via `highlight()` */\n initial?: JSX.Element\n /** Show line numbers. Default: false */\n showLineNumbers?: boolean\n /** Show copy button. Default: true */\n showCopyButton?: boolean\n}\n\n/**\n * Syntax-highlighted code block using shiki.\n *\n * @example Basic usage\n * ```tsx\n * <CodeBlock code=\"const x = 1\" language=\"typescript\" />\n * ```\n *\n * @example With server pre-rendering (Next.js)\n * ```tsx\n * // Server Component\n * const initial = await highlight(code, 'typescript')\n * return <CodeBlock code={code} language=\"typescript\" initial={initial} />\n * ```\n *\n * @example As RichTextContent block renderer\n * ```tsx\n * <RichTextContent\n * data={data}\n * blocks={{\n * Code: ({ node }) => (\n * <CodeBlock code={node.fields.code} language={node.fields.language} />\n * ),\n * }}\n * />\n * ```\n */\nexport function CodeBlock({\n code,\n language = 'typescript',\n theme = 'github-dark',\n className,\n initial,\n showLineNumbers = false,\n showCopyButton = true,\n}: CodeBlockProps) {\n const [nodes, setNodes] = useState<JSX.Element | undefined>(initial)\n const [copied, setCopied] = useState(false)\n\n useEffect(() => {\n let cancelled = false\n void highlight(code, language, theme).then((el) => {\n if (!cancelled) setNodes(el)\n })\n return () => {\n cancelled = true\n }\n }, [code, language, theme])\n\n const handleCopy = () => {\n void navigator.clipboard.writeText(code).then(() => {\n setCopied(true)\n setTimeout(() => setCopied(false), 2000)\n }, () => {})\n }\n\n return (\n <div className={className} style={{ position: 'relative' }}>\n {showCopyButton && (\n <button\n type=\"button\"\n onClick={handleCopy}\n aria-label=\"Copy code\"\n style={{\n position: 'absolute',\n top: 8,\n right: 8,\n zIndex: 1,\n padding: '4px 8px',\n fontSize: 12,\n lineHeight: 1,\n border: '1px solid rgba(255,255,255,0.2)',\n borderRadius: 4,\n background: 'rgba(0,0,0,0.3)',\n color: '#ccc',\n cursor: 'pointer',\n opacity: 0.7,\n transition: 'opacity 0.15s',\n }}\n onMouseEnter={(e) => {\n e.currentTarget.style.opacity = '1'\n }}\n onMouseLeave={(e) => {\n e.currentTarget.style.opacity = '0.7'\n }}\n >\n {copied ? 'Copied!' : 'Copy'}\n </button>\n )}\n {showLineNumbers && nodes ? (\n <div style={{ display: 'flex' }}>\n <div\n aria-hidden\n style={{\n padding: '1em 0.5em 1em 1em',\n textAlign: 'right',\n userSelect: 'none',\n color: 'rgba(255,255,255,0.3)',\n fontFamily: 'monospace',\n fontSize: 13,\n lineHeight: 1.5,\n }}\n >\n {code.split('\\n').map((_, i) => (\n <div key={i}>{i + 1}</div>\n ))}\n </div>\n <div style={{ flex: 1, overflow: 'auto' }}>{nodes}</div>\n </div>\n ) : (\n nodes ?? (\n <pre\n style={{\n margin: 0,\n padding: '1em',\n overflow: 'auto',\n fontFamily: 'monospace',\n fontSize: 13,\n lineHeight: 1.5,\n }}\n >\n <code>{code}</code>\n </pre>\n )\n )}\n </div>\n )\n}\n","import type { JSX } from 'react'\nimport { Fragment } from 'react'\nimport { jsx, jsxs } from 'react/jsx-runtime'\nimport { toJsxRuntime } from 'hast-util-to-jsx-runtime'\nimport { codeToHast, type BundledLanguage, type BundledTheme } from 'shiki'\n\nexport type { BundledLanguage, BundledTheme }\n\n/** Normalize language aliases to shiki-compatible language IDs */\nconst LANGUAGE_ALIASES: Record<string, string> = {\n js: 'javascript',\n ts: 'typescript',\n sh: 'bash',\n shell: 'bash',\n yml: 'yaml',\n py: 'python',\n rb: 'ruby',\n plaintext: 'text',\n}\n\nfunction normalizeLanguage(lang: string): string {\n return LANGUAGE_ALIASES[lang] || lang\n}\n\n/**\n * Highlight code to JSX using shiki.\n * Works in both Server and Client components.\n *\n * @example Server Component\n * ```tsx\n * const highlighted = await highlight('const x = 1', 'typescript')\n * return <div>{highlighted}</div>\n * ```\n */\nexport async function highlight(\n code: string,\n lang: string,\n theme: BundledTheme = 'github-dark',\n): Promise<JSX.Element> {\n const normalized = normalizeLanguage(lang)\n try {\n const hast = await codeToHast(code, {\n lang: normalized as BundledLanguage,\n theme,\n })\n return toJsxRuntime(hast, { Fragment, jsx, jsxs }) as JSX.Element\n } catch {\n // Fallback to plain text if language is not supported\n const hast = await codeToHast(code, { lang: 'text', theme })\n return toJsxRuntime(hast, { Fragment, jsx, jsxs }) as JSX.Element\n }\n}\n"],"mappings":"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","names":[]}