{"version":3,"sources":["../src/images/builder.ts"],"sourcesContent":["import { ContentstackConfigError } from \"../http/errors.js\"\nimport type {\n  ImageFitMode,\n  ImageFormat,\n  ImageOrientation,\n  ImageResizeFilter,\n  ImageTransformBuilder,\n} from \"./types.js\"\n\nconst VALID_FORMATS = new Set<ImageFormat>([\"webp\", \"jpg\", \"png\", \"gif\", \"avif\", \"pjpg\"])\nconst VALID_FITS = new Set<ImageFitMode>([\"bounds\", \"crop\", \"cover\"])\nconst VALID_FILTERS = new Set<ImageResizeFilter>([\n  \"nearest\",\n  \"bilinear\",\n  \"bicubic\",\n  \"lanczos2\",\n  \"lanczos3\",\n])\n\nclass ImageTransformBuilderImpl implements ImageTransformBuilder {\n  constructor(\n    private readonly assetUrl: string,\n    private readonly params: Record<string, string> = {},\n  ) {}\n\n  width(px: number): ImageTransformBuilder {\n    assertPositiveInteger(\"width\", px)\n    return this.with(\"width\", String(px))\n  }\n\n  height(px: number): ImageTransformBuilder {\n    assertPositiveInteger(\"height\", px)\n    return this.with(\"height\", String(px))\n  }\n\n  quality(q: number): ImageTransformBuilder {\n    if (!Number.isInteger(q) || q < 1 || q > 100) {\n      throw new ContentstackConfigError(\"quality() expects an integer between 1 and 100\")\n    }\n    return this.with(\"quality\", String(q))\n  }\n\n  format(fmt: ImageFormat): ImageTransformBuilder {\n    if (!VALID_FORMATS.has(fmt)) {\n      throw new ContentstackConfigError(`Unsupported image format: ${fmt}`)\n    }\n    return this.with(\"format\", fmt)\n  }\n\n  fit(mode: ImageFitMode): ImageTransformBuilder {\n    if (!VALID_FITS.has(mode)) {\n      throw new ContentstackConfigError(`Unsupported fit mode: ${mode}`)\n    }\n    return this.with(\"fit\", mode)\n  }\n\n  crop(params: string): ImageTransformBuilder {\n    return this.withNonEmptyString(\"crop\", params)\n  }\n\n  trim(edges: string): ImageTransformBuilder {\n    return this.withNonEmptyString(\"trim\", edges)\n  }\n\n  orient(angle: ImageOrientation): ImageTransformBuilder {\n    if (!Number.isInteger(angle) || angle < 1 || angle > 8) {\n      throw new ContentstackConfigError(\"orient() expects a value between 1 and 8\")\n    }\n    return this.with(\"orient\", String(angle))\n  }\n\n  overlay(params: Record<string, string>): ImageTransformBuilder {\n    const entries = Object.entries(params)\n      .filter(([, value]) => value.trim().length > 0)\n      .sort(([a], [b]) => a.localeCompare(b))\n\n    if (entries.length === 0) {\n      throw new ContentstackConfigError(\"overlay() requires at least one non-empty key/value pair\")\n    }\n\n    const value = entries.map(([key, val]) => `${key}:${val}`).join(\",\")\n    return this.with(\"overlay\", value)\n  }\n\n  pad(pixels: string): ImageTransformBuilder {\n    return this.withNonEmptyString(\"pad\", pixels)\n  }\n\n  bgColor(hex: string): ImageTransformBuilder {\n    const normalized = hex.trim().replace(/^#/, \"\")\n    if (!/^[0-9a-fA-F]{3}([0-9a-fA-F]{3})?$/.test(normalized)) {\n      throw new ContentstackConfigError(\"bgColor() expects a 3 or 6 character hex value\")\n    }\n    return this.with(\"bg-color\", normalized.toLowerCase())\n  }\n\n  dpr(ratio: number): ImageTransformBuilder {\n    if (!Number.isFinite(ratio) || ratio <= 0) {\n      throw new ContentstackConfigError(\"dpr() expects a positive number\")\n    }\n    return this.with(\"dpr\", String(ratio))\n  }\n\n  disableUpscale(): ImageTransformBuilder {\n    return this.with(\"disable\", \"upscale\")\n  }\n\n  resizeFilter(filter: ImageResizeFilter): ImageTransformBuilder {\n    if (!VALID_FILTERS.has(filter)) {\n      throw new ContentstackConfigError(`Unsupported resize filter: ${filter}`)\n    }\n    return this.with(\"resize-filter\", filter)\n  }\n\n  toURL(): string {\n    if (Object.keys(this.params).length === 0) {\n      return this.assetUrl\n    }\n\n    const query = new URLSearchParams(this.params)\n\n    try {\n      const url = new URL(this.assetUrl)\n      for (const [key, value] of query.entries()) {\n        url.searchParams.set(key, value)\n      }\n      return url.toString()\n    } catch {\n      const separator = this.assetUrl.includes(\"?\") ? \"&\" : \"?\"\n      return `${this.assetUrl}${separator}${query.toString()}`\n    }\n  }\n\n  toSrcSet(widths: number[]): string {\n    return widths\n      .map((width) => {\n        assertPositiveInteger(\"toSrcSet width\", width)\n        return `${this.width(width).toURL()} ${width}w`\n      })\n      .join(\", \")\n  }\n\n  toParams(): Record<string, string> {\n    return { ...this.params }\n  }\n\n  private with(key: string, value: string): ImageTransformBuilder {\n    return new ImageTransformBuilderImpl(this.assetUrl, {\n      ...this.params,\n      [key]: value,\n    })\n  }\n\n  private withNonEmptyString(key: string, value: string): ImageTransformBuilder {\n    if (!value.trim()) {\n      throw new ContentstackConfigError(`${key}() requires a non-empty string value`)\n    }\n    return this.with(key, value)\n  }\n}\n\nexport function imageTransform(assetUrl: string): ImageTransformBuilder {\n  if (!assetUrl.trim()) {\n    throw new ContentstackConfigError(\"imageTransform() requires a non-empty asset URL\")\n  }\n\n  return new ImageTransformBuilderImpl(assetUrl)\n}\n\nfunction assertPositiveInteger(name: string, value: number): void {\n  if (!Number.isInteger(value) || value <= 0) {\n    throw new ContentstackConfigError(`${name} expects a positive integer`)\n  }\n}\n"],"mappings":"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","names":["value"]}