import { ParsedUrlQueryInput } from 'querystring' ; import { addQueryToUrl } from 'url-transformers' ; import { pickBy } from './helpers' ; import { flow } from './helpers/flow' ; import { catMaybesDictionary , mapValueIfDefined } from './helpers/maybe' ; export enum ImgixFit { clamp = 'clamp' , clip = 'clip' , crop = 'crop' , facearea = 'facearea' , fill = 'fill' , fillmax = 'fillmax' , max = 'max' , min = 'min' , scale = 'scale' } export enum ImgixFormat { avif = 'avif' , gif = 'gif' , jp2 = 'jp2' , jpg = 'jpg' , json = 'json' , jxr = 'jxr' , pjpg = 'pjpg' , mp4 = 'mp4' , png = 'png' , png8 = 'png8' , png32 = 'png32' , webm = 'webm' , webp = 'webp' , blurhash = 'blurhash' } export enum ImgixBlendMode { normal = 'normal' , darken = 'darken' , multiply = 'multiply' , burn = 'burn' , lighten = 'lighten' , screen = 'screen' , dodge = 'dodge' , overlay = 'overlay' , softlight = 'softlight' , hardlight = 'hardlight' , difference = 'difference' , exclusion = 'exclusion' , color = 'color' , hue = 'hue' , saturation = 'saturation' , luminosity = 'luminosity' } export type ImgixCrop = Partial < Record < 'top' | 'bottom' | 'left' | 'right' | 'faces' | 'focalpoint' | 'edges' | 'entropy' , boolean > > ; export enum ImgixColorSpace { srgb = 'srgb' , adobergb1998 = 'adobergb1998' , tinysrgb = 'tinysrgb' , strip = 'strip' } export type ImgixAuto = Partial < Record < 'compress' | 'enhance' | 'format' | 'redeye' , boolean > > ; export type ImgixClientHints = Partial < Record < 'width' | 'dpr' | 'saveData' , boolean > > ; export type ImgixAspectRatio = { w : number ; h : number ; } ; export type ImgixRect = { x : number | 'left' | 'center' | 'right' ; y : number | 'top' | 'middle' | 'bottom' ; w : number ; h : number ; } ; type Combinations < T extends string , U extends string = T > = T extends String ? T | `${ T },${ Exclude < U , T > }` : never ; export type ImgixMarkAlignBase = 'top' | 'middle' | 'bottom' | 'left' | 'center' | 'right' ; type ImgixMarkAlign = Combinations < ImgixMarkAlignBase > ; export enum ImgixTxtClip { start = 'start' , middle = 'middle' , end = 'end' , ellipsis = 'ellipsis' } export type ImgixUrlQueryParams = { ar ? : ImgixAspectRatio ; auto ? : ImgixAuto ; q ? : number ; h ? : number ; w ? : number ; rect ? : ImgixRect ; fit ? : ImgixFit ; dpr ? : number ; crop ? : ImgixCrop ; bg ? : string ; ch ? : ImgixClientHints ; blur ? : number ; cs ? : ImgixColorSpace ; faceindex ? : number ; facepad ? : number ; 'min-h' ? : number ; 'mark-w' ? : number ; 'mark-align' ? : ImgixMarkAlign ; 'mark-pad' ? : number ; 'mark-y' ? : number ; mark64 ? : string ; mark ? : string ; 'mark-x' ? : number ; blend64 ? : string ; blend ? : string ; txt64 ? : string ; txt ? : string ; 'txt-color' ? : string ; 'txt-size' ? : number ; 'txt-align' ? : ImgixMarkAlign ; 'txt-font' ? : string ; 'txt-pad' ? : number ; 'txt-width' ? : number ; 'txt-clip' ? : ImgixTxtClip ; 'blend-align' ? : ImgixMarkAlign ; 'blend-mode' ? : ImgixBlendMode ; 'blend-pad' ? : number ; 'blend-alpha' ? : number ; mask ? : string ; 'blend-w' ? : number ; 'blend-x' ? : number ; fm ? : ImgixFormat ; } ; type KebabToCamelCase < S extends string > = S extends `${ infer T }-${ infer U }` ? `${ T }${ Capitalize < KebabToCamelCase < U > > }` : S ; export type QueryParamsInput = { [ K in keyof ImgixUrlQueryParams as KebabToCamelCase < K > ] : ImgixUrlQueryParams [ K ] ; } ; const pickTrueInObject = < K extends string > ( obj ) : Partial < Record < K , true > > => pickBy ( obj , ( _key , value ) : value is true => value ) ; const pickTrueObjectKeys = flow ( pickTrueInObject , Object . keys ) ; const undefinedIfEmptyString = ( str ) : string | undefined => ( str === '' ? undefined : str ) ; const joinWithComma = ( strs ) => strs . join ( ',' ) ; const serializeImgixUrlQueryParamListValue = flow ( pickTrueObjectKeys , joinWithComma , undefinedIfEmptyString ) ; const mapToSerializedListValueIfDefined = mapValueIfDefined ( serializeImgixUrlQueryParamListValue ) ; const serializeImgixUrlQueryParamValues = ( query ) : ParsedUrlQueryInput => { const imgixUrlQueryParams = { ar : mapValueIfDefined ( ( ar ) => `${ ar . w }:${ ar . h }` ) ( query . ar ) , dpr : query . dpr , auto : mapToSerializedListValueIfDefined ( query . auto ) , fit : query . fit , w : query . w , h : query . h , rect : mapValueIfDefined ( ( rect ) => `${ rect . x },${ rect . y },${ rect . w },${ rect . h }` ) ( query . rect ) , q : query . q , cs : query . cs , crop : mapToSerializedListValueIfDefined ( query . crop ) , bg : query . bg , ch : mapToSerializedListValueIfDefined ( query . ch ) , blur : query . blur , faceindex : query . faceindex , facepad : query . facepad , 'min-h' : query . minH , 'mark-w' : query . markW , 'mark-align' : query . markAlign , 'mark-pad' : query . markPad , 'mark-y' : query . markY , mark64 : query . mark64 , blend64 : query . blend64 , txt64 : query . txt64 , 'txt-color' : query . txtColor , 'txt-size' : query . txtSize , 'txt-align' : query . txtAlign , 'txt-pad' : query . txtPad , 'txt-width' : query . txtWidth , 'txt-clip' : query . txtClip , fm : query . fm , 'txt-font' : query . txtFont , 'blend-mode' : query . blendMode , 'blend-alpha' : query . blendAlpha , 'blend-pad' : query . blendPad , 'blend-w' : query . blendW , mask : query . mask , 'blend-align' : query . blendAlign , 'blend-x' : query . blendX , 'mark-x' : query . markX , mark : query . mark , blend : query . blend , txt : query . txt , } ; return catMaybesDictionary ( imgixUrlQueryParams ) ; } ; export const buildImgixUrl = ( url ) => flow ( serializeImgixUrlQueryParamValues , ( query ) => addQueryToUrl ( query ) ( url ) ) ;