From ccc0464fcfd6b2b9992fc6f0c0d59b62ba3c0b69 Mon Sep 17 00:00:00 2001 From: Paolo Mosconi Date: Tue, 22 Apr 2025 15:16:34 +0200 Subject: [PATCH] Remove lodash-es dependency by locally implementing the case functions used by cache key --- bun.lockb | Bin 224681 -> 223924 bytes package.json | 2 - src/cacheKey.ts | 16 +---- src/index.ts | 2 +- src/keyCases.ts | 131 ++++++++++++++++++++++++++++++++++++ src/types.ts | 2 +- test/unit/key-cases.test.ts | 126 ++++++++++++++++++++++++++++++++++ 7 files changed, 260 insertions(+), 19 deletions(-) create mode 100644 src/keyCases.ts create mode 100644 test/unit/key-cases.test.ts diff --git a/bun.lockb b/bun.lockb index 9e5f9c367945ad3ee858d36a72f10570a3dd9c56..a8f78ec984a754854752cc7ff73bee75540f89a2 100755 GIT binary patch delta 36889 zcmeIb33yG{*FS#G;gTC736Y3|m|{+3KoTL>SR&@3F*Jw>f=DDW#FUsysG{h#OmJUx%kU3;y)_TFo+z4ma= zJ#jW)bld%@+x*}<5hX5_$$k{xXMDh#H!69*dT3rwQ?F|klM9Yqe6Q`1_+9Zeh845% zidhgJkn>)IZZh)2+h)tXhNK7R1<+EUXF**-^EI2z0Xi@vF)2CIW(!6^%CkVrfW8OH z{FJmYi6e$5XD>%9Uf}0}mIj@s=qS*#;0J=bFL>-1)eQ+Y*aFlO^c^(F3iqmpvoc4g zBWW8{QZ~>B)HKNGss(6`jZvCUY|sXQh!GsMOQ^LH_#>eHpc_Cdg61iCI;b!BZlIMx zgF$QLAW;U1DxmkE&5YBa)j_v_Rs($rGypVJ(axaM3kPLGUP}HDwUfULiYjvlXC{wH z9+{PS7Ca4&M8_DNfuL||?sPPgL)ZAJ9uG@H$41(0$(aL3r;He6Yg<$HydfwHQ~_m} zmr?TH0ww<~D4dsj4wQO_LFutADu0p6pQ89-p!9f;K-=?X!4?p(V31Pq17!sz6@R~m zY~Ttg^$I{aRC_>a&`Om*NAcOlzT&k)-Ow$DW>~Q7|0WC`Lo+)uV@M{_qeJ9G84Su$ z?qhh`8+7d-CQH2sO6R0=j^R20o^d!j+-Aeb=O$-lq-6vpkE_&B#_LYxGj0c`j2sk% zc(|zKHH-!JS~;x{I9LVb{;%!8=9CIG%GRGE zrF9v}iGzaDhYwj3CHrVu8Pi1eElARw+$Tt|JC{Mtph5wT*&op|Xr?!nF8vME1M*v- zbjmnT2F=L^l21c9M)@@uzz(DbWh4(8os?{YVGOeSN-s4rV|el)n{A7eLxySgpFLiU z4EnQ53u#yqD5EwxHEmeRh?Ife;F(_nlm-c<|6WVk@NDpG&>GD?Fo1?8jYt`t!qIId zXH9xyMrLy9MwquufTkENO8PXJjN(+k-9|e22JEJP&MW)(J|{!X>i5vJwBbRSS%VHV zFlLvmoHMzdbVp3Av?fH+Kv0gCCn(1|B{MN2BQe{SGID5gMoLzu9db7NXIt5;UU9P7 z%=8f{S%{#UkTbF`g3`Tj!W?>GJt%v7w}V-KPHwx7vfvz0Dn^3RP2WI)4Gc~hGCBi$ z*YZx%kmPa6Nr`aF;?B~*X`q}+<3Syurgwr;Ge?4Fc`Kl-{UBNC^)~Y{o*j^&MV5tK zyUBSG3b{FsBgX_KrPyrEx=T-423QSS<*f$ag&rHW>a!Y58=0JylA3HwO-W5j3K~3e zSp#%{idLw1H$ojgIi;SL#jQo|<#=gcrCzdsI`Y}iIVkQ9dJA%z{}m_)%$lGBkzWV= znm$r~3)J*yMp`Py$7Y!~6LNMlH92i8#5uMRO3)dU6Qpc{9Jw@5Has>hW6;=)#B^(W z8LZ^oSW{Cnv+Uq$P${n{7Vitj`HU87W!Gsp;8h z-*$0;te`H2nW1Mb5f-Il(4drz#n9u(=izj~$kCHzL$CuKvDrF#=NkUOuN+x0k^te&AluyncRQ!m4oF#P8}g@?+JNX$gOT12T$`a zp;t89THs!ToMt~7Da+pjr9bB=dA6!&h@u>y@gq{|4$MeN%}7L}+3C`6$s=(JNEtaK zXO#5Ur=X0KNaJcLpV&Llq?wtS8Kzr1W=gFmO6~+t@7Du0H-^Nd#H69gwwqbfteDZ# z88eL*rEBH<364gm2c;&WdE0qt(HX(0jV}8be&U!_Mr{nD-s4p3X-UH&vfTqu+r9&( z-neW@hh+{#_i?~g@^-3RBq-}oM`Lh~YwiLxL~~mi_e%$8!G@=sGso(pZE8i0I?0ie6T}<)+A96`v-(g8)k%pO`V| zH1gT2gNh!QF89J0W=Or&;5nz$6O+=i;L(s5rPn5c(#x4CLo&0{GLl=&WIb2|-H@PH z9z%f@`+=_j`T`o@Fl3D$95f96KRQeDjyxHY;i}whG{}Qc7AR-L08j=)M^FxTG$>;_ z7?kymnj`g-GBcAi{V@-#A%o+364o+^eZiBSHEx!vm9rgYaILep-f7@zZc<86%E-ZK zwlT`g6h*s$vbNTWMuD>5)fM#xW%Rf!nh3`Z#A;(#{O>9X?@Jn%dtC`GD>~p6IbefQ z2BQf40y)ja+Ln|uD8ts*IO-k{nm0i9HW!q+gEMi=%F0Omd7(6KSZ3PD!6_q>J+K1O zd$kNtkAR#P7R%hFLYAHl%Fd4grB9PU>Ctnt8i;9-IU+HWt4)uk%9bG`F~l}o zoZ?fHGlnE%<&R$`odH|TZ&t3$r8C+>Zbsug2-v`NPq99}8 z&5BG-N7xmanu-V*^}X}&Hg*rAYFVEq^)^eRJU}@Yf88XP_b)*?wcc0s4NxEO%Rs$B zr*ASc%09pAY}q9xTwZthyVnh_d}h~B-`cLbR#mU9>A%>FlQm+rW`-lssZB6q@p;6^ z3v}wgX~xOG7%kFp)O0$g>NZU)Fis=0zEM!esf{)qb)EX<5=Q&FG1|*U9+(p)jgw&PhNGTSa~iSroQ^aX zn=KLz*o*~%5&DNN#>sjyT6@D$->EG(V(UBga}Hy6{TQu^QBdFM7>03cY#Ik`ZIuxl zh;AE9uYeu?&;h1S=+x0O4s94N67ZRaOGh)M> zj^j$^Vrt|eq@NC}<3n)xhLc;u?5Y#9g2FWl*P6O!l6`e?lirV%@jn!r7$ zxZ(yKvj7}>rn4sfayjEx+Rg<_1PP z+9M?cXhHo5L|s9Y)BXr^wy$wID%#$|-)8G=rnVu~)9Bd5smYuKEIQrIoHvk4FjH=o z`NfRo#vqkwranhX<~9tl*@l?1_3n{7hv6MwO zEnW@FIg2``A;l;|a0W&=_JfO-9jzasKd5H7I%6D-tJ`dyAe0d@7o3W(K9Me9=rDK@ z&M#I2lN_83=9WfmbEmy`O$?;bv3az81yawMsc(>KXQt}avU1aqlCpfHI+(e|YFi~@ zk&?B{MM~;@ij>r=TE~*5Al1n%n~#*LrS8*OkdkE=ASLVj^r@^;J*z|tQqs~LNVPZX zdxVrM+oHauHy0^o3sPo%4&R`s>r8lrqcb>q7ZU`5Gm{(xN0rM z#}SvBbHVijXD&VZwQ%EPT#UUoVj#wF!*V{@i0$CCuLs}QZ00-WKwYkc4H`*KR-6h> z1)?*;z8)OP1VuY8BE^272^iysHJr=1tRWuBE;0|^*a(iASbwkvUkAr7p~n#sj(QQ6 zZ&*tbINE`h;pf#xUT3G{8^}~B*NJchz!Yl8ZVm&-z{awL_2)HkZNZhIMfx9+#>p-* zj)*APfWvh64scu;Z06E-9~`TeYhY)%mII2Vtww~l)NpijI$SX6)FOtRwxy8=*(S(( zKo84Yy$G#>;ppykEJZclAS=dJG*=@JvhK~SkYGobg5xqOgW$Z%D`|8cjpe+D(=i^s zqFbap4}qi86G=N(+Hjwo9mwkhj&)+E0{03y)@i!V zeiB?$!>vxVqYfgKeUw8t8C*Yb(vC~uSO$6RBOG2ZLJb85vI{urn{!xXXB)A-oc2$s zVRVd$)@m9By_}APt!y@gVy*`*(BE%mwC^3`aDh#X2Xvr&grf<#!QkX7whA0aRC1pv z4yPWt)y2r`<8;Kfk)?5d!FDl0afl}Dblbq8U#uC?^bj08hpxaGdgJGelQmg46L_yQf}h5MiGSE{v;(cGxID zZU?Lsssy|=zmUUp{{$ROlACE+gd3-cxiLEig5wmDo?ik^c^*zW3yvMrjC0rxJmRpv zNlnz52#(``xNV3{7#tlaYdHgsaVfc~9iCbS_auYkXi8VF28Y1|N7wxZPP&d<*N(CU zI2qgTQgG(t=(voOvI9L0ghOc~;tP{L8610q+Tr{iop?IcpMWIAI97L-wIixv|Ciw8 zSg@@iIE1}%m@zv9+|!tKtOUmvQ0IV17cev!QyC*)wQEtu-r!_ta*Z{>Ny9kUAA@5# zc~UA5@6ZW2zJ*5`v4fqCy^x@4wZgb`m(#1187LjVF;L)6bodo;jAIvL!IDTSvKMlW zR>lIsMi988B3;0+eHo*x6ep+KSK!#b+ztGDO1otx&x4aLq+?zJSLlj&!Eu0KH}ZU* zm$e|QFhJ?x2Ab!fuaII5GR(c>t&pNuI)S5ASSsMZ<%*N*>P2ugUmmk-_Oh&^{{|=y z_M@$3;GW}7X@7`ROQsx6dOr7bNks*#7!^+rLu)A1GB7-Uu8=+a+WCWmV&xJcy5p*#n! zAvl?5A0XW%=b957j{v33eP=T`hKgL5Z-AqF%)44x48uaEN>kIR4I#hBOfw4O*fazyWm*8jOK_DxPt=D)touY!ST$1?Gu6bH8>hC zx5%ccrhzr1?X!>yHrsv+srJy2TZL_;96C8TUBJbQN54aPR_l%BmUG;*ZeLl8u5Kr(*?Va(!U$KL$t7lrg;)pDE{; z^vo=9tXa;TcQcKXK{1XpSyq)?@wvI!u9CtG^ z>{G$T7^m^=@CZ_@PL9ma;5Zg?42O+-I=g zn$;X5vLiU@dCxdAOD=89I*%;2CeI!Zr^}5-)<0xM(Vnjd_q^2X8tDS25g0FXk!t#) ztVC}8Gr_T|avwboj%~{-yUr|X*F11?Txd#x%9ENUXGy1E9>zsDdV(vgWiGhF+4mv1 zXtM>np>m##1MGmwkuG4^fUI&YIQBrUx{tv104K+%<7~N9n0fXU;5r$n8%8^BA;k>} zUy>ptUFOK@WRY3mSX~KoF}ndy+Qh#2za%{(*M}FtJvGC=m>eVDei);S6sXN7qjbL6-*9YnI(~zUmCAi0 zWQCltG6eX03>_!u+g@-qR66@daNWV-`y0$ocufwOoVCSQ%32UC^&%WSz|likF2KD8 zj=_Q*B|XA%4_pUu-sVs@T_sl;gz5%t7~q^{3*2%)2gjkoaSjv3ceTuOG0r(7UBI+K zmb`ng!f*z^+ukXxy*hBE(#nL-Hj2NpAoy&sl8z2 zZFSnWuEi2)xOIZ^zyC_40gfPJDYG zaOV9z`zuH_Hcr=!cAP*;#RU5C8#u<2IgRb@HlUB@u09(nE*S_t+{!<>!I=F9?x$>& z10ZKYOK`MF#>O~s94hRDqa&%vX(1QrpTW_`7#kc2V-3ffPJ6q}ygBXmX0&}ZQa#Po z1Eji|skX1<84NSESf!d4N1~%C3fqD~GE9PQ6IYqrdd67DRN@Q@6Qm--@T>n7Jnu-BZkIyUGY{sX%19Dg;=9_tu(j0isyhvF+ z&MD?aS`xslGq0kw7$hwK>bF!BtGszViC0RXQ70Od&lucDNCg8w)w@LM=C}j*_X)!NSPWShL zlE8-mufJ0Gzo>vga?Vtfl>8?EEB*{94qO0u6{XC-WJ)EaftM9ulu~{Lp#E0?pKmY| z%(x0@#@u~ARgtiL1F-q;0Ono?c#&$x@qGbi=zI^3TDJjSq>P6j$>1Vo{x4*3k&=H% z23Ju^`R@RYd#vaaP+mnT^EFLPU7fb!`X}mwd{?DM$_h$@Qsk!Or1Y+*l9yHTzo+Ow zEAmo`q+Fybf|dlWs^p~XSq)H%0+sw(l=an8`J_zNR(w%Py}IVo$%Im@rxZzPNT}jT zSs+~Tq%^RJ;z^l|R{Vd5vc8;Vs$h(wPF2CPC=0YeK4~kZ-&*NEi!!T?$|o%izN_LD zZEOlC>!vbD*+37)Ka(1x57aVtAMoIl`nE)+S(H*VP|2S~nU$pSNg3`#K^Z+Gl$?~w zRK=6hvNXkm%AF@&35rrGW+*u+lbMPqEd_ouDD`rcoRs`j#gj5QP4Pu34W6YTe3_W5 z6#k!37I_&TY;Zm(`33y=4_XHNO33M%wMuWDqU){jU9Sojr4((z2j|UZP&Twh=@q3E zZB_E3lnuV2xWjyu; zWoP?=;-77RPGYP$;)8(2#010QNh&*8(IKF`ic*@D3b`xjSWuQ52TJ*5#pi(HpKS_1 z{+YHnE10SjN$HoDLFwFAKxw~F`9&%9)Mj{2}=+h(O*lv3+;B`-=T+N$KF zjLlu3)ZeY-q~!M~p0qmnFF+}}fDh(h)Up21+^- z3LYz-l*uRfpq`Eo^2Nz0%6eQCPs;q##mwPkf@*)IY`{$^x~u$WQFg#fSO1iol$O4v=*y-8zEr6EqLdZPSMs8i@&!sx%H%?PaF+1T zNqH5e-2ZH^sti(AumY50w;GfNtp&wD+XjC82c_QYN^dJDw}w5StmiGIPf9*t@ucMU zf|~RHZ6(;R6iBIX0F)ITSMs8i@(-1~C}p`bN?w#wepbngP&xlUMFyksvQqe;Phq|D$29nD#p#-rT)E{^6$-*|HYdvTvB+= zmgN5x<%0RFn<%W3@_%opa78bA&xD?lJp5lYgG<^u=HenH|L@HdIN=Gvi4YLTS^mA5 z0+0NAGo?A!2%bRxy_v$BE&tw3VJ!Ur@n%XV^Tyf#+Rc<**KU7_qkq@YzZ-E{ zkkR`F`ga5U1J}TC+(iFwqJKBzv`}LoxV_*ieIJKEgh=@w{revM1J}s#y@meWLjP{X zX%R*NxD()leu&eejO-uKzaP*)aM4Dc+vwkI^zU{Y{*3)RxG%spyAy}Mp3J+0{@p?U zz_l=sQPQX*4xO&XCLDnKKmMV9>(LTuPOLUFwWz% zpAq^fUh8k<;d6j-6`zSl)Nkn3Z|K!;aaxjb^S5|ykkR7zcsygj6rY2Q`}iDU#QqVl z4K-HdGsSrH2m12|`tvwW8*XfVjQ%`EfBuZaAENaB6aD!U{Q;L|IG)67=|&@{yf{ZPLDVS*GEqz+nIz7W zOctTVL2^VMNv^m`GDSq$L8giYB-6xAlIfyF36L3LDaniCKFLfGTT+V`?MiBHVp~Zq zPRkRID0oOgf(rz5#AX)=Hn~9H=736wDJ2R|s5OAxL$FV1d|2!Cnd~ zm4d(!DWxD7S_*>G6f6?Hr6H(L8iGlsArPW~f)f-3xk0d0WV=By&JBXg6f75Y%0N)N z3NT>{r zQ(|*v2sTxQz%2lR)1r3(1ibP)kTX%$hxr*y6YD~5Gd|buw)SgJr_ezORQcDLA%8e*aZZ2L{|a9Lkjj# zP)}$}AlM`zNL~U#kl0B8Bm!%LKryx{#E`wk%1*4Zi5H5~VFmxFN zfy*IiBt|XABy21SNFqelS3x30Hc6B?N76*pSpgC)rjRrh=SiC7hrXu$q>0E?T77L$ ze)1~(7oPTE`03h1oI9w+yVY|ue__jQ1nQBmy`}xC<;FDm-xoiOu#S4v z4YmH~GgAzscsR2D7c~C_`JdKMHhRbi{Qoz@GRNgV-lN^sT`fO+G%WwmJ=$Wk4Ke?1 zG;BJH4d+N-pA#lwf?iU{90sJWDXaf1BMc3A(@`o!sjT9S5GgdWnOwWax~hcFuD zPfx>-x5~OJ)8&7)b6V^?f^C~_xBl;^)ArsA_GywV*Dp$sr~4fM*c{sfrN~C#1b97EioCQiY+ftUm<*EvoL3){z@hKM;=8t(R zl*~=Z_|V`9x&oKGD$5`C_CZFmhm!HPz2OkhL!PQEpO7BO-`;tZQ$jDKvy`m7DqJ42 zL8@UsGQ*@dFj&cal*|XR=OLpf`NWJ#k?sH)JsAKQ{_($xwb@nKoT^G#5keOwtPUBI zegJQnH##uM&7RLih4f8~ih$=RTzBtD|HAkbkXY^<>!`TNMc3QNsEV z(nVE)-AWcB6>ZfZdsE3mA)}M31J{(Sq0*}X*&TpG*ht9&k?sg^xEd>2O{AxrzkMSS zp@g-N?uQELN=_KoT^s17WKl|12Qn|n=*lLL;h(K8P=N(-nNJLX)&qQ%UNfavAF^)& zde_O{zF8&+_!QvPT*(;GXG{s67*w(b;6GHdmP!@^zO9nAQnFC+pCHYvwUULYG-Yj+ zEGHaHJ1~6y{y9*(wIQ$*X-NCLHkKaR|D;$WY{Qd z6P2v1lHpG?Y#aG&3okw@MK9pbP;8r+z-2ui6^%3>nd8+%>ERDe%%?{=3_X>s8Pa?# zo*v>OR4l@${Cfbr;vr+_usfO0)>76-NBdN44lqi2@wqF?S^(3KX3t*$Wp+zowvzF= zEb6rak^majU&&f48I2mCWNnbfc4r!usASKv|GfcT1C@|t*$1HYNlMlZ>AnE3K}r^j z^eUujD4+hKG3|kQNVfzXtYmRW(=)7tPlZvh13;s_nK@JmBh}t;sjavZt5*||&Gn|; zxbR;9J_o)4E&=>{e-Stjd!+cP#?H>T|0Vjb|0G~i9 z08RsZe1&&uwgKCL9RQy$8UhS0hUiW~VkD3TqywXXOn__rXka`HNCLRNCj(s5lpxPM|qZ52z0W0l`26AOzs!&vgJDCk-Zx=3l9PdKU>q<5m;lTK7`nN@L|_sy4VVf{2WA0zz<6K^ z@FFl4zyZtr(-5u_kz!OU-6w~O4Yy1lBCY^m0Ph1lX#4=&2F?TD0iOc_E907O$`4~6>6aXiIQ^32x2f$~*CtQF|Bk?(K6*vwY1-=H}0k{d>1HJ^V z1DAkrfRBJ1z_-9Y-~hnW(lOvNum`vUyaikUxN&_5+yveO?gMWF*SG;~MPfU!1Go)O z+y~Ypy$VO_;HLr8ff)cF>{YFC1O@^*8TiNqvVal5NFWtx3vd~22RsLGHFN^a0UoD5M{l^peGI$@ zyaOBn&Hx_(dx4LDQ@}akD8L7q`JCpT0C!64j5+2Gw;c?3y#DY;U*LJ59S{NV01^i9 zfWdPD&j8(Ez(`P@`6>g|0DtKEkpjB_9>IKpaX>aO9^hG$PqO}m@*7~xMvgysytP1Q z2ww)B2fPI20ds&AsCYRr4VVth0A2)gk(UPif^rXlOF%2|;XosxF%SVn0#Se`a2-0A zfiHmbz-Z3mG@vKY184!11HOQjrO}8xP!=c&{t3_l;Qs$RbOu2F6Vg8e4}gb2AAn~& z?xv*yo|L;o_eIc}z_RD9wUxxfDWZZhW)oww02e1n`0xUq|uK)(;KhNsJ0G`jsL6{DV z0-guj0kJ?F&;jTKbOv}T{s?FUSo(jbyAAqxpm!HoiS%lqBhq~0F`eVj#`vR0E-)4t z34R#R2j~y<26!m#1-t+Z0J;I)0rLN zn#2R>1Yjbt1$czQoq*Y>FcBCC1OhdI8h{^A8Tbx5p9B2?9xmDgc$V76Q*K9qXTPq% zACS)iJmCz2j2H&c zh-836;MA=Ga2n5ro;Oe)@DeTB>$U8h3uVQq z_PSq3S0qaV+^zVfc@8KyNN#rA5P8tBRxhq(v@8YSw4zJ>0Y9Ju;3Hae!1<&ilD+_| z<8h9Q9ZxtlfB=B!kV-%`pgK?ms0xq|1sH!}Km(u_P!p&F)CPiq`aoTv9uNeu48Jaf z0}bIP^Y3FDgJ}&!11*6lpal>KaMh)pvL=c)18oX8f#yJ4faO`Xm7-j++W-voIG{by zLD9~jToStS8)_FMx{3R7dS^SApy8%pM6V9|3vOxPd5Cxk7%2{R&;v9Nak+zDE9Vj< z?*hkwV!%7VQD6r^k8cOI0gHf_frWqpyaKQ{3xN5+Jb=Aq?9*xatN>O4Yk<|jT3{Wp0eBtQq|%!~xd3eiXxI^8C-4Sv7}yK!Qv92sdw|`F z&j)=A7y+>CAz&Zcw;e>{ZQuZ~U!_SoxEBD9!+GE=@F8#lI1bQj?*s2CdK&Zt;1o~* zoCN5JGr$)Br+5JH8Sn{k4p`V6A0GpjJ3m7DS?>H4at06^y9jsySAY<4w3D8Od#s_I zF{ZUe*Uoyly$&*Ji@eTy12=jAZnk-Am!MfJwu{g% zdUPPAw~_k;z-9Y6fUb@KrTe%O&J_!~=xuv?g5_e$tsoHTbD&(QxtiYs=sa%9Tu8qM z&H}7rH0Y-QPlKW0xmkAsz5~KUP*=Ty_L@lOs?Y06?R@~3ZtfXuB@F1Q(qAIo9_fw% zYoLAtD6I-Xn#(=q@c>U@+eNc(dO%gGv8Yvq+Y)6o)Qko(shjRsmA3H=HyGdsLUqc9 zfYOpsv9Ft65BI3Aq0&msNktAZ1>n(wTC^inRPC-eNTdoYn*i`z3waA{-#V>u<6yCA zppFcYBM$~URl*wD_aT9~-nQ;%?CZ_=Q51PBv>&+DC`F#37Dl`m^z zz_6y102}2oV!Jr^yzYbAZa%L!uyf8uiAwPZpY5V!JVqu=WXJ2Z+~|wDP$ym!+v0V< zI&6!_sy`r_1JL6S07m~Wpg#jY0dvKD*7v5U+Dp&RVJXfYYH`h+3k0B+sz7yshqD?$ zAi%wlM_xM4YOOAK9_m=OHYm&UXxsq!5oyj}?$Pcj!!sDqX*>u9LmsMQldvkh0|i#Z z3V1Au26zvR=jup+XKdc2NN^MuZIRPQ_tiFurG4~pZLc^@?j3O* zoZneg=!#OeQr}(P>w4Eyx-1oe6;*WZ3%zS1r7ue5ixuGf*jcJK`{~HelOBzRLOmiF z&Eu<#I7jvO#4YNzfX8UedEf9*SI4}z(1RBBx`}`n^p4sf+ylXu|Eg`{S^yeUK;SLy6ciHy&>&B0mVAdZNjCC$mTxR_<#IOBKPuJ^jx~_kJ z-M3LbhLxpy4*228Z}Sr$c%iFRCQhut$cfQqa))UAIoZcz6!@41=HhtOx%JL|gTeYU-FulBCUVFE7`xK2 z;ju%!IY1Bdw_Y=Mq+(!+{rv}gg#vUxTHal1aiU(KvGv}%86Gc;7%^RY)ohFLX0zUZ z=UcYyh#uA5KT$Q5>pbUCZBl#xFlohc(iR_oryLTocc*MYjPe!*Rg7>Ek3m*Bnj`YX4*%YQTj6-J^$ zSeq$ULa~v03tsNy5!xH+)mmSGLL=FoY6wOT*z)kV2}9rMwQ#+zm4d_vk}z=_Mg6*h zMfZ6ocHoJIQiF6~f9pMd=X$+Fu=}x-Eej2n$A1hHy`Y-W-vTtou|7v03l? z8xWgRs#;!8`drOmQ^nWMdhws9?{QJ#Y~*K9P+>4uEJ#KeOc%#N^s~O=w`4s`zw9f5 z2g82r{d;?!{P3e|#gl=>wT8iASZw$$C2=rJ2p1DT{H*u)mB{*N(1;Iz(hK!c#SSPm zwqE!bd2d4JG9EL}6)IS-1e`PP@vHgOJ-;u^IbBiwNh7S62!7Wh(B+p_t=}!wC?i6L zz=&WG2jXYFg|Nq!!>echJf&ixUb@JELSyT-g_Xv4)~-$bG`CQ}da>cuxRt|iZFcQY zm~+HWd^iL~Sg%5ym9f0m>z#iUe)}!7+sVesg*gQ^#1BLD3jSA6c{zl6NXupY^GmqH zzgFeKzibJFuy-|jZBP{Vp9qY?c>^BTOw%g}uT;IFe!qbTNyP$oR@8eNb=yQzDtckPHSyhxMwzV%y(0>ZG&fc* z?AKEDzS#lvw!Lo6Q&>#cV~?nv44=?CQwd81?)de;c&PH~0`)@w<7e*8m? z@o65tp`aEExkTDwp{%xoXq=`G)%uH-X|QakxW7~PDrs(A2g1ZBY3S>FVZtR{55vP| z(dk$*tv5?P7`b?=m+OY=sG9pZD!kZGq*JkmSeuS*ww1UKeI4s)=~0+{*6W_y97{?% zUF)X|lxq|m&dDVeMXynMMStu4ssl&WXx6-xdnB|%gQKYRaXInwD426CQoKX@Q>5sZ z0iUJ`_YAI1I8fkJm-~D7e!l0g%)WwxjpgoPy^(Kdqy8Hj)W5w5Io$40rB%fm5xNJR z4-yMdlNKYkfcRT4s5@FV`j`G4UXdp{bKSh$M0|yo{j8T)-q zsfRbR-qP5o*3rgO=J)sr3ThOr_ggN%S8mI(OG|n7fGfD|j1vV$(djGzZiSl135e|A`-WV(^)uloNp}rM`O%Oh|Z%?ueV4U zje4ty72y1nT9`MjazER3VU8`sojbamgjVe7@3j;^uy~3H7=w@*EmFtmQ&hlLXk@)S zv)PcdgC@=#R)eiG*1~N6(+S{fwISAx#r#B!9vRE&+*qywMPii4a(MlA8}aj4ob;?0 zaBlhO*EJ!Z-aP@6)R-6b@KO!JZ||bSj{f#W$PXNtaovq ziheFyOjzF;ClAhHw1s18w(eaVGb%)E%f@WBUgxdh9>lkhztYyw=#m2v_mhxH=O^^0Ho!CqxR3lvhb zuD6&n0fmyq%897ldeP>X_^?WICw4jsJvDE~i!;Ot0(l897i^ z-d`*#O+)~hGucbzOw{du)~i3Y*AtJW%xkm@%9vqXsLZCrwPxbuiI}CC#XLeg2x+Xpg2d`WJmc$9;wfanO$`S+vh**k(4NPD%lhI0cVxiP=_bP?KAY{}MZQT;v}9}=J4uzqoQ3dg$KT6E^I zV7^G1ib~}%0}}*ig^o{+%^e`WntFWv=Lf$}X!jDT=RC!D<%#ao^dZ_}v40v$o2GLH zRG*GEpRv(kjpZtLQH+|7HtUKxAkWfc?TE%aaTp4XJ{>3zJ&nD-7#r1fV`Z~>GxTmF zhu^`Fv&79D3{kG5XCSo-j_sB8Of zYS6>hPXDNPGv*ebQn%%SyyE;ys#byDlf|oS!+M+J?Kf@&bzc?6JxZ-7?&1t8Z)Cj& zvgi4$^~wgsjmIL%y#ke2A1uEMe)0IxiTzL6bM@JfNvIUl1#y(8zj4WxuF56VhgUdL0U(=nuxkdWq$%i#;YRKD?tV za+J@eiQ8;qfw(&#TjVo#oG2_(uv#85%NIv*t`tYtqsVrVHXG!in6d-LS+5NpA5wqr z*5~SV5YWUGQkc%rXVVeK_>FSagzE-cu)_uiubFp2S_h-r%hrgSO)vsGp zb-Y)VtCqzdbM=OJ${hxW|K&_&`Z3(kdKK`)O};;^UNP{#*?Dt*9v636^>;7pQ~%D3 zFkq^vx(*$ZgDu{g2kVp_;`@1eL)GyP`hOe%Ef3rqDGtCde%2d=n?w$)>@2p6lT2+I zGUWW!+jDbs2j<7MFZudpHAq+t?uhCOunJ_0coJpEx&``F-055KDtgfT6}@4Q^=9FM z9WieY>d~|c%JZ~{A++8#{K&1^p7PCC-P7T%)vw@2cV%(;71UTycp6yntT*#6di!99 zxBMNQP=Ok0r|55BFjahZ6b95$hv~hq417&d>q)TKPlrxi2p_3)m)N>cuZ$=APc4KG zi`FyP&w6=rLcjKl$uGIF}&ct=A2Q`E0E@ zK6K(tlv8uKod{Tg0!5E}y+u`ls?4I^_yYhv!rywWu}7IZt9P#OP5o2p6l<&Y&^czv(Q{~+W5*4^c6>z=$+)5!B_iG)LDue z)Ix?+?4A6vOZ5nLWydo8W+UsR$9`Qebh+{UhMK5T?H$%@ku&VWzq`?V{zK$&G_ey` z7N?h^N7DTW3f#5)t7j|70Sys3uVU9VL*%a$zZG}pVm_wl)NO9;joOI@ht_LxQU-goUze`@Ll3%V}(+vGnhu2%eZ6$mr z%gCdgTA7|s!c8mnPX2$tnpjIwaZzuTe$(H2&9V1)mnuwmZ*~YxsgscmlnQdS`ETr( z)kLK?%#QEm?kVT3wHT;*`43?t*Y*Em*~Wr1gv+)s{ybzkmv`&!&LM54w;FdpH^mGQ z^G@hr7H!^KwO$CF@#dNDW=A#q%~Um4I=NK)S#OShBf00Yvk_^2VGqzu7x>^7`Cq1%YR}(#!}gH$9XIPO&@ZgiEm$$=-k6#p9 zH()z*6FHkup`Z8?mik$*((bj_ul$G$joYB4+EeApL2Ds`Ha=C?pIHg&+OZJCKZmlS?vDe~$)w#_e z@*E(Fzy81OVsU5->Qv!gcq%Z%sG}TC^NX-Nf?%vYx9Q8(43L9ooeL~Z4f7Bg+a~c5 z1Gek_MQ@|Yn_yzwcC1@cQ+&G}YlbQ;PgrUKi4HrEqv|trmRkltOI^znGv3gLsHy%R zH4YHbJK;|m&SK=w!ixKfwL5X-HWzST{pW?E^qUw4E7ouxX=|* zrH*{oOS4xlZT!o+Pir4Qj=J9&B<7;1U(3bvMU#VJon2v zR;usIaZ^zU-^zJ@7$Xv)fZGWZsAs)0ecJI{_uc(3vbPO`Q9XVV7CWdHCkl3>+8*LD ziMojwA>wc^&riMoJoj+@Ni`Q z{<2;{CA6+~g3TfzAA0-5oW0PKFG;uMrmb;=AMU)x1$rD%EU~icDy-Ui!}_rDIrB5# zs?6UGxt73R_g)i6_G0b1AojD;BIdj&?n3fk)^FaqkhPd!G-M4W*lH1}G*(q#B(nnM zquJ{s4HpPEe(NtL`jVI#Pq}}%G4Sjg>E;aq6-m~;bM@WXUG#q&9bCCq{+js5{(Up& z_>S(QYjrVLyef%pR7k{ARs6Mh?WrZ%D~ElAU2Sq?FmA|%;Me@CP|)1P@6=m?BK(nc zL4!VXYwl?lRalXSXs{o8@;JfyQBh3XkDxv)PVGl1Y!XjE{GV|XNgXrPPY3EI8P6F9 zP@TM6^sKvI+$a$M9mE;x;qR{xnD-kBjo|$QwCUS;I-U~aE$?fO!iRrby%>H`;;nMr ztFT$GpWk}HyV21Ho$yngmGj0Xapxd@kbWO!E1;}1XtT?(3zhE{YFMwdKi7Cy%flc3 z*sn0>*G;17A$-H|*eq}BzP&8DLfeJIjumRu6KRKFwD}v0PpeS#F*XmhvZ&aoPttc! zo9KaA7!^DY7QS&nK9upsK}lVkW+tbONzMpvGcGGRV`Sop?pYZrBZr8u4(YY=dr67I z=1t+1&1M83ZN?GPVOq4yM z?-Lh~=*{x09@Ts3`8$v4@78yWNE?)xIW#CaGk^3weSo)U(7RX(G2xgVAsUn{RwDmW QiDIJ@@~;dkcFN`d02B$1p8x;= delta 37250 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 diff --git a/package.json b/package.json index cd97d94..839b7cc 100644 --- a/package.json +++ b/package.json @@ -80,7 +80,6 @@ "@semantic-release/changelog": "^6.0.3", "@semantic-release/git": "^10.0.1", "@types/bun": "^1.1.13", - "@types/lodash-es": "^4.17.12", "@types/micromatch": "^4.0.9", "@types/node": "^20.16.1", "semantic-release": "^24.2.0", @@ -93,7 +92,6 @@ "dependencies": { "@prisma/client": "^5.18.0", "iovalkey": "^0.2.1", - "lodash-es": "^4.17.21", "micromatch": "^4.0.7", "object-code": "^1.3.3", "promise-coalesce": "^1.1.2" diff --git a/src/cacheKey.ts b/src/cacheKey.ts index ed88085..872c070 100644 --- a/src/cacheKey.ts +++ b/src/cacheKey.ts @@ -1,5 +1,4 @@ -import {camelCase, kebabCase, snakeCase, startCase} from 'lodash-es'; - +import { CacheCase, caseMap } from './keyCases'; import type { CacheAutoKeyParams, CacheKeyParams, @@ -11,19 +10,6 @@ const globCheckRegex = /[*?]/; const globCheck = (s: string) => globCheckRegex.test(s); -export enum CacheCase { - CAMEL_CASE = 'camelCase', - KEBAB_CASE = 'kebabCase', - SNAKE_CASE = 'snakeCase', - START_CASE = 'startCase', -} - -export const caseMap = { - [CacheCase.CAMEL_CASE]: camelCase, - [CacheCase.KEBAB_CASE]: kebabCase, - [CacheCase.SNAKE_CASE]: snakeCase, - [CacheCase.START_CASE]: startCase, -}; export const getKeyGen = ( diff --git a/src/index.ts b/src/index.ts index 1b2c29f..6f41d33 100644 --- a/src/index.ts +++ b/src/index.ts @@ -7,4 +7,4 @@ export type { UncacheOptions, } from './types'; export {filterOperations, unlinkPatterns} from './cacheUncache'; -export {CacheCase} from './cacheKey'; +export {CacheCase} from './keyCases'; diff --git a/src/keyCases.ts b/src/keyCases.ts new file mode 100644 index 0000000..f1fdc3e --- /dev/null +++ b/src/keyCases.ts @@ -0,0 +1,131 @@ +/** + * Converts `string` to [camel case](https://en.wikipedia.org/wiki/CamelCase). + * + * @example + * + * _.camelCase('Foo Bar'); + * // => 'fooBar' + * + * _.camelCase('--foo-bar--'); + * // => 'fooBar' + * + * _.camelCase('__FOO_BAR__'); + * // => 'fooBar' + */ +export const camelCase = (str = ''): string => { + if (!str) return ''; + let string = str.toLowerCase(); + // Replace all special characters (hyphens, underscores) with spaces + string = string.replace(/[-_]+/g, ' '); + string = string.trim(); + // Split by spaces + const words = string.split(/\s+/); + // Capitalize all words except the first one + const camelCased = words.map((word, index) => { + if (index === 0) return word; + return word.charAt(0).toUpperCase() + word.slice(1); + }).join(''); + return camelCased; +}; + +/** + * Converts `string` to + * [kebab case](https://en.wikipedia.org/wiki/Letter_case#Special_case_styles). + * + * @example + * + * _.kebabCase('Foo Bar'); + * // => 'foo-bar' + * + * _.kebabCase('fooBar'); + * // => 'foo-bar' + * + * _.kebabCase('__FOO_BAR__'); + * // => 'foo-bar' + */ +export const kebabCase = (str = ''): string => { + if (!str) return ''; + // First, handle camelCase and PascalCase + let string = str.replace(/([a-z])([A-Z])/g, '$1 $2'); + string = string.toLowerCase(); + // Replace all hyphens, underscores, and special characters with spaces + string = string.replace(/[_\-]+/g, ' '); + // Replace all remaining non-alphanumeric characters with spaces + string = string.replace(/[^\w\s]/g, ' '); + // Trim the string and replace spaces with hyphens + string = string.trim().replace(/\s+/g, '-'); + return string; +}; + +/** + * Converts `string` to + * [snake case](https://en.wikipedia.org/wiki/Snake_case). + * + * @example + * + * _.snakeCase('Foo Bar'); + * // => 'foo_bar' + * + * _.snakeCase('fooBar'); + * // => 'foo_bar' + * + * _.snakeCase('--FOO-BAR--'); + * // => 'foo_bar' + */ +export const snakeCase = (str = ''): string => { + if (!str) return ''; + // First, handle camelCase and PascalCase + let string = str.replace(/([a-z])([A-Z])/g, '$1 $2'); + string = string.toLowerCase(); + // Replace all hyphens, underscores, and special characters with spaces + string = string.replace(/[_\-]+/g, ' '); + // Replace all remaining non-alphanumeric characters with spaces + string = string.replace(/[^\w\s]/g, ' '); + // Trim the string and replace spaces with underscores + string = string.trim().replace(/\s+/g, '_'); + return string; +}; + +/** + * Converts `string` to + * [start case](https://en.wikipedia.org/wiki/Letter_case#Stylistic_or_specialised_usage). + * + * @example + * + * _.startCase('--foo-bar--'); + * // => 'Foo Bar' + * + * _.startCase('fooBar'); + * // => 'Foo Bar' + * + * _.startCase('__FOO_BAR__'); + * // => 'FOO BAR' + */ +export const startCase = (str = ''): string => { + if (!str) return ''; + // First, handle camelCase and PascalCase + let string = str.replace(/([a-z])([A-Z])/g, '$1 $2'); + // Replace all hyphens, underscores, and special characters with spaces + string = string.replace(/[_\-]+/g, ' '); + // Replace all remaining non-alphanumeric characters with spaces + string = string.replace(/[^\w\s]/g, ' '); + // Trim the string, split by spaces, capitalize each word, and join back with spaces + string = string.trim().split(/\s+/).map(word => { + return word.charAt(0).toUpperCase() + word.slice(1); + }).join(' '); + return string; +}; + +export enum CacheCase { + CAMEL_CASE = 'camelCase', + KEBAB_CASE = 'kebabCase', + SNAKE_CASE = 'snakeCase', + START_CASE = 'startCase', +} + +export const caseMap = { + [CacheCase.CAMEL_CASE]: camelCase, + [CacheCase.KEBAB_CASE]: kebabCase, + [CacheCase.SNAKE_CASE]: snakeCase, + [CacheCase.START_CASE]: startCase, +}; \ No newline at end of file diff --git a/src/types.ts b/src/types.ts index 3ff517e..396aa9c 100644 --- a/src/types.ts +++ b/src/types.ts @@ -6,7 +6,7 @@ import type { } from '@prisma/client/runtime/library'; import type {Redis, RedisOptions} from 'iovalkey'; -import type {CacheCase} from './cacheKey'; +import type {CacheCase} from './keyCases'; export const ALL_OPERATIONS = [ '$executeRaw', diff --git a/test/unit/key-cases.test.ts b/test/unit/key-cases.test.ts new file mode 100644 index 0000000..22bf607 --- /dev/null +++ b/test/unit/key-cases.test.ts @@ -0,0 +1,126 @@ +import {expect, test} from 'bun:test'; +import {camelCase, kebabCase, snakeCase, startCase} from '../../src/keyCases'; + +// Tests for camelCase +test('camelCase: should handle regular space-separated words', () => { + expect(camelCase('Foo Bar')).toBe('fooBar'); +}); + +test('camelCase: should handle hyphenated words', () => { + expect(camelCase('--foo-bar--')).toBe('fooBar'); +}); + +test('camelCase: should handle underscore separated words', () => { + expect(camelCase('__FOO_BAR__')).toBe('fooBar'); +}); + +test('camelCase: should handle empty string', () => { + expect(camelCase('')).toBe(''); +}); + +test('camelCase: should handle undefined', () => { + expect(camelCase(undefined)).toBe(''); +}); + +test('camelCase: should handle mixed delimiters', () => { + expect(camelCase('foo_bar-baz')).toBe('fooBarBaz'); +}); + +// Tests for kebabCase +test('kebabCase: should handle regular space-separated words', () => { + expect(kebabCase('Foo Bar')).toBe('foo-bar'); +}); + +test('kebabCase: should handle camelCase words', () => { + expect(kebabCase('fooBar')).toBe('foo-bar'); +}); + +test('kebabCase: should handle PascalCase words', () => { + expect(kebabCase('FooBar')).toBe('foo-bar'); +}); + +test('kebabCase: should handle special characters', () => { + expect(kebabCase('__FOO_BAR__')).toBe('foo-bar'); +}); + +test('kebabCase: should handle empty string', () => { + expect(kebabCase('')).toBe(''); +}); + +test('kebabCase: should handle undefined', () => { + expect(kebabCase(undefined)).toBe(''); +}); + +test('kebabCase: should handle mixed delimiters', () => { + expect(kebabCase('foo_bar-baz')).toBe('foo-bar-baz'); +}); + +test('kebabCase: should handle already kebab cased strings', () => { + expect(kebabCase('foo-bar')).toBe('foo-bar'); +}); + +// Tests for snakeCase +test('snakeCase: should handle regular space-separated words', () => { + expect(snakeCase('Foo Bar')).toBe('foo_bar'); +}); + +test('snakeCase: should handle camelCase words', () => { + expect(snakeCase('fooBar')).toBe('foo_bar'); +}); + +test('snakeCase: should handle PascalCase words', () => { + expect(snakeCase('FooBar')).toBe('foo_bar'); +}); + +test('snakeCase: should handle hyphenated words', () => { + expect(snakeCase('--FOO-BAR--')).toBe('foo_bar'); +}); + +test('snakeCase: should handle empty string', () => { + expect(snakeCase('')).toBe(''); +}); + +test('snakeCase: should handle undefined', () => { + expect(snakeCase(undefined)).toBe(''); +}); + +test('snakeCase: should handle mixed delimiters', () => { + expect(snakeCase('foo-bar_baz')).toBe('foo_bar_baz'); +}); + +test('snakeCase: should handle already snake cased strings', () => { + expect(snakeCase('foo_bar')).toBe('foo_bar'); +}); + +// Tests for startCase +test('startCase: should handle regular space-separated words', () => { + expect(startCase('foo bar')).toBe('Foo Bar'); +}); + +test('startCase: should handle camelCase words', () => { + expect(startCase('fooBar')).toBe('Foo Bar'); +}); + +test('startCase: should handle PascalCase words', () => { + expect(startCase('FooBar')).toBe('Foo Bar'); +}); + +test('startCase: should handle hyphenated words', () => { + expect(startCase('--foo-bar--')).toBe('Foo Bar'); +}); + +test('startCase: should handle underscore words', () => { + expect(startCase('__FOO_BAR__')).toBe('FOO BAR'); +}); + +test('startCase: should handle empty string', () => { + expect(startCase('')).toBe(''); +}); + +test('startCase: should handle undefined', () => { + expect(startCase(undefined)).toBe(''); +}); + +test('startCase: should handle mixed delimiters', () => { + expect(startCase('foo-bar_baz')).toBe('Foo Bar Baz'); +}); \ No newline at end of file